FFmpeg tách video và hợp nhất trở lại


8

Tôi đang cố gắng sử dụng FFmpeg để phân tách video dựa trên một số start_timeend_timeđầu vào và thay thế video đó bằng các tệp video khác. Chẳng hạn, đối với đầu vào, 10 15tôi sẽ cần thay thế CHÍNH XÁC 10 to 15bằng một video khác.

ĐỒNG Ý. Điều gì đến trong tâm trí tôi là thế này:

  1. Đầu tiên chia video (trong trường hợp này là 0-10, 10-15 và 15-end)
  2. Thay thế 10-15 bằng video khác
  3. Hợp nhất tất cả các video phụ trở lại

Câu hỏi đầu tiên: Đây có phải là giải pháp tốt nhất và nhanh nhất? Chúng ta có một lệnh dễ dàng hơn hoặc các công cụ khác để thay thế một khoảng thời gian cụ thể trong video bằng một video khác không?

Câu hỏi thứ hai: Giả sử FFmpeg là giải pháp khả thi, khi tôi chỉ cần sử dụng lệnh ffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4, mã xử lý video của tôi không thể đọc và xử lý tệp. Tôi đã sử dụng mediainfocông cụ để so sánh hai tệp và nhận thấy sự khác biệt về kích thước tiêu đề trong khi tất cả các công cụ liên quan đến codec video đều giống nhau. Tôi nhận thấy KÍCH THƯỚC ĐẦU là khác nhau rõ ràng gây ra vấn đề. Có cách nào để buộc kích thước tiêu đề cũng (ngoài codec) giống nhau không?

CẬP NHẬT: Đây là .mp4tập tin gốc hoạt động tốt trong trình giả lập.


Đầu tiên chúng tôi sẽ phải giải quyết vấn đề bạn đề cập trong câu hỏi thứ hai của bạn. Vui lòng hiển thị chính xác lệnh bạn đang sử dụng và đầu ra dòng lệnh đầy đủ, không bị cắt mà bạn nhận được từ ffmpeg. Cũng hiển thị bất kỳ lỗi thực tế nào bạn gặp phải khi đọc tệp - thật tốt khi biết "mã xử lý" của bạn là gì, chính xác.
slhck

@slhck mã xử lý video là một cơ sở mã lớn. Tôi không thể chia sẻ nó. Nó chỉ là vì một số lý do mà tập tin gốc được đọc nhưng không phải là tập tin được tạo lại. Tuy nhiên tôi có thể chia sẻ .mp4tập tin gốc nếu cần.
Ariana

Tôi đã sử dụng công cụ mediainfo để so sánh hai tệp và nhận thấy sự khác biệt về kích thước tiêu đề và nội dung
Ariana

Có bản gốc sẽ giúp ích, nhưng chúng tôi sẽ không thể khắc phục lý do tại sao nó không thể được đọc, tôi sợ, nếu đó là một số mã nội bộ.
slhck

@slhck Tôi đã tải tệp lên. Câu hỏi của tôi được cập nhật
Ariana

Câu trả lời:


9

Sử dụng trimconcat- các tệp nguồn với các codec khác nhau

Đối với điều này, hãy đảm bảo rằng các tệp riêng lẻ của bạn có cùng độ phân giải, và lý tưởng là cùng một mẫu phụ khung và sắc độ, v.v ... Điều này sẽ ngăn ngừa lỗi hoặc trục trặc trong quá trình ghép.

Bạn có thể thực hiện mọi thứ trong một lần mà không cần tách tệp, sử dụng trimconcatbộ lọc:

ffmpeg -i edv_g24.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[v0][v1][v2]concat=n=3:v=1:a=0[out]" \
-map "[out]" output.mp4

Ở đây, trimđược sử dụng để chỉ định các phần riêng lẻ của các luồng video đầu vào ( 0:v, 1:v) mà sau này bạn muốn nối. Những phần này được đặt tên v0thông qua v2. (Bộ setptslọc đặt lại dấu thời gian của các phần riêng lẻ này thành 0, được yêu cầu để ghép). Sau đó, chúng tôi nối ba phần.

Nếu bạn muốn cắt từ một dấu thời gian nhất định đến hết, hãy sử dụng trim=start=15thay vì chỉ định phạm vi.

Nếu tệp của bạn có âm thanh, bạn phải cắt riêng các luồng đó:

ffmpeg -i edv_g24_2.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[1:a]atrim=0:5,asetpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; \
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4

Lưu ý rằng video và âm thanh sẽ được mã hóa lại trong trường hợp này - đảm bảo chỉ định các mục tiêu chất lượng đầu ra phù hợp (ví dụ: -crfx264, x265 hoặc libvpx-vp9). Bạn có thể đọc thêm về điều này trên FFmpeg Wiki, ví dụ cho VP9 hoặc H.264 .

Sử dụng các phân đoạn riêng lẻ

Nếu bạn muốn tách các clip và sau đó lắp lại chúng:

ffmpeg -i edv_g24.mp4 -ss 0 -to 10 -c copy part1.mp4
ffmpeg -i edv_g24.mp4 -ss 10 -to 15 -c copy part2.mp4
ffmpeg -i edv_g24.mp4 -ss 15 -c copy part3.mp4

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][1:v][2:v]concat=n=3:v=1:a=0[outv]" \
-map "[outv]" -t 30 output.mp4

Nếu các tệp có âm thanh, sử dụng cách tiếp cận tương tự như trên:

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -t 30 output.mp4

Điều này sẽ một lần nữa mã hóa lại luồng video. Nó đơn giản hơn một chút nhưng nếu không thì tương đương với phương pháp trên.

Sử dụng concatdemuxer

Về nguyên tắc, bạn cũng có thể cố gắng nối các dòng bit mà không cần mã hóa lại chúng, bằng cách sử dụng bộ giải mã concat. Tạo một tệp được gọi concat.txtvà thêm các mục sau (tương ứng với các video clip được tạo ở trên):

file 'part1.mp4'
file 'short-video.mp4'
file 'part3.mp4'

Sau đó nối các tệp riêng lẻ này:

ffmpeg -f concat -i concat.txt -c copy output.avi

Tuy nhiên, điều này đòi hỏi các clip của bạn phải có cùng codec, độ phân giải, tốc độ khung hình, v.v. - vì vậy nó không hoạt động với tất cả các loại nguồn không đồng nhất.

Sử dụng concatgiao thức

Loại kết hợp cấp độ tệp ở trên cũng có thể đạt được bằng cách sử dụng concatgiao thức, với cùng một loại ràng buộc như trên (cùng codec, độ phân giải, v.v.):

ffmpeg -i "concat:part1.avi|part2.avi|part3.avi" -c copy output.mp4

Để biết thêm thông tin về ghép nối, hãy đọc trang Wiki FFmpeg tương ứng .


Điều này có vẻ rất đầy đủ! Cảm ơn. Tôi sẽ thử chúng!
Ariana

Idk tại sao sử dụng concatphương pháp đưa ra một lỗi:[concat @ 00000000025c2560] Line 1: unknown keyword 'part1.mp4 \\ text.txt: Invalid data found when processing input
Ariana

Đối với "sử dụng các phân đoạn riêng lẻ", tôi thấy tạm dừng và cắt nhỏ đầu ra. Có cách nào để khắc phục điều này?
Ariana

Phương pháp 1 hoạt động hoàn hảo. Một điều: làm thế nào chúng ta có thể chỉ định "cho đến khi kết thúc" mà không nêu rõ một con số cụ thể (thay vì 30 giây)
Ariana

1
Xin lỗi, đã làm sai. Đối với concatdemuxer, cú pháp là khác nhau. Đã sửa bây giờ. Để đi đến cuối cùng, hãy sử dụng trim=start=15, xem tài liệu về bộ lọc trim: ffmpeg.org/ffmpeg-filters.html#trim - đối với các vấn đề về thời gian, điều này thực sự phụ thuộc vào tài liệu nguồn của bạn. Không có vấn đề gì liên quan đến mặc dù với clip bạn đã tải lên.
slhck
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.