Thả mọi khung hình chẵn hoặc lẻ bằng FFmpeg?


14

Có cách nào chính xác để lấy video thô và trích xuất từ ​​video đó một video mới chỉ chứa các khung lẻ hoặc khung chẵn (theo lựa chọn) không?

Ví dụ:

Tôi có "blah.yuv" với 400 khung hình (0-399). Tôi muốn tạo "blahOdd.yuv" có chứa các khung 1-399 (1,3,5,7 ... 399) và "blahEven" có chứa các khung 0-398 (0,2,4,6 ... 398 ).

Bất kỳ ý tưởng làm thế nào để làm điều đó chỉ bằng FFmpeg?

Câu trả lời:


11

Để hoạt động chính xác, trước tiên hãy chuyển đổi video thành dòng bit RAW YUV (nếu chưa có) bằng cách:

ffmpeg -i input.mp4 -an -vcodec rawvideo -pix_fmt yuv420p rawbitstream.yuv

Bước tiếp theo: Bộ selectlọc lấy một biểu thức , trong đó nlà số khung.

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="mod(n-1\,2)" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="not(mod(n-1\,2))" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an even.yuv

Để ffmpegkhông trùng lặp các khung, bạn phải buộc một nửa tốc độ khung hình của đầu vào - vì vậy bạn đặt "2" làm đầu vào và "1" cho đầu ra. Đừng quên thay thế WxH bằng kích thước thực của clip của bạn vì dòng bit thô không có tiêu đề mang thông tin này.

Thay vì ở trên, một khả năng khác là thêm setptsbộ lọc để đặt dấu thời gian mới cho đầu ra. Nhưng hãy cẩn thận vì nó giảm khung hình không chính xác. Ở đây, 25 là tốc độ khung hình đầu ra thực tế bạn muốn:

ffmpeg -i input.mp4 -filter:v select="mod(n-1\,2)",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -i input.mp4 -filter:v select="not(mod(n-1\,2))",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an even.yuv

Tất nhiên bạn có thể chọn định dạng pixel khác (bất kỳ ffmpeg -pix_fmts). Đảm bảo rằng khi đọc tệp bạn biết kích thước pixel và định dạng pixel:

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …

Cảm ơn, Đối với các phiên bản mới của FFMPEG, nó phải là -vf thay vì -filter: v. Ngoài ra, nó phải là mod (n-1 \, 2) vì số n dường như bắt đầu từ 1 trong khi số khung hình từ 0 (nếu không thì khung đầu tiên được nhân đôi 3 lần). Nhưng vẫn còn một vấn đề, nó sao chép các khung trong khi tôi muốn loại bỏ chúng - ví dụ clip cuối cùng sẽ chỉ chứa một nửa số khung.
Đánh dấu

-vflà một bí danh của -filter:v. Tôi không thể kiểm tra nó một cách đáng tin cậy bây giờ, nhưng sẽ xem xét vấn đề này sau khi tôi quay lại máy. Có lẽ tinterlacebộ lọc có thể làm như vậy?
slhck

Tôi đã thử '-r 2 -i blah.yuv -r 1' nhưng nó cho tôi thấy một lỗi Tùy chọn khung hình không tìm thấy.
Đánh dấu

À xin lỗi .. Cào đó, cái này không hoạt động (nữa?) Và chỉ dành cho hình ảnh.
slhck

1
@AnmolSinghJaggi Không, điều này chỉ làm giảm các khung hình, nhưng tôi không chắc chắn rằng nó có tính quyết định như vậy (nghĩa là giảm mọi khung hình lẻ). Nó sẽ dựa trên mã thời gian, có thể không chính xác.
slhck

2

Nếu ffmpeg của bạn được xây dựng với cờ AviSynth, thì tôi tin rằng bạn có thể vượt qua một .avstệp.

Bạn có thể kiểm tra bằng cách chạy ffmpegvà tìm kiếm --enable-avisynthtrong dữ liệu cấu hình . --enable-avisynth

Nếu nó ở đó bạn có thể sử dụng nó như vậy : ffmpeg -i blahEven.avs blahEven.yuv.

blahEven.avsĐơn giản là ở đâu :

ffideoource ("blah.yuv"). ChọnEven ()

Đối với khung lẻ, sử dụng SelectOdd().

Để biết thêm cách sử dụng, hãy xem tài liệu ChọnEvery .


Đây là một giải pháp thay thế tuyệt vời, nhưng như tôi đã đề cập - Tôi chỉ giới hạn sử dụng ffmpeg. Lý do cho điều đó là một phần của hệ thống tự động sẽ chỉ tạo các tệp .bat, không có khả năng bổ sung AVS.
Đánh dấu

@Mark Tôi đã nghĩ rằng nếu --enable-avisynthở đó, điều đó có nghĩa là AviSynth đã được tích hợp vào ffmpeg, nhưng tôi không chắc về điều đó.
Louis
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.