
我讀過有關切割和拼接的內容連接但這對我來說還不夠。
我想剪切標記的視訊部分並加入到單一視訊檔案中而不需要重新編碼。是否可以一次性(在記憶體中)剪切和合併?
理論上,要剪切或連接的視訊部分的數量應該沒有限制。音訊應該同步。
影片:H.264+AAC
編輯:
從答案中我了解到仍然需要視訊重新編碼。
我想澄清一下,從視訊檔案中間剪切視訊剪輯可能需要多個步驟來完成。我認為一次性處理影片可以透過節省一些 I/O 活動來提高效能。然而,它本身並不是一個目標。
答案1
如果我沒猜錯的話,你的問題有四個主要部分:
- 如何從電影中剪切時間片段
- 如何將多個片段合併在一起
- 如何在不轉碼電影的情況下執行上述操作,從而不損失任何質量
- 如何在速度方面有效率地完成上述工作
切割一個時間段
您可以透過使用選項跳到其起點來剪切片段-ss
,然後使用 設定片段的持續時間-t
,或使用 設定端點-to
:
# skip 30 seconds, then copy the next 60 seconds
ffmpeg -ss 30 -t 60 full-movie.mp4 segment.mp4
在 ffmpeg 文件中,請參閱 部分5.4 主要選項-ss
關於將和-t
選項放在輸入檔案之前或輸出檔案之前的區別。一旦您嘗試過這一點,您可能會發現這種差異與您的情況有關。
重要提示:上面的範例導致影片被轉碼。我們將在下面討論在不進行轉碼的情況下執行此操作的可能性。
合併多個段
執行電影合併的主要方法有三種,本文對其中兩種做了最好的解釋ffmpeg 維基文章,第三個是連接解復用器。如果所有片段在 a/v 編碼規格和容器格式方面都相同,您可能會發現最簡單的方法是協定concat:
:
# merge the segments
ffmpeg -i "concat:seg1.mp4|seg2.mp4|seg3.mp4" final.mp4
需要注意的是,這次合併,就像剪輯一樣,再次對電影進行轉碼,所以我們這裡有一個轉碼的轉碼,可能會降低視頻質量,所以我們真的我們希望盡可能避免這種轉碼!
無需轉碼即可剪切和合併
前面部分中的範例需要轉碼的原因是因為每個文件和每個生成的片段都是一個獨立的電影,它被打包為提供您打開完整電影時期望的所有內容,例如電影的持續時間和其他內容元資料。但是,嘿,您不希望將這些片段作為獨立的電影來播放,您希望這些片段成為更大的視訊串流的一部分。因此,您最好將輸入檔案重新打包(重新重複使用)到即時串流容器中,而不是將 ffmpeg 與盒裝電影一起提供,而忘記此時您並不真正需要的標頭內容。對於 H.264,流復用格式稱為 MPEG-TS,以下是如何在不轉碼的情況下重新重複使用串流的方法:
# re-muxing the whole movie (see a better option in next example)
ffmpeg -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb full-movies-as-ts.ts
好吧,既然您已經了解了,您不妨利用這個機會只剪切您需要的部分:
# skip 30 seconds and re-mux a 60 seconds segment
ffmpeg -ss 30 -t 60 -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb segment.ts
當您合併 TS 片段時,您也可以重新重複使用回 mp4 容器:
# merge the segments and re-mux them as mp4
ffmpeg -i "concat:seg1.ts|seg2.ts|seg3.ts" -c:v copy -c:a copy -movflags empty_moov -flags global_header -bsf:v dump_extra edited-final.mp4
現在我們已經完成了整個過程,無需對電影進行轉碼,保留了原始品質。但與往常一樣,有一個警告......
警告:只能在關鍵影格邊界上進行剪切。說明:H.264 將壓縮幀組織在資料包中,每個資料包都以第一幀的完整壓縮影像開始,然後是後續幀的增量,從而減少每個資料包所需的儲存空間。就我們的目的而言,每個資料包就像該持續時間內所有幀的密封拉鍊 - 它要么是全部,要么沒有。如果您只想要資料包的一部分,那麼您必須將其解壓縮並重新壓縮,換句話說 - 對其進行轉碼。因此,只有當您要剪切影片的每個位置都有關鍵影格時,上述方法才有意義。例如,如果每 5 秒有一個關鍵幀,則只能每 5 秒剪切一次。
所以現在的問題是您是否可以接受剪切點的限制,特別是因為您可能不知道電影中的哪個位置有關鍵影格。這就是我上面建議閱讀的原因5.4 主要選項關於在輸入前或輸出前指定-s
and 。-t
如果您在輸入之前指定,那麼 ffmpeg 將找到附近的關鍵影格來執行您的請求,該關鍵影格將「或多或少」位於您想要執行剪切的位置。如果您不介意切割的精確性,那就好,那就去做吧。
但如果您需要剪切在那個精確的位置,那麼您別無選擇,您必須對電影進行解碼才能精確定位您要查找的幀。好吧,至少我們有一些好消息:您可以使用單一轉碼來代替轉碼和重新轉碼,這在一定程度上改善了情況:
# skip PRECISELY 30 seconds and transcode a 60 seconds TS segment
ffmpeg -i full-movie.mp4 -ss 30 -t 60 -bsf:v h264_mp4toannexb segment.ts
由於產生的片段將位於 TS 中,因此在將片段合併在一起時無需再次轉碼。
速度
在裡面關於合併的 ffmpeg wiki 文章有一個關於如何通過管道運行整個過程的解釋,從而消除了對中間文件的需要並加快了整個過程。不。它會帶你更長。在記憶體中完成這一切需要更長的時間的原因並不是因為它會運行更長時間,而是因為在考慮如何完成整個事情時不會有中間結果,並且您會發現自己再次運行整個過程並且再次。因此,管道理論很好,但就您而言,您應該從制定和完善每個步驟開始。您會發現,要讓一切正常運作並產生良好的結果,需要進行更多的調整和調整。一旦您掌握了整個過程並希望為自動批次編輯編寫一些腳本,那麼您就可以重新審視管道概念。
希望以上內容有幫助。