我正在使用 yt-dlp 下载一些视频,并告诉它嵌入字幕。这似乎有效,但它以最糟糕的方式生成字幕,即复制文本。
例如,如果音频说“但即使该系统的速度也不足以让你到达其他星系。值得注意的是,有一个使用已证实的物理学的技巧”,那么 YouTube 将显示文本的一半,删除该一半并显示文本的后半部分,然后继续。不会有任何重复。
yt-dlp(或 ffmpeg?)所做的是将文本的前半部分和后半部分显示在两行上,然后用第二行替换第一行,第二行变为接下来的内容。结果是我不断地读两遍这些行!如果它一次只显示一行,它会完美地工作。我不知道这种行为是否有名称,或者它是故意的(设置了某些标志?)还是一个错误。我如何让它生成以与 youtube 显示相同的方式显示在视频上的字幕?
编辑:
这是用于生成视频文件的命令:
yt-dlp.exe -k --write-auto-sub --embed-subs --merge-output-format mp4 https://www.youtube.com/watch?v=b3D7QlMVa5s
答案1
该问题Alain1A45
是指, 获取的字幕中的时间线相互重叠!· 问题 #9038 · ytdl-org/youtube-dl,于 2016 年 3 月 31 日发布,首先建议使用--sub-format ttml --convert-subs vtt
来获取正确的 vtt 文件。几篇帖子说这不再有效。 ,于nickaein
2017 年 10 月 20 日发表评论说:“下载 vtt 格式的字幕解决了这个问题。”
我刚刚尝试过,可以确认做工作(2024/03/07 08:41:56)。
我使用--sub-format vtt --convert-subs vtt
并获得了完美的字幕格式。--sub-format vtt
虽然不是必需的,但我还是将其包括在内,以防该格式已经可用。
答案2
我编写了一个 PHP 脚本来处理字幕并解决重复问题。
function cleanVttFile($fileName, $outputName) {
$lines = file($fileName);
$headers = ['WEBVTT', 'Kind: captions', 'Language: en'];
$modified_lines = [];
$prev_line = "";
foreach ($lines as $line) {
// Skip headers
if (in_array(trim($line), $headers)) {
$modified_lines[] = $line;
continue;
}
// Skip timestamp lines and blank lines
if (preg_match('/\d{2}:\d{2}:\d{2}\.\d{3} --> \d{2}:\d{2}:\d{2}\.\d{3}.*/', $line) || trim($line) == "") {
$modified_lines[] = $line;
continue;
}
// Remove time tags
$stripped_line = preg_replace('/<[^>]*>/', '', $line);
// Compare with previous line
if ($stripped_line != $prev_line || $prev_line == "") {
$modified_lines[] = $line;
}
// Update previous line
$prev_line = $stripped_line;
}
file_put_contents($outputName, $modified_lines);
}