iMovie (không mất mát, nhưng tốt hơn trước)
iMovie v10 (được phát hành một thời gian sau khi câu hỏi ban đầu được hỏi) bây giờ xử lý tốt hơn các loại phương tiện khác, do đó, tránh việc mã hóa nhập lại cho hầu hết nội dung H.264 (mp4, m4v, Mov, AVHDC, mts, mt2s).
Tuy nhiên, nó vẫn sẽ được mã hóa lại khi xuất để không bị tổn thất về mặt kỹ thuật, tuy nhiên, một tính năng mới khác là khả năng tùy chỉnh chất lượng xuất, có thể gần hơn với tổn thất. Tôi nghi ngờ phần này của câu trả lời có thể áp dụng tương tự cho phần mềm chỉnh sửa video 'điều khiển dự án' khác (ví dụ Premiere hoặc Final Cut) bởi vì tôi nghĩ rằng tất cả chúng thường mã hóa lại đầu ra, mặc dù thường rất dễ sử dụng để cắt tỉa chính xác.
Cá nhân, tôi thường nghĩ rằng một lần mã hóa lại không phải là một vấn đề lớn, nhưng hiểu rằng bạn đã đặc biệt yêu cầu một giải pháp không mất mát, vì vậy ...
Mất mát (nhưng cách phức tạp hơn!)
Có những hạn chế về mặt kỹ thuật là bạn có thể cắt video chính xác như thế nào mà không phải mã hóa lại ít nhất một phần của video và về cơ bản nó phụ thuộc vào tần số khung hình i. Nếu mọi khung hình là một khung hình i, bạn có thể cắt ở bất cứ đâu, nhưng nếu chúng chỉ mất vài giây, thì bạn chỉ có thể cắt không mất mát tại các khung hình đó mà không mất nội dung hoặc phải mã hóa lại (ít nhất là một phần của luồng) để nó có thể bắt đầu với khung hình i.
ffmpeg
Câu hỏi và trả lời SO này đặc biệt đặt ra câu hỏi làm thế nào để cắt giữa các khung hình i bằng cách sử dụng ffmpeg
. Tôi không biết bất kỳ ứng dụng GUI nào để thực hiện việc này, nhưng về cơ bản, bạn chạy một lệnh như sau:
ffmpeg -i input.m4v -vcodec copy -acodec copy -ss 00:01:20.000 -t 00:37:50.000 output.m4v
Hai lần được chỉ định là bắt đầu và thời lượng , và có thể được chỉ định là giây hoặc hh:mm:ss.ss
, -acodec copy
và-vcodec copy
nói với ffmpeg không được mã hóa lại.
Tôi không chắc chắn điều gì sẽ xảy ra nếu bạn cắt quá sớm, nhưng tôi nghĩ rằng video về cơ bản là trống (hoặc có thể bị hỏng, tùy thuộc vào trình phát) cho đến khi gặp khung hình i. Vì vậy, có lẽ bạn sẽ muốn tìm khung hình i gần nhất trước khi cắt. Câu trả lời này giải quyết vấn đề đó bằng cách sử dụng ffprobe
và awk
, mặc dù có một chút lúng túng. Về cơ bản, bạn sử dụng ffprobe
để quét các khung và tìm khung hình chính ( flags=K
) gần nhất trước điểm cắt lý tưởng của bạn. Có thể xem toàn bộ đầu ra cho từng khung hình của video như sau:
ffprobe -select_streams v -show_frames <INPUT>
Câu trả lời được liên kết cung cấp lệnh này để tìm một khung hình chính trước một thời gian cụ thể:
ffprobe -select_streams v -show_frames -v quiet INPUT.mp4 |
awk -F= '
/pict_type=/ { if (index($2, "I")) { i=1; } else { i=0; } }
/pkt_pts_time/ { if (i && ($2 >= 150)) print $2; }
' | head -n 1
Và cuối cùng, nếu bạn thực sự cần phải cắt ở đâu đó giữa hai khung hình i, bạn có thể chia video và tham gia lại. Dựa trên thông tin từ câu trả lời này , nó sẽ giống như:
ffmpeg -f concat -i list_of_videos.txt -c copy OUTPUT.mp4
Đâu list_of_videos.txt
là một tệp văn bản đơn giản liệt kê các tệp bạn muốn ghép.
Tóm lược
iMovie có lẽ đủ tốt cho hầu hết các trường hợp (kể từ v10), và rất dễ dàng.
ffmpeg có thể làm điều đó một cách dễ dàng (hoặc rất gần với lossless), với một chút khó khăn; mức độ khó phụ thuộc vào mức độ kén chọn của bạn về điểm bắt đầu chính xác và tần suất của khung hình i.