ffmpeg tham gia hai tệp mp4 với ffmpeg trên dòng lệnh


28

Tôi có thể tham gia thành công nhiều tệp bằng lệnh sau:

ffmpeg -f concat -i input.txt -codec copy output.mp4

Vấn đề duy nhất với lệnh này là bạn cần đọc các filepath từ tệp văn bản có tên input.txt với nội dung sau:

file 'C:\Users\fabio\Downloads\Super\Sharks\01.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\02.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\03.mp4'

Có cách nào để đạt được cùng một mục tiêu mà không cần phải đọc các filepath từ một tập tin không? Tôi đã thử những điều sau đây không có may mắn:

ffmpeg -f concat -i file "C:\a\b\01.mp4" file "C:\a\b\02.mp4" -codec copy output.mp4
ffmpeg -f concat -i "C:\a\b\01.mp4" "C:\a\b\02.mp4" -codec copy output.mp4

Tôi có phải sử dụng một lệnh khác không?


Câu trả lời:


36

Cập nhật 2019:

Như đã đề cập trong các bình luận, Stack Overflow có một mô tả tuyệt vời về các tùy chọn có sẵn để ghép nối, cũng như thảo luận về phương pháp sử dụng tùy thuộc vào loại tệp bạn đang sử dụng:

Làm cách nào để ghép hai tệp MP4 bằng FFmpeg?

Bản gốc 2016 Trả lời:

Bạn sẽ có thể sử dụng phương thức giao thức concat để kết hợp các tệp:

ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4

Ngoài ra, hướng dẫn FFmpeg thảo luận về một phương pháp dành riêng cho các tệp MP4, để ghép nối chúng một cách dễ dàng, nhưng yêu cầu bạn tạo các tệp tạm thời (hoặc các ống có tên):

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

1
Lệnh đầu tiên làm việc với tôi như một con bơ..tôi mất 2 đến 3 giây để ghép các tập tin 6 mp4 của tôi thành tập tin đầu ra (khoảng 239 MB).
Sachin

22
Lệnh đầu tiên không làm việc cho tôi. Nó chỉ sao chép tập tin đầu tiên.
Luis A. Florit

3
Điều này không hoạt động, nó chỉ sao chép tập tin đầu tiên output.mp4.
crmpicco

2
Nối ghép mức tệp không hoạt động cho MP4, vì vậy giao thức concat không được khuyến nghị cho định dạng này và thường sẽ không hoạt động.
llogan

1
@brasofilo Cảm ơn bạn đã liên kết. Điều này đã quá hạn lâu, nhưng tôi đã cập nhật câu trả lời để chỉ mọi người theo hướng đó.
Carson Darling

5

Bạn có thể thay thế tệp bằng danh sách bằng cách xuất danh sách sang stdoutvà đọc danh sách từ stdinffmpeg:

(echo file 'a.mp4' & echo file 'b.mp4') | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy "result.mp4"

Sử dụng ffmpeg phiên bản 2.4.3-tessus trên Mac OS 10.12.6, điều này chỉ gây ra lỗi: "Tùy chọn không được nhận dạng 'Protocol_whlistist'". Nếu không có tùy chọn Protocol_whlistist, nó dường như chỉ tạo một bản sao của tệp MP4 thứ hai.
James

2

Không, dường như không có cách nào để sử dụng bộ giải mã ffmpeg concat trên một dòng lệnh mà không có một số hack. Bạn cần tạo tệp văn bản đầu vào với danh sách các tệp. Bản thân tôi đã nghĩ điều này kỳ lạ, có lẽ ai đó sẽ thêm nó vào FFMpeg vào một ngày sau đó.

Câu trả lời được chấp nhận cho câu hỏi này sử dụng giao thức concat, không phải là demuxer concat, đó là những gì OP yêu cầu.


1
Thật ra là có. stdin.
Qwertiy

giao thức concat không nên được sử dụng với MP4 hoặc bất kỳ định dạng nào khác yêu cầu tiêu đề toàn cầu.
llogan

1

Bạn vẫn có thể làm điều đó trong một kịch bản mà không thay đổi lệnh. Cái gì đó như:

echo "file fname1" >$$.tmp    #single redirect creates or truncates file
echo "file fname2" >>$$.tmp   # double redirect appends
echo "file fname3" >>$$.tmp   # do as many as you want.

ffmpeg -f concat -i $$.tmp -codec copy output.mp4

rm $$.tmp  # just to clean up the temp file. 
           # For debugging, I usually leave this out.

$$ mở rộng tới pid của shell đang chạy lệnh, vì vậy tên tệp sẽ khác nhau mỗi khi bạn chạy nó. vì vậy bạn có thể sử dụng $$. txt nếu bạn thích. Hay cái gì khác ...

Ngoài ra, bạn có thể sử dụng các tệp ở đây để thêm một loạt dữ liệu vào tệp:

cat <<EOF >$$.tmp
file fname1
file fname2
file fname3
EOF

bash Biến thay thế hoạt động, do đó bạn có thể xác định một cách lập trình nội dung của tệp, nó không phải sửa. Tôi nhúng loại công cụ này vào các vòng lặp mọi lúc. Cuối cùng, chuyển hướng hoạt động giống như trên, vì vậy> $$. Tmp cắt ngắn rồi viết, >> $$. Tmp nối thêm.


2
Câu hỏi đặt ra, "có cách nào để đạt được cùng một mục tiêu mà không cần phải đọc các filepath từ một tập tin không?" Tất cả những gì bạn đã làm là cung cấp một cách để ghi các filepath vào một tệp (trước khi đọc các filepath từ tệp). Điều này không trả lời câu hỏi.
Scott
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.