Lặp lại / lặp Video đầu vào với ffmpeg?


52

Tôi chỉ muốn lặp một video mp4 với ffmpeg và giữ các cài đặt và codec hiện tại.

Ví dụ: nếu input.mp4 dài 0h10 và tôi muốn lặp lại 4 lần để output.mp4 dài 0,40, làm thế nào tôi có thể thay đổi dòng lệnh sau để làm điều đó?

ffmpeg -i input.mp4 -c copy output.mp4

Tôi đã thử ...

ffmpeg -loop 4 -i input.mp4 -c copy output.mp4

... nhưng tôi gặp lỗi "Không tìm thấy vòng lặp tùy chọn."


Sử dụng quicktime 7 pro và Mov container. Vì vậy, bạn sẽ không nhận được kích thước tệp lớn hơn so với mã nguồn mở.
Làm việc vào

Câu trả lời:


69

Trình giải thích concat

Điều này cho phép bạn lặp một đầu vào mà không cần phải mã hóa lại.

  1. Tạo một tệp văn bản. Nội dung của một tệp văn bản mẫu để lặp lại 4 lần.

    file 'input.mp4'
    file 'input.mp4'
    file 'input.mp4'
    file 'input.mp4'
    
  2. Sau đó chạy ffmpeg:

    ffmpeg -f concat -i list.txt -c copy output.mp4
    

Dành cho người dùng Linux

Ví dụ này giống như trên nhưng bạn không phải thực hiện thủ công list.txt:

for i in {1..4}; do printf "file '%s'\n" input.mp4 >> list.txt; done
ffmpeg -f concat -i list.txt -c copy output.mp4

Với hầu hết các shell hiện đại được sử dụng phổ biến, bạn thậm chí có thể tránh việc tạo list.txttệp hoàn toàn. Ví dụ: với bash:

ffmpeg -f concat -i <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -c copy output.mp4

Cũng thấy:


bộ lọc vòng lặp

Ví dụ sử dụng bộ lọc vòng lặp để lặp 4 lần, mỗi vòng lặp là 75 khung hình, mỗi vòng lặp bỏ qua 25 khung hình đầu tiên của đầu vào:

ffmpeg -i input -filter_complex loop=loop=3:size=75:start=25 output
  • Hoặc sử dụng tốc ký: loop=3:75:25
  • Lọc đòi hỏi phải mã hóa lại.
  • Bộ lọc này đặt tất cả các khung vào bộ nhớ .
  • Sử dụng loop=3sẽ lặp 4 lần.
  • Để lặp vô hạn sử dụng -1.
  • Bạn phải liệt kê số lượng khung hình cần lặp (hiển thị là 75 trong ví dụ trên). Giá trị tối đa là 32767.
  • Cũng thấy ffmpeg -h filter=loop.

bộ lọc phim

Bộ lọc phim có tùy chọn vòng lặp. Xem câu trả lời dưới đây của Monah Tuk. Lọc đòi hỏi phải mã hóa lại. Đối với âm thanh, sử dụng bộ lọc amovie.


-stream_loop Lựa chọn

Xem câu trả lời dưới đây của Thingy và câu trả lời của Gyan.

Lưu ý rằng tùy chọn này lỗi (xem báo cáo lỗi # 5719 , # 6121# 7043 ) vì vậy có thể không hoạt động đối với các bản dựng cũ (bất cứ thứ gì cũ hơn 2018 06-27 bao gồm cả nhánh phát hành FFmpeg 4.0.x). Đối với người dùng các bản dựng cũ, như được đề cập bởi mulvya trong vé số 6121, một cách giải quyết khác là lần đầu tiên chuyển lại thành MKV hoặc TS sau đó sử dụng -stream_looptrong lệnh tiếp theo.


-loop Lựa chọn

Các -looptùy chọn là cụ thể cho các tập tin hình ảnh demuxergif muxer , vì vậy nó không thể được sử dụng cho các file video thông thường, nhưng nó có thể được sử dụng để lặp vô hạn một loạt các hình ảnh đầu vào. Ví dụ này sẽ lặp đi lặp lại nhưng -t 30sẽ giới hạn thời lượng đầu ra là 30 giây:

ffmpeg -loop 1 -i %03d.png -t 30 output.mkv

Hoặc để lặp một đầu ra GIF:

ffmpeg -i input -loop 3 output.gif

Điều này có hoạt động tốt với các tập tin mp4?
Thomas King

3
Tôi gặp lỗi này> <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -bash: /dev/fd/63: Permission denied
JZ11

1
@jamesfzhang - Tôi nghĩ đó là vì bạn cần một đường dẫn tuyệt đối đến tệp (như được giải thích ở đây: trac.ffmpeg.org/wiki/Concatenate ). Để thực hiện điều đó, bạn có thể viết: ffmpeg -safe 0 -f concat -i <(đối với i trong {1..4}; do printf "tệp '$ PWD' / '% s' \ n" input.mp4; xong ) -c sao chép đầu
ra.mp4

1
Đối với tôi, điều này hoạt động để lặp lại video toàn thời gian mà không bỏ qua các lần nổi tiếng trong 4 lầnffmpeg -i video.mp4 -filter_complex "loop=4:32767" output.mp4
Vlad

Vấn đề này đã được 4 tuổi và không ai nhận thấy rằng liên kết đến vấn đề thứ hai trong -stream_loopphần này đang chỉ đến cùng một vé với cái đầu tiên ...
Leonid Usov

15

Ít nhất là trên FFmpeg 2.8.x (nhưng oldie cũng hoạt động), bạn có thể sử dụng lavfilàm định dạng đầu vào và biểu đồ bộ lọc phức tạp bằng cách sử dụng moviesetptsbộ lọc làm đối số cho -itùy chọn.

Lệnh tiếp theo thực hiện công việc này cho bạn:

ffmpeg -re -f lavfi -i "movie=filename=input.mp4:loop=0, setpts=N/(FRAME_RATE*TB)" output.mp4

Không loop=đối số có nghĩa là vòng lặp vô cực. Giá trị lớn hơn không đặt số lần lặp lại. setptscác bộ lọc cần thiết để điều chỉnh PTS cho các lần lặp lại thứ hai và sau đó, nếu không, hầu hết các bộ chuyển đổi đầu ra sẽ thất bại với việc tăng PTS không đơn điệu: vòng lặp không tính lại PTS.

Lưu ý rằng việc sử dụng các bộ lọc giả định rằng bỏ qua các khung mà không giải mã / mã hóa là không thể: bởi các bộ lọc thiết kế chỉ xử lý các khung được giải mã.

Tại FFmpeg 2.8.2 tùy chọn đầu vào mới được đưa vào -stream_loop. Trước tiên tôi thấy nó hoạt động đơn giản hơn và cho phép sao chép nội dung mà không cần chuyển mã:

ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -y output.mp4

Nhưng nó không tính toán lại PTS và tập tin đầu ra là sai. Nếu bạn thêm bộ lọc để sửa PTS (xem setpts), bạn cũng phải xóa -c copy. Chỉ các bộ lọc dòng bit mới có thể xử lý các gói được mã hóa, nhưng không có bất kỳ bộ lọc dòng bit nào để sửa PTS (xem: https://ffmpeg.org/ffmpeg-bitstream-filters.html )

Trong mọi trường hợp, ffmpeg trên pass thứ hai không thành công với lỗi:

input.mp4: Resource temporarily unavailable

Công việc đã biết đối với tôi : sử dụng bộ chứa cho tệp đầu vào không có giới hạn PTS (bộ chứa phát trực tuyến). Một trong số họ, được biết đến với tôi, là MPEG-TS. Vì vậy, bạn có thể đơn giản chuyển đổi tệp MP4 của mình sang MPEG-TS:

ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input.ts

Và sử dụng lệnh tiếp theo để soạn tập tin vô cực:

ffmpeg -re -stream_loop -1 -i input.ts -c copy -strict -2 -bsf:a aac_adtstoasc -y output.mp4

(chỉ nên sử dụng bộ lọc dòng bit nếu cần, trên các mẫu của tôi là bắt buộc)

FFmpeg> = 2.8.2 là bắt buộc trong trường hợp này.


1
Chạy lệnh đó gây ra lỗi cho tôi: "[mp4 @ 00000000053fa1a0] Không thể tìm thấy thẻ cho codec rawvideo trong luồng # 0, codec hiện không được hỗ trợ trong container". Nếu tôi thêm -vcodec h264 trước đầu vào, lỗi đó sẽ biến mất, nhưng bộ mã hóa không thoát. Cung cấp số vòng lặp khác không tạo ra rất nhiều lỗi nhưng không thoát. Các tập tin không phải là một đầu ra hợp lệ.
Gyan

1
Tài liệu cho stream_loop nói "Vòng lặp 0 có nghĩa là không có vòng lặp, vòng lặp -1 có nghĩa là vòng lặp vô hạn."
Gyan

Có vẻ như các tập tin đầu vào không chính xác. Bạn có thể cầu xin chia sẻ nó? "Vòng 0 có nghĩa là không có vòng lặp, vòng -1 có nghĩa là vòng lặp vô hạn." - dường như tôi thấy các tài liệu cũ :-)
Monah Tuk

1
Tôi quên: bộ lọc giả định chuyển mã (giải mã / mã hóa). Thiết kế bởi. Vì vậy, bạn phải loại bỏ -c copy. Trả lời cố định.
Monah Tuk

1
Rất vui được biết, nhưng đó là một hạn chế đáng kể nếu bạn có một vòng lặp lớn để tạo.
Gyan

14

Với ffmpeg 2.8.4, lệnh sau sẽ tạo output.mp4 là bản sao lặp lại của input.mp4 cho đến khi quá trình ffmpeg bị dừng:

ffmpeg -stream_loop -1 -i input.mp4 -c copy output.mp4

Lệnh này sẽ không tự chấm dứt và tệp đầu ra sẽ phát triển vô hạn.


2
Có vẻ là phương pháp nhanh nhất
josef

2
Phương pháp nhanh nhất là một cách đánh giá thấp, phương pháp này tạo ra các video nhiều giờ trong vài giây.
SleighBoy

Đây là một phương pháp thuận tiện tuyệt vời, vì không cần phải tạo một tệp với các dòng lặp lại.
Markus Zeller

-1

Hỏi: "... làm thế nào tôi có thể thay đổi dòng lệnh sau để làm điều đó? Ffmpeg -i input.mp4 -c sao chép output.mp4"?

Trả lời: Phương pháp đơn giản để tránh các vấn đề trong đó Lệnh hoạt động với phiên bản nào là 'giải pháp tầm thường':

ffmpeg -i input.mp4 -i input.mp4 -i input.mp4 -i input.mp4 -c sao chép output.mp4

Xem thêm: https://trac.ffmpeg.org/wiki/Concatenate để biết nhiều ví dụ.


2
Điều này không làm bất kỳ nối. Ít nhất một trong các phương thức concat phải được sử dụng: giao thức, bộ lọc hoặc demuxer. Trong lệnh này, ánh xạ tự động của ffmpeg sẽ chọn một video, một âm thanh và một luồng phụ đề trong số các đầu vào. Vì chúng giống hệt nhau, nó tương đương với lệnh đầu tiên của OP.
Gyan

Cảm ơn bạn đã kiểm tra Mulvya, vì nó khác với hành vi được mô tả trong Tài liệu: ffmpeg.org/ffmpeg.html#Des mô tả - Nếu có sự giống nhau trong tên Tệp bằng cách sử dụng "-i -i /tmp/test%d.mp4" ( et. al) cũng có thể.
Rob
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.