☰
video-use:视频工程的底层行为契约与四层漏斗工作流
2026/10/17 9:12:57 网站建设 项目流程

1. “video-use”不是功能模块,而是视频工作流的底层契约

你搜“video-use”,页面上跳出来的全是 ffmpeg、yt-dlp、EDL、ElevenLabs 这些词——没有文档、没有 GitHub 仓库、没有 npm 包名,甚至没有一个像样的 README。它不像react-router或axios那样自带语义,也不像ffmpeg-python那样有明确封装边界。它就静静躺在终端命令行里、Shell 脚本开头、Dockerfile 的 RUN 指令中,甚至藏在 CI/CD 流水线 YAML 的某个 job 步骤里。“video-use”本质上不是一段代码,而是一组被反复验证过、可组合、可替换、可审计的视频处理行为契约。它代表的是:当业务提出“把这段 YouTube 视频下载下来转成 720p MP4 并提取字幕”“把直播流切片推到 SRS 服务器”“用 AI 语音替换原声但保持唇形同步”这类需求时,工程师脑子里自动调用的一套最小可行动作集合。

我第一次真正意识到“video-use”这个概念,是在给一家教育平台做课件自动化生成系统时。当时后端同事甩来一句:“视频处理那块你来搞,我们只管调video-use接口。” 我愣了三秒——查遍所有内部文档、Swagger、OpenAPI 定义,根本没这个接口。最后发现,所谓“video-use”就是他们写在 Jenkins Pipeline 里的一个 shell 函数:video-use --source "$url" --format mp4 --resolution 720p --subtitles true。它背后调的是 yt-dlp + ffmpeg + aeneas(语音对齐工具)的三段式流水线。没人把它注册成服务,但它稳定运行了 18 个月,处理了 23 万节课程视频,失败率低于 0.17%。这让我明白:“video-use”是视频工程落地的“事实标准”,它不靠文档定义,靠生产环境里的存活率定义。它的关键词不是“技术栈”,而是“可复现性”“错误隔离性”“资源可控性”。你不需要知道 yt-dlp 怎么解析 DASH manifest,但你必须清楚:当--no-check-certificate和--ignore-errors同时启用时,哪些错误会被吞掉、哪些会静默失败、哪些会导致后续 ffmpeg 命令因输入为空而卡死。这些细节,才是“video-use”的真实边界。

所以本文不讲“如何安装 ffmpeg”,也不列“yt-dlp 最全参数表”。我要带你拆解的是:一个真正能扛住日均 5000+ 视频任务的video-use工作流,它的骨架怎么搭、血肉怎么填、神经怎么连、故障怎么自愈。你会看到:为什么yt-dlp必须加--downloader aria2c而不是默认的 urllib;为什么ffmpeg的-vsync 0和-copyts在直播切片场景下是生死开关;为什么 EDL(Edit Decision List)文件不是老古董,而是现代 AI 视频编辑的精准锚点;为什么 ElevenLabs 的 API 调用必须配--max-retries 3+ 指数退避,而不是简单try/catch。这些不是“最佳实践”,而是我在 7 个不同视频项目里,用服务器重启、磁盘爆满、客户投诉换来的硬核经验。如果你正被“视频处理不稳定”“转码耗时忽高忽低”“字幕时间轴漂移”这些问题折磨,这篇就是为你写的。

2. 四层漏斗:从原始 URL 到可用媒体资产的不可跳过路径

所有“video-use”流程的起点,从来不是ffmpeg -i input.mp4 ...,而是对一个 URL 的信任度评估。这不是玄学,是实打实的协议解析、证书校验、响应头分析和内容指纹比对。我把整个流程抽象为四层漏斗,每一层都在过滤噪声、确认意图、锁定格式——漏掉任何一层,后面所有操作都是在沙上筑塔。

2.1 第一层:URL 解析与源可信度分级

yt-dlp默认能处理 YouTube、Bilibili、Vimeo 等 1000+ 站点,但它的“能处理”不等于“该处理”。比如一个https://example.com/video?id=12345的链接,yt-dlp可能直接返回Unsupported URL,也可能成功下载一个 2MB 的.mp4文件——但这个文件可能是前端 JS 动态拼接的 HLS 地址,也可能是后端 Nginx 直接吐出的静态文件。关键不在“能不能下”,而在“下下来的到底是什么”。

我建立了一套轻量级 URL 分级规则(无需额外依赖,纯 Bash 实现):

# 根据域名和路径特征快速分类 case "$url" in https://www.youtube.com/*|https://youtu.be/*) source_type="youtube" trust_level="high" # YouTube 的 CDN 结构稳定,manifest 可预测 ;; https://www.bilibili.com/video/*) source_type="bilibili" trust_level="medium" # Bilibili 的 UA 限制严格,需模拟浏览器 ;; https://*.m3u8|https://*.mpd) source_type="hls/dash" trust_level="high" # 直接拿到流地址,跳过页面解析 ;; https://*.*/*.{mp4,avi,mkv,webm}) source_type="direct_file" trust_level="low" # 静态文件无防盗链?先 HEAD 再说 ;; *) source_type="unknown" trust_level="critical" # 必须人工介入,禁止自动流程 ;; esac

提示:trust_level="critical"不是终止流程,而是触发人工审核队列。我们在 Redis 中建了一个video-use:review_queue,把这类 URL 的截图、HTTP 头、curl -I结果存进去,由运营同学在 Web 界面确认是否允许接入。过去三个月,这个队列拦截了 17 个伪装成教育视频实则为广告跳转的恶意链接。

2.2 第二层:元数据探针与格式预判

很多人以为yt-dlp --print-json "URL"就够了,但 JSON 里duration字段可能为null,formats数组可能包含 50+ 条记录,其中只有 3 条是真正可用的。真正的探针要解决三个问题:

  • 这个源有没有音频轨?(有些直播流只有视频)
  • 最小可用分辨率是多少?(避免--format "best[height<=720]"匹配失败)
  • 是否存在硬编码字幕?(影响后续ffmpeg -scodec copy策略)

我写了一个精简版探针脚本probe-video.sh,核心逻辑是:

# 1. 先用 yt-dlp 获取最简信息(不下载) yt_dlp_info=$(yt-dlp --no-warnings --print-json --skip-download "$url" 2>/dev/null) # 2. 提取关键字段(用 jq,轻量且可靠) has_audio=$(echo "$yt_dlp_info" | jq -r '.is_live // false') min_height=$(echo "$yt_dlp_info" | jq -r '[.formats[] | select(.height != null) | .height] | min // 0') has_subtitles=$(echo "$yt_dlp_info" | jq -r '(.subtitles | length) > 0') # 3. 对 HLS/DASH 源,额外用 ffprobe 快速检查第一个切片 if [[ "$source_type" == "hls/dash" ]]; then first_segment=$(curl -s "$url" | head -n 1 | grep -o "https://[^[:space:]]*") if [[ -n "$first_segment" ]]; then ffprobe -v quiet -show_entries stream=codec_type,width,height,duration -of csv=p=0 "$first_segment" 2>/dev/null | head -n 1 fi fi

实测下来,这个探针平均耗时 1.8 秒(远低于完整下载),但能提前规避 63% 的后续失败。比如当min_height返回0,说明该源可能只有音频(如播客 RSS),流程立刻转向--extract-audio模式;当has_subtitles为false,则跳过字幕提取步骤,避免ffmpeg报错Stream #0:3 -> #0:3 (copy)。

2.3 第三层:下载策略动态编排

yt-dlp的参数不是越多越好,而是越精准越稳。我见过太多人把--all-formats --merge-output-format mp4 --recode-video h264 --postprocessor-args "-c:v libx264 -crf 23"堆在一起,结果下载完发现文件损坏,重试又触发平台限速。真正的下载策略是“分阶段、带熔断、可回滚”的。

我们定义了三种下载模式:

模式触发条件核心参数超时/重试输出物
fastmin_height >= 720 && !has_audio--format "best[height<=720][ext=mp4]" --no-part90s / 2次单 MP4 文件
safehas_audio && trust_level != "high"--format "bestvideo[height<=720]+bestaudio/best" --merge-output-format mp4 --no-part120s / 3次MP4 + 字幕 SRT(若存在)
rawsource_type == "hls/dash"--hls-prefer-native --no-part --download-archive /tmp/archive.txt180s / 1次TS 切片或 MPD 清单

关键细节:

  • --no-part强制禁用临时文件,避免磁盘空间碎片化(尤其在 Docker 容器里);
  • --download-archive记录已下载 URL 的 SHA256,防止重复拉取(yt-dlp默认不启用);
  • --hls-prefer-native用内置解析器而非ffmpeg,减少依赖冲突(ffmpeg版本不一致时常见坑)。

注意:--recode-video是性能杀手。我们实测过,对一个 1080p 视频做libx264 -crf 23编码,CPU 占用率达 92%,耗时是直接下载的 4.7 倍。除非业务强制要求统一编码规格,否则一律走--format直接选最优源。

2.4 第四层:资产标准化与指纹固化

下载完成不等于可用。一个video-use流程的终点,必须产出带唯一指纹、格式统一、元数据完备的资产。我们强制执行三项标准化:

  1. 容器格式归一化:全部转为 MP4(H.264 + AAC),因为它是 iOS/Android/Web 兼容性最好的容器。命令模板:

    ffmpeg -i "$input" \ -c:v copy -c:a aac -b:a 128k \ -movflags +faststart \ -metadata title="Generated by video-use v2.3" \ -y "$output.mp4"
    • -c:v copy保留原视频流,零损耗;
    • -movflags +faststart把 moov box 移到文件开头,网页播放秒开;
    • -metadata写入来源标识,便于审计。
  2. 时间基(Timebase)对齐:不同源的时间基差异巨大(YouTube 常用1/1000,本地录制可能是1/90000)。用ffprobe -v quiet -show_entries stream=time_base "$file"检查,若非1/1000,强制重写:

    ffmpeg -i "$input" -vf "settb=1/1000,setpts=PTS/TB*1/1000" -c:v copy -c:a copy "$output.mp4"
  3. SHA256 指纹固化:对最终 MP4 文件计算哈希,存入数据库关联原始 URL。这是“video-use”可审计性的基石。命令:

    sha256sum "$output.mp4" | cut -d' ' -f1 > "$output.sha256"

这四层漏斗,每层都增加 0.5~2 秒延迟,但换来的是 99.2% 的端到端成功率(对比裸用yt-dlp + ffmpeg的 83.7%)。视频处理不是比谁命令行更炫,而是比谁漏掉的 corner case 更少。

3. EDL:被低估的视频编辑元语言,也是 AI 时代的精准锚点

提到 EDL(Edit Decision List),很多人第一反应是“电视台老古董”“Final Cut Pro 专用”。但当你需要把一段 30 分钟的会议录像,精准剪掉中间 3 分钟的广告插播,再把剩余部分无缝拼接,并让 AI 语音合成只覆盖被剪掉的部分——这时候,EDL 就不是可选项,而是唯一可靠的坐标系。EDL 的本质,是把“时间”从模糊描述(“大概第 12 分钟开始”)变成机器可执行的精确指令(001 AX V C 00:11:58:00 00:12:01:00 00:00:00:00 00:00:03:00)。

3.1 EDL 的现代语法:从 SMPTE 到 JSON 的进化

传统 EDL 基于 SMPTE 时间码(HH:MM:SS:FF),对帧率敏感(25fps/29.97fps/30fps),解析麻烦。我们团队把 EDL 升级为 JSON 格式,命名为video-use-edl.json,结构清晰、易读易写、兼容所有编程语言:

{ "version": "1.0", "source": "https://example.com/meeting.mp4", "edits": [ { "id": "ad_break_1", "type": "remove", "start_ms": 718000, "end_ms": 721000, "reason": "commercial_break" }, { "id": "intro", "type": "keep", "start_ms": 0, "end_ms": 30000, "reason": "opening_remarks" } ], "metadata": { "created_by": "video-use-v2.3", "timestamp": "2024-06-15T08:22:15Z" } }
  • start_ms/end_ms用毫秒,彻底摆脱帧率依赖;
  • type支持keep/remove/replace/mute四种原子操作;
  • reason字段用于业务标记,导出报表时按reason分类统计。

提示:我们用 Python 的moviepy库自动生成初版 EDL。moviepy.VideoFileClip("input.mp4").subclip(0, 30).write_videofile("out.mp4")会输出时间戳,但精度只有秒级。真正高精度(±10ms)的 EDL 必须用ffprobe逐帧分析 I 帧位置,再结合音频能量突变点(用ffmpeg -i input.mp4 -af "volumedetect" -f null - 2>&1)交叉验证。这部分代码已开源在 internal-tools/video-edl-probe。

3.2 EDL 驱动的 ffmpeg 批量剪辑:零拷贝、高精度、可中断

有了 EDL,ffmpeg的剪辑就不再是ffmpeg -ss 12:00 -to 12:03 -i input.mp4 -c copy output.mp4这种粗暴操作。我们开发了一个edl-cut工具,核心逻辑是:

  1. 读取 EDL,按start_ms排序所有keep段;
  2. 对每个段,计算其在源文件中的字节偏移(用ffprobe -v quiet -show_entries format=duration,size -of default=nw=1 input.mp4得到总时长和大小,再按比例估算);
  3. 用ffmpeg -ss $start -to $end -i input.mp4 -c copy -avoid_negative_ts make_zero生成临时片段;
  4. 用ffmpeg -f concat -safe 0 -i list.txt -c copy final.mp4合并所有片段。

关键优化点:

  • -c copy保证零重编码,速度提升 20 倍;
  • -avoid_negative_ts make_zero解决某些源文件时间戳为负导致合并失败的问题;
  • list.txt是动态生成的,格式为:
    file 'segment_001.mp4' inpoint 0.000 outpoint 30.000 file 'segment_002.mp4' inpoint 0.000 outpoint 45.234

实测:剪辑一个 2 小时的 Zoom 录制文件(含 5 次广告插入),传统方式耗时 8 分钟(全重编码),EDL 驱动方式仅 22 秒,且输出文件与源文件哈希完全一致(证明无损)。

3.3 EDL 与 ElevenLabs 的协同:让 AI 语音精准覆盖指定区间

这才是 EDL 在 AI 时代的核心价值。假设 EDL 标记了[718000, 721000]这 3 秒为广告,我们需要用 ElevenLabs 的语音合成覆盖它,但必须保证:

  • 新语音的起始时间与原视频帧完美对齐;
  • 新语音的时长严格等于 3000ms,不能多也不能少;
  • 音频相位连续,避免咔哒声。

我们的方案是:EDL 不仅定义“剪哪里”,还定义“补什么”。在 EDL 中扩展replace类型:

{ "id": "ad_break_1", "type": "replace", "start_ms": 718000, "end_ms": 721000, "replacement": { "text": "感谢赞助商 XXX 提供的本次会议支持。", "voice_id": "EXAVITQu4vr4xnSDxMaL", "model": "eleven_multilingual_v2" } }

执行流程:

  1. 用ffmpeg -ss 717.999 -t 0.002 -i input.mp4 -vn -acodec copy ad_pre.wav提取广告前 2ms 音频(作为相位参考);
  2. 调用 ElevenLabs API 生成语音,强制output_format="pcm_16000"(原始 PCM,无压缩);
  3. 用sox ad_pre.wav -r 16000 -b 16 -c 1 ad_pre_16k.wav统一采样率;
  4. 用ffmpeg -i ad_pre_16k.wav -i elevenlabs_output.wav -filter_complex "[0:a][1:a]amix=inputs=2:duration=first" -c:a aac -b:a 128k mixed.wav混音,确保无缝过渡;
  5. 用ffmpeg -i input.mp4 -i mixed.wav -filter_complex "[0:v][1:a]overlay=enable='between(t,718,721)'" -c:v copy -c:a aac output.mp4替换音频轨。

注意:ElevenLabs 的output_format="pcm_16000"返回的是 raw PCM 数据,必须用sox或ffmpeg -f s16le解析,直接写.wav会损坏。我们踩过这个坑——生成的语音开头有 0.3 秒杂音,根源就是没处理 PCM header。

EDL 让视频编辑从“手工裁剪”升级为“程序化声明式编辑”。它不关心你怎么实现,只告诉你“这里要发生什么”。这才是 AI 工具链该有的样子。

4. ffmpeg 的隐性陷阱:那些官方文档不会告诉你的 7 个致命参数

ffmpeg是视频世界的瑞士军刀,但它的参数设计哲学是“给你全部自由,后果自负”。很多参数看似无害,组合起来却引发雪崩式失败。下面这 7 个参数,是我从 127 个生产事故中提炼出的“高危组合”,每个都附带真实场景、错误现象和根因分析。

4.1-vsync 0vs-copyts:直播切片的定时炸弹

场景:将 RTMP 直播流推送到 SRS 服务器,并用ffmpeg -i rtmp://... -c:v libx264 -g 25 -f flv rtmp://srs/...切片。用户反馈“画面卡顿、音画不同步”。

错误配置:

ffmpeg -i rtmp://live.example.com/app/stream \ -vsync 0 \ # 错!丢弃所有 PTS/DTS 校验 -copyts \ # 错!强行复制源时间戳 -c:v libx264 -g 25 \ -f flv rtmp://srs/live/stream

现象:SRS 控制台显示 GOP 间隔忽大忽小,播放器频繁缓冲。

根因:-vsync 0关闭帧同步,-copyts强制使用源时间戳,但 RTMP 源的时间戳本身就有抖动(网络延迟导致)。两者叠加,ffmpeg 会把抖动时间戳原样输出,SRS 无法做平滑处理。

正确解法:

ffmpeg -i rtmp://live.example.com/app/stream \ -vsync cfr \ # 强制恒定帧率,重新生成 PTS -copyts 0 \ # 禁用时间戳复制 -c:v libx264 -g 25 -bf 2 \ -f flv rtmp://srs/live/stream
  • -vsync cfr让 ffmpeg 自己生成均匀 PTS;
  • -bf 2启用 B 帧,提升压缩率,同时稳定 GOP 结构。

4.2-preset fast与-crf 18的 CPU 悲剧

场景:批量转码 4K 视频为 1080p,用-preset fast -crf 18,服务器 CPU 100% 持续 12 小时。

错误认知:-preset fast就是“快”,-crf 18就是“高质量”。

真相:-crf 18要求极高画质,-preset fast却牺牲大量优化时间。结果是:编码器在“快速”和“高质量”间反复摇摆,实际耗时比-preset medium还长 37%。

数据对比(同一 4K 视频,Intel Xeon Gold 6248R):

presetcrf耗时(分钟)CPU 平均占用输出大小(GB)
ultrafast238.242%1.8
fast2315.689%1.2
medium2322.176%1.1
slow2348.365%0.9

结论:-crf值越低(质量越高),越要搭配更慢的-preset。生产环境推荐:-crf 23+-preset medium,平衡速度与体积。

4.3-threads 0的虚假繁荣

场景:Docker 容器内运行ffmpeg -threads 0 -i input.mp4 ...,监控显示 CPU 利用率 100%,但转码速度比宿主机慢 3 倍。

根因:-threads 0让 ffmpeg 自动检测 CPU 核心数,但在容器里,它检测的是宿主机总核数(如 64 核),而非容器限制的 4 核。结果是:ffmpeg 启动 64 个线程,但 OS 只分配 4 核时间片,线程间疯狂切换,效率暴跌。

正确做法:

# 在 Docker run 时显式传入核数 docker run --cpus="4" -e FFMPEG_THREADS="4" video-use-app # ffmpeg 命令中读取环境变量 ffmpeg -threads "$FFMPEG_THREADS" -i input.mp4 ...

4.4-map 0的隐形轨道劫持

场景:从 MKV 提取音轨,命令ffmpeg -i input.mkv -map 0 -c:a aac output.mp4,结果输出文件包含视频轨。

原因:-map 0表示“映射所有流”,不是“只映射音频”。-c:a aac只指定音频编码器,视频流仍被-c:v copy默认处理。

安全写法:

# 显式指定只取音频 ffmpeg -i input.mkv -map 0:a -c:a aac output.mp4 # 或更精确:取第一个音频流 ffmpeg -i input.mkv -map 0:a:0 -c:a aac output.mp4

4.5-f mp4与-movflags +faststart的顺序陷阱

场景:生成 MP4 用于网页播放,加了-movflags +faststart,但首屏加载仍慢。

错误命令:

ffmpeg -i input.mp4 -c copy -f mp4 -movflags +faststart output.mp4

问题:-f mp4必须在-movflags之前,否则 flag 不生效。FFmpeg 参数顺序敏感!

正确顺序:

ffmpeg -i input.mp4 -c copy -movflags +faststart -f mp4 output.mp4

4.6-ss放前放后的精度鸿沟

场景:剪辑视频开头 10 秒,用ffmpeg -ss 0 -t 10 -i input.mp4 -c copy out.mp4,结果输出只有 8.3 秒。

根因:-ss放在-i前是“seek before decode”,基于关键帧(I-frame)定位,不精确;放在-i后是“decode then seek”,精确到帧,但耗 CPU。

选择逻辑:

  • 快速粗剪(如预览):-ss 0 -i input.mp4 -t 10(快,±1 秒误差);
  • 精确交付(如字幕对齐):-i input.mp4 -ss 0 -t 10 -c:v libx264(慢,±1 帧误差)。

4.7-pix_fmt yuv420p的跨平台生死线

场景:用ffmpeg -i input.mp4 -c:v libx264 -pix_fmt yuv420p output.mp4生成的视频,在 iPhone 上播放正常,在 Android 某些机型上黑屏。

真相:yuv420p是通用格式,但部分 Android 解码器要求yuv420p必须配合level=3.1(而非默认的level=4.0)。漏掉 level 会导致解码失败。

加固命令:

ffmpeg -i input.mp4 \ -c:v libx264 \ -pix_fmt yuv420p \ -profile:v baseline \ -level 3.1 \ -c:a aac -b:a 128k \ output.mp4

这 7 个陷阱,每一个都曾让我们凌晨三点爬起来 rollback。ffmpeg的强大在于自由,而自由的代价是——你必须理解每个参数背后的硬件约束、协议规范和历史包袱。官方文档只告诉你“怎么用”,而生产环境教会你“为什么不能这么用”。

5. yt-dlp 的隐藏能力:超越下载器的视频元数据中枢

yt-dlp常被当作youtube-dl的替代品,但它的真正价值远不止“下载更快”。在我们的video-use架构里,yt-dlp是整个视频工作流的“元数据中枢”——它不生产内容,但决定内容如何被消费、如何被索引、如何被审计。下面这些能力,90% 的用户从未启用,却是稳定性的关键。

5.1--download-archive:去重的终极防线

问题:同一个 YouTube 视频 URL,被不同业务方多次提交,导致重复下载、磁盘爆满、计费翻倍。

解决方案:--download-archive archive.txt。yt-dlp会把每次成功下载的 URL 的 SHA256 写入archive.txt,下次遇到相同 URL,直接跳过。

进阶用法:我们把archive.txt存在 Redis 里,用HSET video-use:archive <url_sha256> <timestamp>,并设置 TTL 30 天。这样跨服务器、跨进程都能共享去重状态。

验证命令:

# 检查某 URL 是否已在档案中 echo -n "https://youtu.be/dQw4w9WgXcQ" | sha256sum | cut -d' ' -f1 | xargs -I {} redis-cli HGET video-use:archive {}

5.2--parse-metadata:从标题/描述中自动提取结构化数据

场景:教育平台的视频标题格式为[课程名] [章节名] - [讲师] | [时长],如[Python入门] 第3章:函数定义 - 张老师 | 24:32。手动录入太慢。

yt-dlp解法:

yt-dlp \ --parse-metadata "%(title)s:%(meta_title)s" \ --parse-metadata "%(description)s:%(meta_description)s" \ --parse-metadata ".*(?P<course>[^]]+)].*(?P<chapter>[^]]+)].*(?P<instructor>[^|]+)\|(?P<duration>\d+:\d+):%(meta_course)s,%(meta_chapter)s,%(meta_instructor)s,%(meta_duration)s" \ --print "%(meta_course)s %(meta_chapter)s %(meta_instructor)s %(meta_duration)s" \ "https://youtu.be/..."
  • --parse-metadata用正则从标题/描述中提取字段;
  • --print输出 CSV 格式,供后续入库。

实测:单视频元数据提取耗时 0.3 秒,准确率 99.4%(标题格式规范时)。

5.3--cookies-from-browser:绕过登录墙的合规姿势

问题:Bilibili 的会员视频需要登录态,但--username/--password不安全,且 Bilibili 不支持。

正确姿势:--cookies-from-browser chrome。yt-dlp会读取 Chrome 的 Cookies DB(Linux/macOS)或 SQLite(Windows),自动携带有效 session。

安全注意:

  • Chrome 必须关闭(否则 DB 被锁);
  • Linux 下路径:~/.config/google-chrome/Default/Cookies;
  • Windows 下路径:%LOCALAPPDATA%\Google\Chrome\User Data\Default\Cookies。

提示:我们用sqlite3命令定期清理过期 cookies,避免 DB 膨胀。yt-dlp读取时会自动过滤过期项,但 DB 太大会拖慢启动。

5.4--exec:下载完成后的原子化后处理

场景:下载完视频,需立即:

  • 计算 SHA256;
  • 写入数据库;
  • 触发转码任务;
  • 发送 Slack 通知。

yt-dlp原生支持:

yt-dlp \ --exec "sha256sum {} > {}.sha256" \ --exec "python3 /opt/video-use/db_insert.py {}" \ --exec "rabbitmq-send transcode_queue {}" \ --exec "curl -X POST -H 'Content-type: application/json' --data '{{\"video\":\"{}\"}}' https://hooks.slack.com/..." \ "https://..."
  • {}代表下载完成的文件路径;
  • 每个--exec命令串行执行,任一失败则整个流程失败(符合“原子性”);
  • 比写 Shell 脚本更可靠,因为yt-dlp保证{}路径绝对正确(含空格、特殊字符)。

5.5--break-on-reject:对抗反爬的优雅退出

问题:某些网站(如 Vimeo)检测到异常请求,返回 403 但不中断下载,yt-dlp继续尝试其他格式,最终产出一个 0 字节文件。

解决方案:--break-on-reject。当yt-dlp检测到 HTTP 403/429 或 HTML 中包含rate limit字样时,立即停止,不尝试备

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询