Sử dụng ffmpeg để cắt video


333

Tôi đang sử dụng ffmpeg để cắt ra một phần của một tệp lớn như thế này:

ffmpeg -i input.wmv -ss 60 -t 60 -acodec copy -vcodec copy output.wmv

Phần -sshoạt động tốt nhưng -tđược bỏ qua. Nó loại bỏ chính xác các giây được chỉ định ban đầu được chỉ định với -ssnhưng sau đó tiếp tục đi đến cuối của đầu vào với bản sao.

Có cách nào để sử dụng ffmpeg để cắt phần cuối của video mà không cần mã hóa lại không?


1
cú pháp này là chính xác.
jiggunjer

Câu trả lời:


394

Bạn có thể sử dụng -sstùy chọn để chỉ định dấu thời gian bắt đầu và -ttùy chọn để chỉ định thời lượng mã hóa. Dấu thời gian cần phải ở HH:MM:SS.xxxđịnh dạng hoặc tính bằng giây ( s.msec).

Sau đây sẽ quay 30 giây đầu tiên, và sau đó cắt mọi thứ sau 10 giây:

ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 00:00:10.0 output.wmv
ffmpeg -ss 30 -i input.wmv -c copy -t 10 output.wmv

Lưu ý rằng đó -tlà một tùy chọn đầu ra và luôn cần được chỉ định sau -i .

Một số lời khuyên:

  • Đối với các phiên bản ffmpeg cũ hơn, nếu bạn sử dụng -sssau -i, bạn sẽ tìm kiếm chính xác hơn với chi phí thực hiện chậm hơn hoàn toàn. Xem thêm: Tìm kiếm với FFmpeg
  • Bạn có thể sử dụng -tothay vì -tchỉ định dấu thời gian mà bạn muốn cắt. Vì vậy, thay vì -i <input> -ss 30 -t 10bạn cũng có thể làm -i <input> -ss 30 -to 40để đạt được điều tương tự.

  • Nếu ffmpeg của bạn không hỗ trợ -c, hoặc -to, nó có thể rất lỗi thời. Tự biên dịch phiên bản mới hoặc tải xuống bản dựng tĩnh từ trang chủ của họ. Nó thực sự không phức tạp.


1
@Mondain Trên thực tế, bạn có được độ chính xác cao hơn khi đặt -ss sau. Và slhck đề cập đến điều này ở đây blog.superuser.com/2012/02/24/ cũng trong tài liệu ffmpeg cho -ss nó đề cập đến một sự khác biệt giữa đặt nó trước hoặc sau.
barlop

5
+1 Tôi đến đây để tìm hiểu làm thế nào để bỏ qua mọi thứ sau 35 giây đầu tiên, cảm ơn:ffmpeg -i input.wmv -c copy -t 35 output.wmv
karlphillip

2
Điều này không làm việc cho tôi (mp4). Nó chỉ tạo ra một màn hình đen 5 giây:frame= 150 fps=0.0 q=-1.0 Lsize= 264kB time=00:00:09.97 bitrate= 216.6kbits/s
thợ đồng hồ

2
Điều này tạo ra màn hình đen 3-4 giây vào đầu video clip của tôi. Sửa đổi của Chris với bỏ qua -c copymàn hình đen ban đầu, xem câu trả lời của anh ấy để biết chi tiết.
joelostblom

4
Bạn viết "Sau đây sẽ quay 30 giây đầu tiên, và sau đó cắt mọi thứ chỉ sau 10 giây:" <- Điều đó có nghĩa là gì? Theo clip bạn có nghĩa là bao gồm? Clip cos có thể có nghĩa là clip ra. Giả sử bạn có nghĩa là bao gồm. Bạn có nghĩa là Bắt đầu từ 30 giây và chỉ bao gồm 10 giây từ đó? Nếu vậy thì tôi đề nghị bạn viết rằng nó sẽ rõ ràng hơn nhiều.
barlop

94

Như những người khác đã đề cập, đặt -sstrước (nhanh hơn nhiều) hoặc sau (chính xác hơn) sẽ -itạo ra sự khác biệt lớn. Phần "Tìm kiếm nhanh và chính xác" trên trang tìm kiếm ffmpeg cho bạn biết làm thế nào để có được cả hai, và tôi đã sử dụng nó, và nó tạo ra sự khác biệt lớn. Về cơ bản bạn đặt -sstrước VÀ sau -i, chỉ cần đảm bảo để đủ thời gian trước khi bạn muốn bắt đầu cắt để có khung chính khác. Ví dụ: Nếu bạn muốn tạo một clip dài 1 phút, từ 9 phút0 đến 10 phút 0 giây trong Video.mp4, bạn có thể thực hiện nhanh chóng và chính xác bằng cách sử dụng:

ffmpeg -ss 00:08:00 -i Video.mp4 -ss 00:01:00 -t 00:01:00 -c copy VideoClip.mp4

Cái đầu tiên -sstìm kiếm nhanh đến (khoảng) 8 phút0 giây, và sau đó lần thứ hai -sstìm kiếm chính xác đến 9 phút0 giây và -t 00:01:00lấy ra một clip 1 phút0 giây.

Cũng lưu ý điểm quan trọng này từ trang đó: "Nếu bạn sử dụng -sscùng -c:v copy, dòng bit kết quả có thể sẽ bị biến dạng, không thể phát hoặc không đồng bộ với luồng âm thanh, vì ffmpeg buộc phải chỉ sử dụng / tách trên các khung hình i. "

Điều này có nghĩa là bạn cần mã hóa lại video, ngay cả khi bạn chỉ muốn sao chép nó, hoặc có nguy cơ bị giật và không đồng bộ. -c copyTrước tiên, bạn có thể thử , nhưng nếu video bị mất, bạn cần phải thực hiện lại.


cảnh báo tương tự áp dụng -c:a copycho cách tìm kiếm này.
jiggunjer

1
Câu trả lời tốt nhất, cách này làm việc tốt nhất cho tôi.
Ondra Žižka

3
Có vẻ như "-ss" hiện nhanh và chính xác trong ffmpeg 2.1+ mà không chỉ định hai lần. trac.ffmpeg.org/wiki/Seeking
Conrad Meyer

25

Tôi thấy rằng -sskết hợp với -c copykết quả trong một nửa giây khi bắt đầu.

Để tránh điều đó, bạn phải loại bỏ -c copy(mà phải thừa nhận sẽ thực hiện chuyển mã).


4
Có một câu trả lời khác liên quan đến độ chính xác. Mã hóa lại với tùy chọn mặc định thường KHÔNG phải là những gì bạn muốn làm!
Tomasz Gandor

Điểm tốt @TomaszGandor
Chris

1
Tôi hoàn toàn không hiểu câu trả lời của @ TomaszGandor, nhưng đã -c copysửa nó.
Iulian Onofrei

14

MANUALLY

Mở tệp trong trình phát đa phương tiện sẽ tăng khung hình trước và phát tệp AVISynth với dữ liệu như:

DirectShowSource(("C:\Downloads\Video\Do you want him.flv"), Pixel_Type="yuy2").Crop(0,0,-0,-0)
Subtitle("C:\Downloads\Video\Do you want him.flv", font="Arial", size=24, text_color=$ff0000, align=3)
ShowFrameNumber(scroll=true, x=336, y=27, font="Arial", size=24, text_color=$ff0000)
ShowTime(x=398, y=44, font="Arial", size=24, text_color=$ff0000)

Sau đó cắt với định dạng thời gian CHÍNH XÁC:

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:05.240 -to 00:00:08.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him1.flv"

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:10.240 -to 00:00:14.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him2.flv"

Bây giờ tạo một tệp txt với các tệp video có nội dung như:

file 'C:\Downloads\Video\Do you want him1.flv'
file 'C:\Downloads\Video\Do you want him2.flv'

Chạy ffmpeg:

ffmpeg -f concat -i FileList.txt -c copy "Path\NewName_joined.flv"

9

Đối với tôi -ttùy chọn không hoạt động, nhưng -vframeslàm việc. Tôi thích sử dụng hơn #frames, vì tôi muốn cắt tại I-Frames và tôi đã tìm ra GOP cho video bằng cách sử dụng ffprobe.

Dòng lệnh làm việc cho tôi là:

ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv

Nhân tiện, đặt -ssở phía trước -itạo ra một sự khác biệt lớn trong thời gian thực hiện.


1
Trên thực tế -vframes(hoặc -frames:v) nên đến sau -ivì đó là một tùy chọn đầu ra.
slhck

5

Như với user225366, tùy chọn -t không hoạt động đối với các video ngắn, nhưng đối với các video dài hơn. Đối với các video ngắn, có vẻ như -frames: v là tốt hơn. Đây là những gì làm việc cho tôi.

ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy output.mp4

-acodec sao chép cần phải thêm nếu video có âm thanh, như các câu trả lời khác hiển thị.


0

Tôi thấy không có nhiều người đề cập đến điều này (tôi không phải là chuyên gia nên có thể có một nhược điểm), nhưng nếu tệp của bạn có các luồng khác như phụ đề và siêu dữ liệu khác như chương, v.v., có thể cắt / cắt và giữ tất cả các luồng với theo lệnh

ffmpeg -to 60 -i input.mkv -map 0 -c copy output.mkv

Với -map 0bạn lấy tất cả các luồng trong tệp, và với -c copybạn sao chép tất cả chúng như chúng là.
Sử dụng -tobỏ qua bắt đầu thông qua -sssẽ cắt video đầu vào từ đầu đến 60.

Việc thay đổi mapcũng hữu ích nếu bạn chỉ muốn lưu các luồng cụ thể (có thể bạn không cần tất cả các nguồn âm thanh trong tệp hoặc chỉ một số phụ đề).

Tôi sử dụng điều này khi tôi cần chia các tệp MKV lớn không thể lưu trữ trong bộ lưu trữ FAT32.

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.