從命令列分割 MPEG 視訊?

從命令列分割 MPEG 視訊?

我有一張自製的 DVD,我正在有效地嘗試插入章節並重新排列 - 原作者將其刻錄為一個長章節,我想將其撕成更小的片段並將其重新編碼到新的 DVD 中。我使用以下指令翻錄了 DVD:

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

我正在使用 mplayer 版本 1.0-rc2_p20090731(Portage 中的最新版本)來運行 Gentoo Linux。

我有一個章節應該跨越的時間列表(例如 30:11-33:25),所以我的第一個想法是翻錄整個 DVD 並使用mpgtx剪切文件的某些部分。我的問題是,mpgtx -i在文件上運行會報告相當多的時間戳跳躍:

時間戳從 59.753789 躍升至位置 1d29800 的 0.001622
時間戳從 204963823030450.343750 躍升至位置 2d4f800 的 31.165900
時間戳從 60.077878 躍升至位置 43cc000 的 0.001622
時間戳從 60.024233 躍升至位置 65c5000 的 0.001622
時間戳從 204963823068631.718750 躍升至位置 7fd1000 的 52.549244

我嘗試使用以下方法修復索引:

mencoder raw.vob -oac 複製 -ovc 複製 -forceidx -o 固定.vob -of mpeg

但 mpgtx 仍然會報告時間戳問題。我迫在眉睫的問題:有沒有辦法獲取我的翻錄電影並更正其時間戳,以便我可以用 mpgtx 剪切它?如果我能解決這個問題,製作 DVD 的其餘部分就會一帆風順。

如果無法修復此文件上的時間戳記:是否有更好的方法將 DVD 的小塊分成單獨的文件以便稍後重新編譯?我非常希望在 Linux 上完成這件事,如果我能以某種方式編寫腳本那就更好了(輸入開始和結束位置的列表,或者開始時間和持續時間,並獲得一系列撕裂的內容)文件)。如果需要的話,我還有一台 Mac OS X 機器,但沒有 Windows。

編輯:我最終找到了另一個解決方案手煞車ffmpeg(在幫助下這個問題),但問題依然存在。

再次編輯:事實證明我的另一個解決方案不太有效——音訊不同步了大約五秒,大約是我削減的英里數的一半——所以我又回到了第一個方向。任何人?

答案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

相關內容