Twitch có một bài về điều này. Họ giải thích rằng họ quyết định sử dụng chương trình của riêng họ vì nhiều lý do; Một trong số đó là ffmpeg không cho phép bạn chạy các phiên bản x264 khác nhau trong các luồng khác nhau, mà thay vào đó dành tất cả các luồng được chỉ định cho một khung hình trong một đầu ra trước khi chuyển sang đầu ra tiếp theo.
Nếu bạn không thực hiện phát trực tuyến thời gian thực, bạn có nhiều thứ xa xỉ hơn. Cách 'chính xác' có lẽ là mã hóa ở một độ phân giải chỉ với kích thước GOP được chỉ định bằng -g, sau đó mã hóa các độ phân giải khác buộc các khung hình chính ở cùng một vị trí.
Nếu bạn muốn làm điều đó, bạn có thể sử dụng ffprobe để lấy thời gian keyframe và sau đó sử dụng tập lệnh shell hoặc ngôn ngữ lập trình thực tế để chuyển đổi nó thành lệnh ffmpeg.
Nhưng đối với hầu hết các nội dung, có rất ít sự khác biệt giữa việc có một khung hình chính cứ sau 5 giây và hai khung hình chính cứ sau 5 giây (một bắt buộc và một từ phối cảnh). Đây là về kích thước khung I trung bình so với kích thước của khung P và khung B. Nếu bạn sử dụng x264 với các cài đặt thông thường (lý do duy nhất tôi nghĩ bạn nên làm bất cứ điều gì để ảnh hưởng đến những điều này là nếu bạn đặt -qmin, như một cách kém để ngăn x264 sử dụng bitrate trên nội dung dễ dàng; điều này giới hạn tất cả các loại khung có cùng giá trị , Tôi nghĩ vậy) và nhận được kết quả như kích thước trung bình của khung hình I là 46 kB, khung hình P 24 kB, khung hình B 17 kB (thường bằng một nửa khung hình P), sau đó thêm khung hình I mỗi giây ở 30 khung hình / giây chỉ tăng 3% kích thước tập tin. Sự khác biệt giữa h264 và h263 có thể được tạo thành từ một loạt giảm 3%, nhưng một điều duy nhất không quan trọng lắm.
Trên các loại nội dung khác, kích thước khung hình sẽ khác nhau. Công bằng mà nói, đây là về sự phức tạp theo thời gian chứ không phải sự phức tạp về không gian, vì vậy nó không chỉ là nội dung dễ dàng so với nội dung cứng. Nhưng nhìn chung, các trang web phát video trực tuyến có giới hạn bitrate và nội dung có khung I tương đối lớn là nội dung dễ dàng sẽ được mã hóa với chất lượng cao cho dù có thêm bao nhiêu khung hình chính. Thật lãng phí, nhưng chất thải này thường sẽ không được chú ý. Trường hợp lãng phí nhất có lẽ là một video chỉ là một hình ảnh tĩnh kèm theo một bài hát, trong đó mỗi khung hình chính xác giống nhau.
Một điều tôi không chắc chắn là làm thế nào các khung hình chính bắt buộc tương tác với bộ giới hạn tốc độ được đặt với -maxrate và -bufsize. Tôi nghĩ ngay cả YouTube cũng gặp sự cố gần đây khi định cấu hình chính xác cài đặt bộ đệm để có chất lượng ổn định. Nếu một số trang web chỉ sử dụng cài đặt bitrate trung bình mà một số trang web có thể nhìn thấy (vì bạn có thể kiểm tra các tùy chọn của x264 trong phần tử tiêu đề / Mov? Với trình soạn thảo hex) thì mô hình bộ đệm không phải là vấn đề, nhưng nếu bạn phục vụ nội dung do người dùng tạo, tốc độ bit trung bình khuyến khích người dùng thêm màn hình đen vào cuối video.
Tùy chọn -g của Ffmpeg hoặc bất kỳ tùy chọn bộ mã hóa nào khác mà bạn sử dụng được ánh xạ tới tùy chọn dành riêng cho bộ mã hóa. Vì vậy, '-x264-params keyint = GOPSIZE' tương đương với '-g GOPSIZE'.
Một vấn đề với việc sử dụng phát hiện cảnh là nếu bạn thích khung hình chính gần số cụ thể vì bất kỳ lý do gì. Nếu bạn chỉ định khung hình chính cứ sau 5 giây và sử dụng phát hiện cảnh và có thay đổi cảnh ở mức 4,5, thì nó sẽ được phát hiện, nhưng sau đó khung hình chính tiếp theo sẽ ở mức 9,5. Nếu thời gian cứ tiếp tục tăng dần như thế này, bạn có thể kết thúc với các khung hình chính ở 42,5, 47,5, 52,5, v.v., thay vì 40, 45, 50, 55. Ngược lại, nếu có thay đổi cảnh ở 5.5, thì sẽ có một khung hình chính ở mức 5 và 5,5 sẽ là quá sớm đối với một cái khác. Ffmpeg không cho phép bạn chỉ định "tạo khung hình chính ở đây nếu không có thay đổi cảnh trong 30 khung hình tiếp theo". Một người hiểu C có thể thêm tùy chọn đó, mặc dù.
Đối với video tốc độ khung hình thay đổi, khi bạn không phát trực tiếp như Twitch, bạn sẽ có thể sử dụng các thay đổi cảnh mà không cần chuyển đổi vĩnh viễn sang tốc độ khung hình không đổi. Nếu bạn sử dụng bộ lọc 'select' trong ffmpeg và sử dụng hằng số 'cảnh' trong biểu thức, thì đầu ra gỡ lỗi (-v gỡ lỗi hoặc nhấn '+' vài lần trong khi mã hóa) hiển thị số thay đổi cảnh. Điều này có lẽ khác với và không hữu ích bằng số được sử dụng bởi x264, nhưng nó vẫn có thể hữu ích.
Sau đó, quy trình có thể là thực hiện một video thử nghiệm chỉ dành cho thay đổi khung hình chính, nhưng có thể có thể được sử dụng cho dữ liệu kiểm soát tốc độ nếu sử dụng 2-pass. (Không chắc liệu dữ liệu được tạo có hữu ích cho các độ phân giải và cài đặt khác nhau hay không; dữ liệu cây macroblock sẽ không.) Chuyển đổi nó thành video tốc độ khung hình liên tục, nhưng hãy xem lỗi này về đầu ra bị gián đoạn khi giảm một nửa tốc độ khung hình nếu bạn quyết định để sử dụng bộ lọc fps cho các mục đích khác. Chạy nó qua x264 với các cài đặt keyframe và GOP mong muốn của bạn.
Sau đó, chỉ cần sử dụng các thời gian khung hình chính này với video tốc độ khung hình biến ban đầu.
Nếu bạn cho phép hoàn toàn điên cuồng nội dung do người dùng tạo với khoảng cách 20 giây giữa các khung, thì đối với mã hóa tốc độ khung hình thay đổi, bạn có thể tách đầu ra, sử dụng bộ lọc fps, bằng cách nào đó sử dụng bộ lọc chọn (có thể xây dựng biểu thức thực sự dài mỗi thời gian khung hình chính) ... hoặc có thể bạn có thể sử dụng video thử nghiệm làm đầu vào và chỉ giải mã các khung hình chính, nếu tùy chọn ffmpeg đó hoạt động hoặc sử dụng bộ lọc chọn để chọn khung hình chính. Sau đó chia tỷ lệ thành kích thước chính xác (thậm chí còn có bộ lọc scale2ref cho điều này) và phủ lên video gốc trên đó. Sau đó, sử dụng bộ lọc xen kẽ để kết hợp các khung hình chính bắt buộc này với video gốc. Nếu điều này dẫn đến hai khung hình cách nhau 0,001 giây mà bộ lọc xen kẽ không ngăn được, thì hãy tự giải quyết vấn đề này bằng một bộ lọc chọn khác. Xử lý các giới hạn bộ đệm khung cho bộ lọc xen kẽ có thể là vấn đề chính ở đây. Tất cả đều có thể hoạt động: sử dụng một số loại bộ lọc để đệm luồng dày đặc hơn (bộ lọc fifo?); tham khảo tệp đầu vào nhiều lần để nó được giải mã nhiều lần và các khung không phải được lưu trữ; sử dụng bộ lọc 'streamelect', điều mà tôi chưa bao giờ thực hiện, vào thời điểm chính xác của các khung hình chính; cải thiện bộ lọc xen kẽ bằng cách thay đổi hành vi mặc định của nó hoặc thêm tùy chọn để xuất khung cũ nhất trong bộ đệm thay vì bỏ khung. điều mà tôi chưa bao giờ thực hiện, vào thời điểm chính xác của các khung hình chính; cải thiện bộ lọc xen kẽ bằng cách thay đổi hành vi mặc định của nó hoặc thêm tùy chọn để xuất khung cũ nhất trong bộ đệm thay vì bỏ khung. điều mà tôi chưa bao giờ thực hiện, vào thời điểm chính xác của các khung hình chính; cải thiện bộ lọc xen kẽ bằng cách thay đổi hành vi mặc định của nó hoặc thêm tùy chọn để xuất khung cũ nhất trong bộ đệm thay vì bỏ khung.