iMovie (не без потерь, но лучше, чем раньше)
iMovie v10 (выпущенный спустя некоторое время после того, как вопрос был задан изначально) теперь лучше обрабатывает больше типов носителей, поэтому позволяет избежать повторного кодирования импорта для большинства содержимого H.264 (mp4, m4v, mov, AVHDC, mts, mt2s).
Тем не менее, он все равно будет перекодировать при экспорте, поэтому не может быть технически без потерь - еще одна новая функция - возможность настроить качество экспорта, которое может быть практически без потерь. Я подозреваю, что эта часть ответа может в равной степени относиться к другим «проектно-ориентированным» программам для редактирования видео (например, Premiere или Final Cut), потому что я думаю, что все они обычно перекодируются на выходе, хотя обычно очень просты в использовании для точной обрезки.
Лично я вообще думаю, что одно перекодирование не является большой проблемой, но понимаю, что вы специально просили решение без потерь, так что ...
Без потерь (но намного сложнее!)
Существуют технические ограничения в отношении того, насколько точно вы можете вырезать видео без необходимости перекодировать хотя бы его часть, и это в основном зависит от частоты i-кадра. Если каждый кадр является i-кадром, вы можете вырезать его в любом месте, но если он выполняется только каждые несколько секунд, то вы можете вырезать только без потерь в этих i-кадрах без потери контента или перекодирования (по крайней мере, части поток), поэтому он может начинаться с I-кадра.
FFmpeg
Это SO Q & A, в частности, поднимает вопрос о том, как разрезать между i-кадрами, используя ffmpeg
. Я не знаю ни одного приложения с графическим интерфейсом, чтобы сделать это, но в основном вы запускаете команду примерно так:
ffmpeg -i input.m4v -vcodec copy -acodec copy -ss 00:01:20.000 -t 00:37:50.000 output.m4v
Два указанных значения времени - это начало и продолжительность , и они могут быть указаны либо в секундах, либо hh:mm:ss.ss
, а также -acodec copy
и -vcodec copy
указывать ffmpeg не перекодировать.
Я не совсем уверен, что произойдет, если вы режете слишком рано, но я думаю, что видео практически пустое (или может быть повреждено, в зависимости от плеера), пока не встретит i-frame. Таким образом, вы, вероятно, захотите найти ближайший I-кадр до вашего разреза. Этот ответ решает эту проблему с помощью ffprobe
и awk
, хотя и немного неловко. По сути, вы используете ffprobe
для сканирования кадров и найти ближайший ключевой кадр ( flags=K
) до идеальной точки вырезания. Полный вывод для каждого кадра видео можно увидеть так:
ffprobe -select_streams v -show_frames <INPUT>
Связанный ответ предоставляет эту команду, чтобы найти ключевой кадр до определенного времени:
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
И, наконец, если вам действительно нужно разрезать что-то между двумя i-кадрами, вы можете разделить видео и снова присоединиться. Основываясь на информации из этого ответа , это должно быть что-то вроде:
ffmpeg -f concat -i list_of_videos.txt -c copy OUTPUT.mp4
Где list_of_videos.txt
находится простой текстовый файл со списком файлов, которые вы хотите объединить.
Резюме
iMovie, вероятно, достаточно хорош для большинства случаев (начиная с версии 10) и очень прост.
ffmpeg может делать это без потерь (или очень близко к без потерь), с небольшим переворотом; Уровень сложности зависит от того, насколько вы требовательны к точной начальной точке и частоте i-кадров.