Cắt chính xác các tập tin video từ dòng lệnh


22

Tôi gặp sự cố khi tìm ứng dụng cli có thể lấy tệp video (tốt nhất là avi, mkv và mp4) và cắt các clip rất ngắn (2-6 giây) với độ chính xác về thời gian. Tôi đã thử ffmpeg , mencoder , avidemuxmp4box nhưng tất cả đều cắt trên các khung hình chính tạo ra hơn 6 clip thứ hai. Có một công cụ sẽ mã hóa lại tập tin đầu vào và cắt thời gian chính xác hoặc cắt không chính xác, mã hóa lại, và sau đó cắt chính xác?


Bạn có thể sẽ phải mã hóa lại trước khi cắt để làm cho đúng. Bạn có thể có thể tăng tốc mọi thứ bằng cách trước tiên cắt bỏ các khung hình chính xung quanh và chỉ mã hóa lại các đoạn mã.
Nifle

4
Chính xác thì lệnh FFmpeg nào bạn đã thử? Tôi tin rằng nếu bạn giải mã video trước (nghĩa là đặt -sstham số sau -i ), nó sẽ chính xác hơn.
slhck

1
Thủ thuật FFmpeg đã hoạt động! Tôi đã không nhận ra thứ tự quan trọng rất nhiều. Điều này có giống với bất kỳ công cụ nào khác không?
curmil

Câu trả lời:


23

Cắt video với ffmpeg

Bạn có thể cắt chính xác video với FFmpeg. Kể từ phiên bản 2.5, nó rất dễ dàng. Ví dụ, điều này sẽ cắt giảm 10 giây, bắt đầu từ 0 phút, 3 giây và 123 mili giây.

ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4

Vị trí và thời gian có thể tính bằng giây hoặc ở hh:mm:ss[.xxx]dạng.

Lưu ý rằng trong các ví dụ này, video sẽ được mã hóa lại bằng bộ mã hóa x264 ; âm thanh được sao chép.

Bạn cũng có thể sử dụng -tothay vì -tchỉ định điểm kết thúc thay vì thời lượng. Tuy nhiên, trong trường hợp này -tolà tương đương với -t, vì bằng cách đặt -ssphía trước -i, ffmpeg trước tiên sẽ tìm đến điểm đó và sau đó bắt đầu xuất ra.

Xem thêm mục Tìm kiếm wiki.


Cắt chính xác cho các ffmpegphiên bản cũ

Nếu bạn có phiên bản cũ hơn của ffmpeg, thì để tìm kiếm chính xác, bạn cần đặt phần -sssau -i, điều này làm cho quá trình mã hóa chậm hơn một chút, vì toàn bộ video phải được giải mã trước:

ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4

Ở đây, -to-thành xử khác nhau. -t 10sẽ tạo một clip dài mười giây, trong khi đó -to 10sẽ tạo một clip dài bảy giây.


Thay vì -c:v libx264 -c:a libfaactôi nghĩ rằng chúng ta có thể sử dụng thông báo -acodec copy -vcodec copycho ffmpeg chỉ để phát hiện và sử dụng cùng một codec với tệp gốc. Bất cứ ai có thể xác nhận?
Baodad

2
@Baodad Bạn có thể, nhưng điều này sẽ không cắt chính xác . Khi sao chép dòng bit video / âm thanh, ffmpeg cần bắt đầu tại một khung hình chính, có thể chỉ được đặt ở mỗi giây hoặc thậm chí cách xa nhau.
slhck

Làm cách nào để khắc phục lỗi "Bộ mã hóa không xác định 'libfaac'"?
Doug

@Doug Chọn một bộ mã hóa khác, ví dụ -c:a aac -strict experimental. Đó là giải pháp đơn giản nhất.
slhck

1

Công cụ dòng lệnh Linux duy nhất tôi tìm thấy cho đến nay, có thể cắt ở khung chính xác (hoặc, với độ chính xác của khung), là melt( sudo apt-get install melt).

Giả sử bạn có inputvid.mp4- trước tiên hãy kiểm tra cài đặt mã hóa của nó bằng cách nói ffmpeg(ở đây, tôi chỉ nói rằng tôi muốn mã hóa lại -f mp4, nhưng vì tệp /dev/nullbị loại bỏ, tôi chuyển hướng stderr để tôi có thể grep qua nó - ghi chú ở giữa , lệnh sẽ nhắc và bạn nên trả lời ybằng ENTER, vì vậy quá trình tiến hành và bỏ thông tin hữu ích, đây là với ffmpeg 3.3.3 trên Ubuntu 14):

ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Ok, vì vậy chúng ta có thể thấy các ffmpeglựa chọn libx264aacbộ mã hóa cho video này; sau đó chúng ta có thể nhập cái này vào cho melt:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264

.... và meltsẽ cắt với phần giữa khung 7235 và 7349 thành một tệp mới , cut.mp4. Sau đó, để kiểm tra xem cut.mp4các vòng lặp có chính xác không, sử dụng meltlại để phát lại hai lần - và phát nó vào cửa sổ SDL:

melt cut.mp4 cut.mp4 -consumer sdl

... và đây là những gì ffmpegnhìn thấy cho tập tin này:

ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'    encoder         : Lavf54.20.4
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Các cài đặt mã hóa video cut.mp4dường như giống hệt với inputvid.mp4ngoại trừ bitrate video đã thay đổi từ 389 kb / s thành 526 kb / s, và các cài đặt mã hóa âm thanh cũng gần giống nhau, ngoại trừ tốc độ lấy mẫu thay đổi từ 44100 thành 48000 Hz; mặc dù điều đó có thể được quy định với:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k

... tuy nhiên, ngay cả với điều này, tốc độ bit video cuối cùng đối với tôi kết thúc là 336 kb / s. Tuy nhiên, vòng lặp cắt tốt (và bao gồm âm thanh) khi được phát trong một vòng lặp, vì vậy tôi đoán đây thực sự là khung hình chính xác ...


1
meltđang mã hóa lại video và nó sử dụng các thư viện FFmpeg bên dưới. Nếu bạn cho phép mã hóa lại, ffmpeg có thể tạo ra cùng một đầu ra.
Gyan

Cảm ơn @Gyan - không biết điều đó (đặc biệt là meltsử dụng các thư viện FFmpeg), rất tốt để biết!
sdaau

tan có vẻ dễ sử dụng hơn ffmpeg, tất cả những gì chúng ta cần là một cách để chỉ định thời gian, đặc biệt là thời gian ở dạng hr, min, sec hoặc hr, min, sec, ms, chuyển đổi chúng sang khung bên phải.
barlop

0

Giống như Baodad đã nói trong các bình luận (tôi đăng vì không dễ tìm nếu bạn đọc nhanh), cách tiếp cận tốt hơn là tự động phát hiện các bộ mã hóa âm thanh / video bằng ffmpeg, vì vậy:

ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4 
  • bắt đầu @ 00: 05: 17,18
  • đầu vào = in.mp4
  • dừng @ 00: 06: 29.10
  • đầu ra = out.mp4

2
Điều này không mã hóa lại và không cung cấp độ chính xác của khung.
Andrea Lazzarotto
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.