Cách nối các clip từ cùng một video với ffmpeg


15

Tôi có một video dài với nhiều cảnh khác nhau trong đó. Tôi muốn trích xuất và ghép 2 cảnh từ video (không bắt đầu trên khung hình I) bằng cách sử dụng ffmpeg 2.1.4.

Để tranh luận, giả sử tôi muốn 5 giây từ 01:00 và 02:00.

Tôi có thể làm điều này:

ffmpeg -ss 01:00 -i in.mkv -ss 02:00 -i in.mkv -filter_complex "
  [0:v]select='lt(t,5)'[v0];
  [0:a]aselect='lt(t,5)'[a0];
  [v0][a0][1:v][1:a]concat=n=2:v=1:a=1
" -c:a libvorbis -t 10 out.mkv

Điều đó mang lại cho tôi bộ phim tôi muốn, nhưng thực sự chọn buộc ffmpeg phải giải mã toàn bộ phần còn lại của bộ phim. Vì vậy, làm thế nào để tôi nói với nó để cắt ngắn bộ phim đầu tiên thay vì giải mã nó?

Tôi muốn làm điều này với bộ lọc phức tạp ffmpeg, nếu có thể. Tôi biết rằng trước tiên tôi chỉ có thể sử dụng -tđể mã hóa lại các phim riêng biệt, nhưng bước mã hóa bổ sung rất chậm trong trường hợp của tôi và cũng làm mất một lượng chất lượng tương đối cho video này.

Tôi dường như không thể tìm thấy một bộ lọc cắt ngắn chiều dài của hơi nước. Có các nút lọc tương ứng với -thoặc -sstham số không?

Câu trả lời:


16

bộ lọc concat

Phương pháp này là tốt nhất nếu bạn cần thực hiện lọc bổ sung:

Sử dụng trim, atrim, setpts, asetpts, và concatbộ lọc:

ffmpeg -i input -filter_complex \
"[0:v]trim=60:65,setpts=PTS-STARTPTS[v0]; \
 [0:a]atrim=60:65,asetpts=PTS-STARTPTS[a0]; \
 [0:v]trim=120:125,setpts=PTS-STARTPTS[v1];
 [0:a]atrim=120:125,asetpts=PTS-STARTPTS[a1]; \
 [v0][a0][v1][a1]concat=n=2:v=1:a=1[out]" \
-map "[out]" output.mkv
  • setptsasetptssẽ ngăn chặn một đầu ra giật do vấn đề dấu thời gian trình bày.

  • Hãy chắc chắn để sử dụng một phiên bản gần đây. Xem trang Tải xuống FFmpeg để biết các liên kết đến bản dựng cho Windows, OS X và Linux.


trình giải thích concat

Một phương pháp khác là tạo các phân đoạn riêng lẻ và truyền phát sao chép chúng thay vì mã hóa lại (để tiết kiệm thời gian và chất lượng) và tham gia chúng với bộ giải mã concat .

$ ffmpeg -ss 60 -i input -t 5 -codec copy clip1.mkv
$ ffmpeg -ss 120 -i input -t 5 -codec copy clip2.mkv
$ echo "file 'clip1.mkv'" > concat.txt
$ echo "file 'clip2.mkv'" >> concat.txt
$ ffmpeg -f concat -i concat.txt -codec copy output.mkv

2
À, cảm ơn. trim là những gì tôi đã thiếu. Tuy nhiên, phải mất một thời gian rất dài để có được thời gian bù mà tôi chỉ định, như thể giải mã mọi thứ theo nó. Ngoài ra, một phần của đầu ra bị thiếu âm thanh. Để khắc phục, tôi đã chỉ định cùng một đầu vào nhiều lần với -ss, sau đó sử dụng trim để cắt bớt video. Bạn không cần setpts trong trường hợp đó, vì ss đặt pts thành 0. Điều đó dường như hoạt động và không có tạm dừng ngẫu nhiên kỳ lạ trong quá trình mã hóa. Đối với việc sao chép luồng, tôi đã thử điều đó trước đây. Nó bắt đầu ở khung hình I trước đó, vì vậy bạn có được một phần khác của bộ phim so với phần bạn muốn.
quét

Bạn vui lòng trả lời câu hỏi của tôi tương tự như câu hỏi này. video.stackexchange.com/questions/18247/ Mạnh
Eftekhari

Điều thú vị là các -filter_complextác phẩm nhưng các concattệp không - tức là video thứ 1 trông ổn nhưng chất lượng của thứ 2 thì thật kinh khủng. Lưu ý, tôi đã sao chép chính xác các lệnh này cho cả hai (ngoại trừ tệp đầu vào).
bobmarkie

7

Điều này sẽ làm việc nhanh hơn ...

ffmpeg -ss 1:00 -t 5 -i in.mkv -ss 2:00 -t 5 -i in.mkv \
  -filter_complex "[0][1]concat=n=2:v=1:a=1" \ 
  out.mkv

Không cần chỉ định -t trên đầu ra. Không cần phải phân tách âm thanh và video trước khi concat.


1
Điều này sử dụng bộ lọc concat sẽ yêu cầu mã hóa lại. Điều này có thể hoặc không thể được mong muốn bởi người dùng.
llogan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.