十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

douyin-downloader 命令行架构全解:douyin-dl 入口、Rich 进度显示与 Whisper 转录

douyin-downloader 命令行架构全解:douyin-dl 入口、Rich 进度显示与 Whisper 转录 douyin-downloader 命令行架构全解douyin-dl 入口、Rich 进度显示与 Whisper 转录【免费下载链接】douyin-downloaderA practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音批量下载工具去水印支持视频、图集、合集、音乐(原声)。项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader导读douyin-downloader是一个同时支持单条作品与作者主页批量下载的抖音下载工具而cli/目录承载了它面向终端的完整交互层从argparse参数解析、异步主下载循环到基于 Rich 的进度条界面与可选的 Whisper 语音转录全部集中于此。本文将围绕 cli/AGENTS.md 的模块说明结合 cli/main.py、cli/progress_display.py、cli/whisper_transcribe.py 等源码从入口函数、单链接下载管线、进度模型、登录失效自动重登到转录工具链完整还原 CLI 层的实现细节与运行原理。一、CLI 模块定位命令行交互层做什么根据 cli/AGENTS.md 的Purpose描述cli包负责四件事参数解析用argparse解析用户在终端输入的命令行参数主异步下载循环main()→main_async()→ 每个 URL 执行download_url()的编排进度显示用 Rich 渲染横幅banner、进度条、步骤跟踪与结果汇总可选 Whisper 转录通过openai-whisper对下载的视频做语音识别。关键文件一览文件职责cli/init.py包标记文件。特意不在其中导入main避免遮蔽cli.main子模块、破坏测试中的import cli.main as mcli/main.pyCLI 入口main()→main_async()→ 逐 URL 调用download_url()的完整编排cli/progress_display.py基于 Rich 的终端 UI横幅、进度条、步骤跟踪、结果汇总表cli/whisper_transcribe.py可选的 OpenAI Whisper 音频转录工具独立可运行的脚本包级说明还明确了douyin-dl这个 CLI 入口的映射关系在 pyproject.toml 中[project.scripts]段将douyin-dl cli.main:main即安装项目后终端里直接输入douyin-dl即可启动下载器。二、入口与参数解析main()是如何工作的整个 CLI 从 cli/main.py 的main()开始流程如下构造argparse.ArgumentParser注册全部命令行参数根据-v/--show-warnings调整控制台日志级别用asyncio.run(main_async(args))启动异步主循环捕获KeyboardInterrupt打印用户中断并以 0 退出与其余异常打印致命错误、记录日志并以 1 退出。命令行参数总表参数含义默认值-u/--url待下载链接actionappend可多次传入无-c/--config配置文件路径config.yml-p/--path保存路径覆盖配置无-t/--thread并发线程数覆盖配置配置值默认 5--show-warnings控制台显示警告日志关闭-v/--verbose控制台显示完整 INFO 日志关闭--hot-board [N]拉取抖音热搜榜并导出 JSONLN为可选条数上限不执行--search KEYWORD按关键词搜索作品并导出 JSONL不执行--search-max N--search场景下最多拉取条数50--serve以 REST API 服务模式运行关闭--serve-hostREST 服务监听地址127.0.0.1--serve-portREST 服务监听端口8000--version打印版本号—日志级别的选择逻辑cli/main.py-v设为logging.INFO--show-warnings设为logging.WARNING否则设为logging.ERROR。版本号优先从包__init__.py导入导入失败时回退到2.0.0。三、主异步循环main_async配置、Cookie、数据库与调度main_async 是 CLI 的核心编排函数其执行顺序体现了完整的主流程3.1 配置加载与容错未指定--config时默认读取config.ymlcli/main.py特殊容错当配置文件不存在、但用户使用了--hot-board/--search/--serve这类独立子命令时允许以默认配置运行——前提是命令行提供了--pathcli/main.py--serve场景下仍会传入配置文件路径这样后续 REST 设置接口调用config.save()时能把文件写到正确位置例如 Electron 的 userData 目录配置的加载优先级由 config/config_loader.py 实现DEFAULT_CONFIG内置默认值 →config.yml文件覆盖 → 环境变量覆盖DOUYIN_COOKIE、DOUYIN_PATH、DOUYIN_THREAD、DOUYIN_PROXY层层合并。-p与-t参数通过config.update(path..., thread...)覆盖配置-u传入的 URL 会被追加进config.get(link, [])cli/main.py。3.2 配置校验调用config.validate()config/config_loader.py检查必须存在至少一个链接link且必须配置保存路径paththread必须为 ≥1 的整数非法时警告并回退为 5retry_times必须为 ≥0 的整数非法时回退为 3start_time/end_time必须是YYYY-MM-DD格式非法则清空。3.3 Cookie 与数据库初始化通过config.get_cookies()取出 Cookie交给CookieManager若validate_cookies()返回 False则打印Cookies may be invalid or incomplete警告cli/main.py当database开关开启时默认数据库路径为dy_downloader.db创建Database并await database.initialize()cli/main.py。3.4 日志静默避免 Rich 重绘冲突这是一个非常实用的工程细节进度条渲染期间如果控制台持续输出大量错误日志会触发 Rich 反复重绘、导致屏幕出现重复块。因此当配置中progress.quiet_logs为 True默认 True且未加-v/--show-warnings时会在下载会话期间把控制台日志级别提升到logging.CRITICAL会话结束后恢复为logging.ERRORcli/main.py。3.5 逐 URL 调度与结果聚合display.start_download_session(len(urls))开启整体会话对每个 URL 依次start_url→download_url→complete_url/fail_url所有结果汇总为一个DownloadResult其total / success / failed / skipped字段累加并调用display.show_result()打印 Overall Summary 汇总表cli/main.py无论全部成功还是全部失败只要通知开关开启都会通过utils/notifier的build_notifier分发完成通知——全部失败时标题为抖音下载器全部失败部分失败时标题为抖音下载部分失败cli/main.py。四、单链接下载管线download_url六步流水线download_url 是每个 URL 都要走一遍的标准化流水线cli/AGENTS.md 将其概括为resolve short URL → parse → factory → download → record history。源码中通过ProgressDisplay.advance_step将过程细分为 6 个中文步骤对应_URL_STEP_TOTAL 6步骤阶段具体工作1初始化创建FileManager保存路径、RateLimiter默认 2 req/s、RetryHandler默认 3 次、QueueManager默认 5 并发2解析链接短链检测与解析、URL 类型识别3创建下载器通过DownloaderFactory.create按类型实例化下载器4执行下载调用downloader.download(parsed)拉取并保存资源5记录历史结果写入 SQLite 历史表6收尾汇总成功/失败/跳过数量4.1 短链解析支持多种短链变体v.douyin.com、v.iesdouyin.com以及无 scheme 的裸链接。当is_short_url(url)为真时先经normalize_short_url规范化再调用api_client.resolve_short_url()解析解析失败会直接终止该 URLcli/main.py。4.2 URL 解析与能力门禁URLParser.parse()core/url_parser.py负责识别链接类型并抽取关键 IDvideo→aweme_id/video/id或modal_ididuser→sec_uid/user/sec_uidcollection→mix_id/collection/id或/mix/idgallery→note_idaweme_id/note|gallery|slides/idmusic→music_idlive→room_idlive.douyin.com/id、/follow/live/id、webcast 回放链接live_replay→episode_idreplay_id。解析结果会进入能力门禁某些类型虽然能解析出来但永远不会有下载器。例如lvdetail抖音放映厅影视内容因版权 DRM 加密无法获取可播放成片UNSUPPORTED_URL_TYPE_DETAILcore/downloader_factory.py会在创建下载器之前就拦截并给出真实原因而不是让用户看到含糊的 No downloader foundcli/main.py。4.3 下载器工厂与失败隔离DownloaderFactory.create()core/downloader_factory.py根据url_type选择下载器实现VideoDownloader单视频、UserDownloader主页批量、MixDownloader合集、MusicDownloader音乐/原声、LiveDownloader直播、LiveReplayDownloader直播回放等。下载执行被包裹在try/except Exception中cli/main.py任何下载器抛出的异常例如 Cookie 失效导致 user_info 拉取失败都只会让当前 URL标记失败而不会拖垮整个批量任务——这是多 URL 批量运行保持稳健的关键设计。4.4 历史记录写入下载成功后若启用了数据库会将url原始链接、url_type、total_count、success_count以及一份脱敏配置写入历史表cookies、cookie、transcript等敏感字段会被剔除后再序列化cli/main.py。五、登录态失效与自动重新登录抖音接口的 Cookie 会定期失效CLI 通过 cli/login_flow.py 提供终端内的交互式重登录能力_run_with_relogincli/main.py在捕获LoginRequiredError后最多重试一次通过can_interactive_login(serve...)判断环境是否允许交互登录--serve模式直接返回 False且必须sys.stdin.isatty()为 Truecli/login_flow.py允许时调用interactive_relogin()借助tools/cookie_fetcher的fetch_cookies打开浏览器引导用户登录用户回到终端按 Enter 后读取并清洗config/cookies.json校验必须包含sessionidcli/login_flow.py新 Cookie 通过cookie_manager.set_cookies()整体替换而非合并随后用全新的协程重试重试时会基于刷新后的 Cookie 创建新的DouyinAPIClient若重试仍失败或处于非交互环境则打印指引手动更新config/cookies.json或运行python tools/cookie_fetcher.py登录cli/main.py。六、Rich 进度显示三级进度模型cli/progress_display.py 中的ProgressDisplay是 CLI 的门面采用总体 → URL → 作品三级进度模型底层由 Rich 的Progress渲染进度条组件SpinnerColumn转圈动画TextColumn描述文字BarColumn进度条TaskProgressColumn百分比TimeRemainingColumn剩余时间 灰色detail字段transientTrue且refresh_per_second6cli/progress_display.pyURL 级进度每个 URL 有 6 步对应_URL_STEP_TOTAL描述格式为URL {i}/{total} · {步骤}作品级进度当解析出作品总数后set_item_total创建作品下载任务实时显示S:成功 F:失败 K:跳过计数与最近状态单 URL 特化当总 URL 数为 1 时总体进度条会切换为按作品数推进模式_single_url_item_mode让单个主页批量下载的进度展示得更加细致cli/progress_display.py结果汇总下载结束打印 RichTable包含 Total / Success / Failed / Skipped / Success Rate成功率保留一位小数cli/progress_display.py信息分级着色print_info蓝 ℹ、print_success绿 ✓、print_warning黄 ⚠、print_error红 ✗文本截断URL 与 detail 超过长度72 / 36 / 60 字符时统一用...截断防止长链接撑爆终端布局。该三级模型的行为有专门的单元测试保障tests/test_progress_display.py 通过_FakeProgress桩对象验证了两条核心规则——单 URL 场景下总体进度跟随作品数set_item_total(5)后总体 total 变为 5advance_item逐条推进以及多 URL 场景下总体进度保持按 URL 计数作品推进不影响总体complete_url/fail_url才推进一次。七、独立子命令热榜、搜索与 REST 服务除下载外CLI 还支持三类独立子命令在 cli/main.py 中实现--hot-board [N]拉取抖音热搜榜通过core.discovery.dump_hot_board导出 JSONL可选上限 N--search KEYWORD按关键词搜索作品通过core.discovery.search_and_dump导出 JSONL默认最多 50 条--serve启动 REST API 服务模式内部延迟导入server.app.run_server若未安装fastapiuvicorn会打印明确的安装提示pip install fastapi uvicorn后退出。服务参数、任务上限等可在 config/default_config.py 的server段配置max_jobs默认 500、job_ttl_seconds默认 86400。这两个子命令同样包裹在_run_with_relogin中登录失效时自动触发重登录流程。八、可选 Whisper 转录whisper_transcribe.pycli/whisper_transcribe.py 是一个独立可运行的批量转录脚本位于transcribe可选依赖之后pip install openai-whisper见 pyproject.toml。它采用与主下载器不同的绿色主题bright_green避免与下载器的 cyan/magenta 混淆。8.1 命令行用法python whisper_transcribe.py # 扫描 ./Downloaded/ 下所有 mp4 python whisper_transcribe.py -d ./Downloaded/ # 指定目录 python whisper_transcribe.py -f video.mp4 # 单个文件 python whisper_transcribe.py -d ./Downloaded/ -m medium # 用 medium 模型 python whisper_transcribe.py -d ./Downloaded/ --srt # 同时输出 SRT 字幕 python whisper_transcribe.py --skip-existing --sc # 跳过已有 繁体转简体8.2 参数详解参数含义默认值-d/--dir扫描的视频目录./Downloaded-f/--file单个视频文件无-m/--modelWhisper 模型tiny/base/small/medium/largebase-l/--language识别语言zh--srt额外输出 SRT 字幕关闭--skip-existing跳过已有 transcript 的视频关闭--sc繁体转简体需pip install OpenCC关闭-o/--output转录文件输出目录默认与视频同目录8.3 关键实现细节ffmpeg 定位三级回退find_ffmpeg()依次尝试shutil.which(ffmpeg)→ 脚本同目录的ffmpeg.exe→imageio_ffmpeg.get_ffmpeg_exe()cli/whisper_transcribe.py音频提取调用 ffmpeg 将视频转成pcm_s16le、16kHz、单声道 WAV专为 Whisper 优化cli/whisper_transcribe.py临时目录隔离先把视频复制到tempfile.mkdtemp临时目录再处理规避抖音文件名中的换行、#等特殊字符导致 ffmpeg 或写入失败若复制失败长路径/特殊字符会尝试 Windows 短路径GetShortPathNameW兜底cli/whisper_transcribe.py文件名清洗_safe_stem()将换行替换为空格、把:/\|?*#等 Windows 非法字符替换为下划线、折叠连续分隔符并限制在 150 字符内cli/whisper_transcribe.py输出文件stem.transcript.txt与可选的stem.transcript.srtSRT 时间戳按HH:MM:SS,mmm格式生成输出目录回退默认写入视频所在目录但会先做一次实际写文件测试若原目录不可写常见于含换行/#的抖音文件夹名自动回退到./transcriptscli/whisper_transcribe.py跳过已有--skip-existing会在扫描阶段检查视频对应的*.transcript.txt是否已存在于视频目录、-o输出目录或./transcripts中进度与汇总内置TranscribeDisplay每个文件经历提取音频 → 识别 → 转换 → 保存4 步结束打印Transcription Summary表Total / Success / Failed / Skipped / Success Rate。九、测试与质量保障cli模块的测试策略在 cli/AGENTS.md 中有明确说明直接单元测试集中在 tests/test_progress_display.py通过注入_FakeProgress/_FakeProgressContext桩对象验证进度状态机单 URL 作品模式、多 URL 计数模式、任务清理main.py主要通过集成测试间接覆盖做单元测试时需 mockasyncio.run避免真实拉起事件循环。此外pyproject.toml 配置了pytest-asyncio的asyncio_mode auto测试自动识别异步测试并对 aiosqlite 后台线程与事件循环关闭的已知交互问题做了 warning 过滤保证pytest tests/输出干净。十、依赖关系与扩展方式根据 cli/AGENTS.md 的Dependencies部分cli层是典型的编排中枢聚合了项目几乎所有子系统内部依赖模块提供能力config/ConfigLoader负责 YAML 配置加载与校验auth/CookieManager负责登录态管理storage/DatabaseSQLite 历史去重、FileManager文件落盘control/QueueManager、RateLimiter、RetryHandler并发/限速/重试core/DouyinAPIClient、URLParser、DownloaderFactory核心能力utils/loggersetup_logger、set_console_log_level日志静默机制外部依赖rich终端 UI 渲染进度条、表格、彩色输出为必需依赖openai-whisper可选转录功能位于[transcribe]extra 中未安装时主下载流程完全不受影响。若需要同时启用全部可选能力可直接安装聚合依赖pip install douyin-downloader[all]对应 pyproject.toml 的allextra包含 browser / transcribe / server / dev。总结从 cli/AGENTS.md 的模块骨架出发可以看到cli层是 douyin-downloader 的指挥中心main()负责参数解析与异常兜底main_async()负责配置/Cookie/数据库的初始化与多 URL 调度download_url()以六步流水线完成从短链解析、类型识别、下载器创建到历史记录的完整链路ProgressDisplay以三级 Rich 进度模型提供直观反馈而whisper_transcribe.py则把下载产物进一步转化为可检索的文字。理解这一层就掌握了整个项目从输入一个链接到产出本地文件 历史记录 完成通知的全部调用路径。【免费下载链接】douyin-downloaderA practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音批量下载工具去水印支持视频、图集、合集、音乐(原声)。项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表