Câu hỏi Cắt tệp video thành nhiều phân đoạn


Tôi hiện đang sử dụng ffmpeg để cắt các tệp video. Tôi đã tự động hóa quy trình này thông qua một tập lệnh gọi là ffmpeg_split.sh. Mặc dù điều này rất chậm nhưng hiệu quả trong việc tách video thành các cài đặt tương đương. Vấn đề duy nhất là nó có vấn đề về tốc độ khung hình. Bên dưới súp ác đề nghị một cách để làm tất cả điều này bằng cách sử dụng segment trong ffmpeg. Tôi đã thử điều này nhưng nó không cho tôi phân đoạn thời gian tương đương.

CẬP NHẬT

Mỗi evilsoup sử dụng lệnh này để phân đoạn video:

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 8 -f segment output%03d.mp4

CŨ: 

Đây là cú pháp để cắt video bằng tập lệnh: ffmpeg_split.sh -s test_vid.mp4 -o video-part%03d.mp4 -c 00:00:08

Các kết quả

my_split_script.sh

input.mp4 – Duration 00:01:20
#EXTINF:10,
Output01.mp4
#EXTINF:10,
Output02.mp4
#EXTINF:10,
Output03.mp4
#EXTINF:9,
Output04.mp4
#EXTINF:10,
Output05.mp4
#EXTINF:10,
Output06.mp4
#EXTINF:11,
Output07.mp4
#EXTINF:10,
Output08.mp4
real    0m30.517s #execution time

ffmpeg

input.mp4 – Duration 00:01:20
#EXTINF:10,
Output01.mp4
#EXTINF:10,
Output02.mp4
#EXTINF:6,
Output03.mp4
#EXTINF:10,
Output04.mp4
#EXTINF:10,
Output05.mp4
#EXTINF:7,
Output06.mp4
#EXTINF:10,
Output07.mp4
#EXTINF:9,
Output08.mp4
real    0m7.493s #executition time

4
2017-10-04 14:10


gốc


Thiếu thông tin cần thiết: Kịch bản của bạn làm gì, chính xác? Bạn có thể đăng nó ở đây không? Ngoài ra, hãy nhớ rằng ffmpeg chỉ có thể phân chia ở I-frame khi thực hiện sao chép luồng. Tuy nhiên, nếu tập lệnh của bạn mã hóa lại tệp, nó hầu như có thể phân chia ở bất kỳ đâu. - slhck
@slhck tập lệnh gốc của tôi chia tách video thành các phân đoạn tương đương. Ví dụ -c 8 sẽ chia nhỏ video thành các phân đoạn là 8 giây. Nó không tái mã hóa vì vậy đó là lý do tại sao một số phân đoạn có hình ảnh tĩnh ở cuối. Đây là một liên kết đến kịch bản tôi đang kiện: KỊCH BẢN . Làm thế nào có thể làm điều này? Có thể làm tất cả điều này mà không cần một kịch bản? - Code_Ed_Student
@Code_Ed_Student Chúng có thể có độ dài giống nhau nhưng khi bạn báo cáo có thông tin lặp lại giữa các phân đoạn. Trình phân đoạn xử lý tất cả điều này dưới mui xe cho bạn (tốt nhất có thể). Nếu bạn muốn biết nhiều hơn thì nó có thể là đáng giá để đọc trên mã hóa video chính nó. - dstob


Các câu trả lời:


Bạn có thể làm điều này trực tiếp từ ffmpeg mà không cần sử dụng tập lệnh. Về cơ bản bất cứ khi nào bạn sử dụng ffmpeg segment, nó sẽ tiếp tục và cố gắng hết sức để phân chia gần thời gian bạn đã chỉ định cho từng phân đoạn. Điều này có trụ sở tại key_frames nó sẽ tìm thấy khung chính gần nhất và cắt ở đó. Để cắt các phân đoạn chính xác, bạn sẽ cần phải mã hóa lại toàn bộ video.

ffmpeg -i input.mp4 -c:v libx264 -crf 22 -map 0 -segment_time 9 -g 9 -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*9)" -f segment output%03d.mp4

Bạn sẽ cần đọc -crf, -sc_threshold và -force_key_frames. Trong wiki cho ffmpeg.


7
2017-10-12 19:47



Những công việc này! nhưng nó chỉ mất một thời gian dài để mã hóa lại video - Code_Ed_Student
Kích thước GOP là 9 thực sự thấp, không chắc chắn nếu đó là đề xuất ở đây. - slhck
@Code_Ed_Student Nó phụ thuộc vào ứng dụng của bạn. Nếu bạn nhắm mục tiêu phát lại từ phương tiện mà bạn không mong đợi sự cố mất gói hoặc giải mã khung, hãy đi với GOP lớn hơn tối đa 10 giây (ví dụ: -g 250ở tốc độ 25 khung hình / giây). Đối với phương tiện truyền trực tuyến thích ứng (ví dụ: DASH, HLS), các phân đoạn có thể chỉ dài một giây, do đó kích thước GOP sẽ bằng FPS. Nhưng chắc chắn không có gì ít hơn FPS, bởi vì nó không hiệu quả. - slhck
Đó chỉ là số lần thứ hai khung hình trên giây mà video của bạn có. Nếu video của bạn có 25 khung hình / giây và bạn muốn có GOP trong 10 giây, bạn cần kích thước GOP là 250. @Code_Ed_Student - slhck
Vui lòng giải thích thêm về "expr: gte (t, n_forced * 9)"? - Mr.Hyde


ffmpeg thực sự có thể tự làm điều này, bằng cách sử dụng phân đoạn muxer

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 8 -f segment output%03d.mp4

Bạn chắc chắn nên đọc tài liệu và chơi xung quanh một chút để có được kết quả tốt nhất (mặc định sẽ đủ tốt cho hầu hết các mục đích, nhưng sẽ không giúp bạn tách chính xác 100%).


Nói chung, nếu bạn cần nhận thông tin như thời lượng của một tệp thì tốt hơn là nên sử dụng ffprobe, đi kèm với ffmpeg - nó in thông tin như một loạt key=value cặp, làm cho nó dễ dàng hơn để đối phó với.

ffprobe -show_format file.mp4 | grep -F duration | cut -d= -f2
## or, if you want hh:mm:ss format:
ffprobe -show_format -sexagesimal file.mp4 | grep -F duration | cut -d= -f2

... nhưng, tôi nghĩ tốt hơn nên dựa vào ffmpegtùy chọn của riêng, chứ không phải là một kịch bản lệnh shell (sẽ ít hiệu quả hơn nhiều vì nó cần gọi nhiều phiên bản ffmpeg).


6
2017-10-04 15:21



Làm cách nào để đảm bảo độ chính xác khi sử dụng ffmpeg -segment_time thay vì quá trình tập lệnh chậm hơn? - Code_Ed_Student