从命令行分割 MPEG 视频?

从命令行分割 MPEG 视频?

我有一张自制的 DVD,我想在其中插入章节并重新排列 - 原作者将其刻录为一个长章节,我想将其翻录成较小的部分并将其重新编码到新的 DVD 中。我使用以下命令翻录了 DVD:

mplayer dvd:// -dvd-device /dev/sr2 -dumpstream -dumpfile raw.vob

我正在运行 Gentoo Linux 和 mplayer 版本 1.0-rc2_p20090731(Portage 中最新版本)。

我有一个章节应该跨越的时间列表(例如 30:11-33:25),所以我的第一个想法是翻录整个 DVD 并使用mpgtx剪切出文件的某些部分。我的问题是,mpgtx -i在文件上运行报告了相当多的时间戳跳转:

时间戳在位置 1d29800 处从 59.753789 跳转到 0.001622
时间戳从 204963823030450.343750 跳转到位置 2d4f800 处的 31.165900
在位置 43cc000 处,时间戳从 60.077878 跳转到 0.001622
时间戳在位置 65c5000 处从 60.024233 跳转到 0.001622
时间戳从 204963823068631.718750 跳转到位置 7fd1000 处的 52.549244

我尝试使用以下方法修复索引:

mencoder raw.vob -oac 复制 -ovc 复制 -forceidx -o fixed.vob -of mpeg

但 mpgtx 仍会报告时间戳问题。我立即想到的问题是:有没有办法获取我已翻录的电影并更正其时间戳,以便我可以使用 mpgtx 进行剪切?如果我能解决这一问题,那么制作 DVD 的其余部分就会一帆风顺。

如果无法修复此文件的时间戳:有没有更好的方法将 DVD 的小块翻录成单独的文件以便以后重新编译?我非常希望这可以在 Linux 上完成,如果我能以某种方式编写脚本就更好了(输入开始和结束位置的列表,或开始时间和持续时间,然后获取一系列翻录的文件)。如果需要,我还有一台 Mac OS X 机器可用,但没有 Windows。

编辑:我最终找到了另一个解决方案手刹ffmpeg(在以下人员的帮助下这个问题),但问题依然存在。

再次编辑:事实证明,我的其他解决方案并不奏效 - 音频不同步了大约五秒钟,大约是我所减少的 mpg 的一半 - 所以我又回到了原点。有人吗?

答案1

FFmpeg 将为您完成此操作。

你的命令可能看起来像这样:

代码:ffmpeg -i input.mpg -ss 00:00:10 -t 00:00:30 out1.mpg -ss 是视频文件开头的 hh:mm:ss 中的起点

-t 是新段的时间长度(以 hh:mm:ss 为单位)。

因此,在上面的例子中,您从原始文件的开头 10 秒开始,并在 30 秒后结束。

如果您想一次性创建多个部件,那么可以执行以下操作:

代码:ffmpeg -i input.mpg -ss 00:00:10 -t 00:00:30 out1.mpg -ss 00:00:35 -t 00:00:30 out2.mpg 在此示例中,第一段与第一个例子相同,但您还创建了第二个文件,从 35 秒开始,时长为 30 秒。

答案2

我曾经破解过这个来获取 DVD-RAM 的视频:

#! /usr/bin/ruby -w

a = [0, 0x37f9800, 0xf3e1800]

filename = "input.vob"

a.each_with_index{|seq_start, i|
  if seq_start % 1024 != 0 then
    puts "Error: Blocksize doesn't match 1024"
  end

  seq_end = a[i+1]

  if seq_end then
    puts "dd if=#{filename} of=chapter#{i+1}.mpeg bs=1024 skip=#{seq_start/1024} count=#{(seq_end - seq_start)/1024}"
  else
    puts "dd if=#{filename} of=chapter#{i+1}.mpeg bs=1024 skip=#{seq_start/1024}"
  end
}

a变量获取发生跳转的位置值,然后仅用于dd在这些位置将文件切成碎片。结果是每个章节都有单独的 mpeg 文件,因为每次录制停止和重新启动时都会发生跳转。生成的 mpeg 文件没有跳转,然后可以照常处理。

脚本本身实际上并没有调用dd,它只是输出将dd文件切分成几部分所需的命令。

答案3

num=1
offset=0
divide="Title:"
divide="Chapter:"
input="VTS_01_1.VOB|VTS_01_2.VOB|VTS_01_3.VOB|VTS_01_4.VOB|VTS_01_5.VOB|VTS_01_6.VOB" 
#|VTS_01_7.VOB|VTS_01_8.VOB|VTS_01_9.VOB"

for len in $(lsdvd -c VIDEO_TS | grep "$divide" | awk -F' +|,' '/Length:/ { print $5 }')
do
 ss=$(date -u -d "@$offset" +%T.%3N)

 echo $num $ss $len
 cd VIDEO_TS
 #ffmpeg -ss $ss -i "concat:$input" -t $len -c copy ../$(printf "%02d" $num).VOB 2>/dev/null
 ffmpeg -ss $ss -i "concat:$input" -map 0:1 -map 0:3 -t $len -acodec copy -vcodec libx264 ../$(printf "%02d" $num).mp4 2>/dev/null
 cd ..

 len=$(date -u -d "1970-01-01 $len" +%s.%3N)
 offset=$( echo "$offset + $len" | bc )
 num=$((num+1))
done

相关内容