Skip to content

Commit bfad5d9

Browse files
committed
feat(app): 新增 TikTok 直播下载功能
1 parent 0d5d7f1 commit bfad5d9

6 files changed

Lines changed: 67 additions & 33 deletions

File tree

docs/Release_Notes.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
11. 优化 `latest` 参数设置规则
1414
12. 新增批量下载视频原画功能
1515
13. 新增实况作品处理数量统计
16-
14. 重构请求参数更新逻辑
17-
15. 优化项目代码复用性
18-
16. 重构 Web API 模式
19-
17. 更新项目英语翻译
20-
18. 移除内置延时机制
21-
19. 优化网络异常捕获
22-
20. 优化代码运行逻辑
23-
21. 支持 `SOCKS` 代理
24-
22. 优化运行状态提示
25-
23. 修复其他已知问题
16+
14. 新增 TikTok 直播下载功能
17+
15. 重构请求参数更新逻辑
18+
16. 优化项目代码复用性
19+
17. 重构 Web API 模式
20+
18. 更新项目英语翻译
21+
19. 移除内置延时机制
22+
20. 优化网络异常捕获
23+
21. 优化代码运行逻辑
24+
22. 支持 `SOCKS` 代理
25+
23. 优化运行状态提示
26+
24. 修复其他已知问题

docs/TikTokDownloader文档.md

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</div>
1616
<br>
1717
<p>🔥 <b>TikTok 发布/喜欢/合辑/直播/视频/图集/音乐;抖音发布/喜欢/收藏/收藏夹/视频/图集/实况/直播/音乐/合集/评论/账号/搜索/热榜数据采集工具:</b>完全开源,基于 HTTPX 模块实现的免费数据采集和文件下载工具;批量下载抖音账号发布、喜欢、收藏、收藏夹作品;批量下载 TikTok 账号发布、喜欢作品;下载抖音链接或 TikTok 链接作品;获取抖音直播推流地址;下载抖音直播视频;获取 TikTok 直播推流地址;下载 TikTok 直播视频;采集抖音作品评论数据;批量下载抖音合集作品;批量下载 TikTok 合辑作品;采集抖音账号详细数据;采集抖音用户 / 作品 / 直播搜索结果;采集抖音热榜数据。</p>
18-
<p>⭐ <b>文档对应项目版本:<code>5.5</code>;文档内容正在完善中,如有发现任何错误或描述模糊之处,请告知作者以便改进!</b></p>
18+
<p>⭐ <b>文档对应项目版本:<code>5.6 Beta</code>;文档内容正在完善中,如有发现任何错误或描述模糊之处,请告知作者以便改进!</b></p>
1919
<hr>
2020
<h1>快速入门</h1>
2121
<p>⭐ 本项目包含手动构建可执行文件的 GitHub Actions,使用者可以随时使用 GitHub Actions 将最新源码构建为可执行文件!</p>
@@ -182,11 +182,11 @@ https://www.douyin.com/note/123456789
182182

183183
<h2>直播下载</h2>
184184
<p><code>获取直播推流地址</code> 功能需要调用 <code>ffmpeg</code> 下载直播文件;程序会优先调用系统环境的 <code>ffmpeg</code>,其次调用 <code>ffmpeg</code> 参数指定的 <code>ffmpeg</code>,如果 <code>ffmpeg</code> 不可用,程序将不支持直播下载!</p>
185-
<p>建议前往 <a href="https://ffmpeg.org/download.html">官方网站</a> 获取 <code>ffmpeg</code> 程序!</p>
185+
<p>建议前往 <a href="https://ffmpeg.org/download.html">官方网站</a> 或者 <a href="https://github.com/BtbN/FFmpeg-Builds">FFmpeg-Builds</a> 获取 <code>ffmpeg</code> 程序!</p>
186186
<p>项目开发时所用的 FFmpeg 版本信息如下,不同版本的 FFmpeg 可能会有差异;若功能异常,请向作者反馈!</p>
187187
<pre>
188-
ffmpeg version N-116650-g7897b0beed-20240815 Copyright (c) 2000-2024 the FFmpeg developers
189-
built with gcc 14.2.0 (crosstool-NG 1.26.0.106_ed12fa6)
188+
ffmpeg version n7.1.1-6-g48c0f071d4-20250405 Copyright (c) 2000-2025 the FFmpeg developers
189+
built with gcc 14.2.0 (crosstool-NG 1.27.0.18_7458341)
190190
</pre>
191191
<h2>功能简介</h2>
192192
<table>
@@ -1141,7 +1141,28 @@ built with gcc 14.2.0 (crosstool-NG 1.26.0.106_ed12fa6)
11411141
<li><code>https://vt.tiktok.com/分享码/</code></li>
11421142
<li><code>https://www.tiktok.com/@TikTok号/live</code></li>
11431143
</ul>
1144-
<p>TikTok 平台直播视频下载功能尚未开发完成,请自行使用第三方工具下载!</p>
1144+
<p>下载说明:</p>
1145+
<ul>
1146+
<li>程序会询问用户是否下载直播视频,支持同时下载多个直播视频。</li>
1147+
<li>程序调用 <code>ffmpeg</code> 下载直播时,关闭 TikTokDownloader 不会影响直播下载。</li>
1148+
<li><del>程序调用内置下载器下载直播时,需要保持 TikTokDownloader 运行直到直播结束。</del></li>
1149+
<li>程序询问是否下载直播时,输入直播清晰度或者对应序号即可下载,例如:下载最高清晰度输入 <code>FULL_HD1</code> 或者 <code>1</code> 均可。</li>
1150+
<li><del>程序调用内置下载器下载的直播文件,视频时长会显示为直播总时长,实际视频内容从下载时间开始,靠后部分的片段无法播放。</del></li>
1151+
<li>直播视频会下载至 <code>root</code> 参数路径下的 <code>Live</code> 文件夹。</li>
1152+
<li>经测试,强行终止程序或 <code>ffmpeg</code> 并不会导致已下载文件丢失或损坏,但无法继续下载。</li>
1153+
</ul>
1154+
<h3>批量下载视频原画(TikTok)</h3>
1155+
<p><strong>注意:本功能为实验性功能,依赖第三方 API 服务,可能不稳定或存在限制!</strong></p>
1156+
<ol>
1157+
<li>手动输入待采集的作品链接。</li>
1158+
<li>输入文本文档路径,读取文件包含的作品链接。</li>
1159+
</ol>
1160+
<p>支持链接格式:</p>
1161+
<ul>
1162+
<li><code>https://vm.tiktok.com/分享码/</code></li>
1163+
<li><code>https://www.tiktok.com/@TikTok号/video/作品ID</code></li>
1164+
</ul>
1165+
<p>作品会下载至 <code>root</code> 参数和 <code>folder_name</code> 参数拼接成的文件夹。</p>
11451166
<h2>后台监测模式</h2>
11461167
<p>敬请期待!</p>
11471168
<h2>Web API 接口模式</h2>

src/application/TikTokDownloader.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,6 @@ async def inner():
437437

438438
run(
439439
inner(),
440-
debug=self.VERSION_BETA,
441440
)
442441

443442
def restart_cycle_task(

src/application/main_complete.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,6 @@ def show_live_info_tiktok(self, data: list[dict]) -> list[tuple]:
11681168
self.console.print(_("在线观众:"), item["user_count"])
11691169
self.console.print(_("点赞次数:"), item["like_count"])
11701170
self.show_live_stream_url_tiktok(item, download_tasks)
1171-
self.console.print("TikTok 直播下载功能尚未完成!") # 完成后移除
11721171
return [i for i in download_tasks if isinstance(i, tuple)]
11731172

11741173
def show_live_stream_url(self, item: dict, tasks: list):
@@ -1194,20 +1193,21 @@ def show_live_stream_url_tiktok(self, item: dict, tasks: list):
11941193
self.console.print(_("FLV 推流地址: "))
11951194
for i, (k, v) in enumerate(item["flv_pull_url"].items(), start=1):
11961195
self.console.print(i, k, v)
1197-
# TODO: TikTok 直播下载功能异常,代理错误
1198-
# if self.parameter.download:
1199-
# tasks.append(
1200-
# (
1201-
# item,
1202-
# *u,
1203-
# ) if (
1204-
# # TikTok 平台 暂无 m3u8 地址
1205-
# u := self._choice_live_quality(
1206-
# item["flv_pull_url"],
1207-
# item["flv_pull_url"],
1208-
# )
1209-
# ) else u
1210-
# )
1196+
if self.parameter.download:
1197+
tasks.append(
1198+
(
1199+
item,
1200+
*u,
1201+
)
1202+
# TikTok 平台 暂无 m3u8 地址
1203+
if (
1204+
u := self._choice_live_quality(
1205+
item["flv_pull_url"],
1206+
item["flv_pull_url"],
1207+
)
1208+
)
1209+
else u
1210+
)
12111211

12121212
@check_storage_format
12131213
async def comment_interactive_tiktok(self, select="", *args, **kwargs):

src/interface/live_tiktok.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Union
33

44
from src.interface.template import APITikTok
5+
from src.translation import _
56

67
if TYPE_CHECKING:
78
from ..config import Parameter
@@ -27,7 +28,8 @@ async def run(
2728
*args,
2829
**kwargs,
2930
) -> dict:
30-
return await self.with_room_id()
31+
response = await self.with_room_id()
32+
return self.check_response(response)
3133

3234
async def with_room_id(self) -> dict:
3335
return await self.request_data(
@@ -45,6 +47,17 @@ def __generate_room_id_data(
4547
"room_id": self.room_id,
4648
}
4749

50+
def check_response(
51+
self,
52+
data_dict: dict,
53+
*args,
54+
**kwargs,
55+
):
56+
if data_dict and "prompt" in data_dict["data"]:
57+
self.console.warning(_("此直播可能会令部分观众感到不适,请登录后重试!"))
58+
return {}
59+
return data_dict
60+
4861

4962
async def test():
5063
from src.testers import Params

src/module/ffmpeg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __generate_command(
5252
"-loglevel",
5353
"info",
5454
"-protocol_whitelist",
55-
"rtmp,crypto,file,http,https,tcp,tls,udp,rtp",
55+
"rtmp,crypto,file,http,https,tcp,tls,udp,rtp,httpproxy",
5656
"-analyzeduration",
5757
f"{10 * 1000 * 1000}",
5858
"-probesize",

0 commit comments

Comments
 (0)