Вопрос или проблема
Хочу получить FFmpeg 7.1 (macOS), чтобы сжать файлы MP4, созданные GoPro, при этом копируя метаданные потоков, особенно данные GPS. Это работает для вывода MOV, но не для вывода MP4. Я хотел бы сохранить его в формате MP4 для максимальной совместимости. Похоже, что программа не может копировать поток 2, поток tmcd.
Вот команда, которая работает:
ffmpeg -i GX-0195-02.MP4 -copy_unknown -map 0 -map_metadata 0 -c:v hevc_videotoolbox -q:v 45 -vtag hvc1 GX-0195-02-htb45.mov
Если я просто изменю название выходного файла с .mov
на .mp4
, я получаю следующую ошибку:
[mp4 @ 0x13af06a70] Вы запросили копирование оригинальной дорожки временных кодов, поэтому метаданные временного кода теперь игнорируются
[mp4 @ 0x13af06a70] Не удалось найти тег для кодека none в потоке #2, кодек в данный момент не поддерживается в контейнере
[out#0/mp4 @ 0x600000194180] Не удалось записать заголовок (неправильные параметры кодека ?): Неверный аргумент
[vf#0:0 @ 0x600000594140] Ошибка при отправке кадров потребителям: Неверный аргумент
[vf#0:0 @ 0x600000594140] Задача завершилась с кодом ошибки: -22 (Неверный аргумент)
[vf#0:0 @ 0x600000594140] Завершение потока с кодом возврата -22 (Неверный аргумент)
[out#0/mp4 @ 0x600000194180] Ничего не было записано в выходной файл, так как как минимум один из его потоков не получил пакетов.
Вот информация о входном файле:
% ffprobe GX-0195-02.MP4 11:05:32
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'GX-0195-02.MP4':
Metadata:
major_brand : mp41
minor_version : 538120216
compatible_brands: mp41
creation_time : 2024-08-05T16:21:07.000000Z
firmware : H22.01.02.30.70
Duration: 00:03:31.01, start: 0.000000, bitrate: 45108 kb/s
Stream #0:0[0x1](eng): Видео: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 44844 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (по умолчанию)
Metadata:
creation_time : 2024-08-05T16:21:07.000000Z
handler_name : GoPro H.265
vendor_id : [0][0][0][0]
encoder : GoPro H.265 encoder
timecode : 10:00:05:09
Stream #0:1[0x2](eng): Аудио: aac (LC) (mp4a / 0x6134706D), 48000 Hz, стерео, fltp, 189 kb/s (по умолчанию)
Metadata:
creation_time : 2024-08-05T16:21:07.000000Z
handler_name : GoPro AAC
vendor_id : [0][0][0][0]
timecode : 10:00:05:09
Stream #0:2[0x3](eng): Данные: none (tmcd / 0x64636D74) (по умолчанию)
Metadata:
creation_time : 2024-08-05T16:21:07.000000Z
handler_name : GoPro TCD
timecode : 10:00:05:09
Stream #0:3[0x4](eng): Данные: bin_data (gpmd / 0x646D7067), 57 kb/s (по умолчанию)
Metadata:
creation_time : 2024-08-05T16:21:07.000000Z
handler_name : GoPro MET
Unsupported codec with id 0 for input stream 2
Unsupported codec with id 98314 for input stream 3`
Пробовал различные варианты с -tag:2
на основе других поисков, но я не совсем понимаю, что это на самом деле делает, поэтому не полностью понимаю синтаксис или последствия.
Я нашел способ заставить это работать. Изменив командную строку, указав все потоки, кроме потока tmcd
.
ffmpeg -i GX-0195-02.MP4 -copy_unknown -map 0:0 -map 0:1 -map 0:3 -map_metadata 0 -c:v hevc_videotoolbox -q:v 45 -vtag hvc1 GX-0195-02-htb45.mp4
Создает новый MP4 с сжатым видео и аудио, но другой поток (поток gpmd
) также скопирован. “Поток” tcmd
реконструируется выводом MP4, по всей видимости, хотя он и переставлен по сравнению с оригинальным порядком потоков.
Я не могу объяснить, почему -map 0
сработал для файлов выводов .mov
, но не для файлов выводов .mp4
.
Я бы предпочел, чтобы мне не нужно было знать полную структуру потоков этих файлов заранее. Кажется, что флаг -copy_unknown
должен работать, копируя все потоки без каких-либо дополнительных флагов -map
. Но на данный момент это способ, которым я заставил это работать.
Ответ или решение
FFmpeg — мощный инструмент для обработки мультимедиа, и его использование для работы с файлами, созданными GoPro, часто вызывает множество вопросов, особенно когда дело доходит до копирования и обработки потоков данных. В данном случае мы столкнулись с проблемой копирования метаданных, таких как GPS-данные, из файла MP4, созданного GoPro, с использованием FFmpeg версии 7.1 на macOS.
Проблема
Вы пытаетесь использовать следующую команду для конвертации ваших файлов:
ffmpeg -i GX-0195-02.MP4 -copy_unknown -map 0 -map_metadata 0 -c:v hevc_videotoolbox -q:v 45 -vtag hvc1 GX-0195-02-htb45.mov
Эта команда успешно работает для формата MOV, однако, при изменении расширения на MP4 возникает ошибка:
[mp4 @ ...] Could not find tag for codec none in stream #2, codec not currently supported in container
Эта ошибка указывает на проблему с потоком данных, который не поддерживается контейнером MP4. В вашем случае это поток времени (tmcd), который не имеет поддерживаемого кодека для MP4.
Причины возникновения проблемы
-
Проблема с кодеками: В файле входит несколько потоков, и не все из них поддерживаются форматом MP4. Например, поток с идентификатором 2 (
tmcd
), усыпанный недоступным кодеком, приводит к сбою при попытке его копирования в новом файле MP4. -
Кодек контейнера: Контейнер MP4 имеет строгие требования к кодекам, и если в нем имеется неподдерживаемый поток, это приводит к ошибке. Формат MOV более гибок и поддерживает широкий спектр кодеков, в то время как MP4 требует, чтобы все потоки имели четкие определения.
Решение
Как вы заметили, вы нашли обходной путь, указав конкретные потоки в команде:
ffmpeg -i GX-0195-02.MP4 -copy_unknown -map 0:0 -map 0:1 -map 0:3 -map_metadata 0 -c:v hevc_videotoolbox -q:v 45 -vtag hvc1 GX-0195-02-htb45.mp4
Выборочное копирование потоков, исключая проблемный tmcd
, позволяет создать файл MP4 без ошибок.
Объяснение поведения флагов
Ключ -copy_unknown
предназначен для копирования потоков данных, кодеки которых не известны. Однако в вашем случае он не смог автоматически поддержать поток tmcd
, что и стало причиной ошибки. Когда вы используете -map 0
, FFmpeg пытается скопировать все потоки, в том числе и неподдерживаемые, что приводит к сбою при создании MP4.
Заключение
Если вы стремитесь сохранить максимальную совместимость и избежать мыслей о структуре файлов, полезно заранее изучить входные файлы, чтобы понимать, какие потоки могут быть проблемными. В будущем, вы могли бы заполнить этот недостаток автоматизации, используя скрипты для анализа структуры ваших видеофайлов, что позволит заранее исключать неподходящие потоки.
Тем не менее, описанный вами метод — выборочное копирование потоков — является рабочим решением, позволяющим вам извлечь компрессионные преимущества при сохранении важной метаданных, как GPS, при конвертации в формате MP4.