Как эффективно установить продолжительность первого кадра фильма mp4?

423
LWChris

У меня есть приложение с собственным кодом, которое использует образец Camera2Video от Google, опубликованный на GitHub . К сожалению, существует проблема с Android 6 и выше, которая приводит к повреждению записанного видео. Согласно отчету о проблеме на GitHub, время декодирования первого кадра является огромным по сравнению с рабочим видео.

Для моего примера файла длиной 11 с, симптомы:

  • На самом телефоне Android видео проигрыватель зависает на первом кадре. Звук воспроизводится, воспроизведение останавливается через 11 секунд. После возврата ползунка в начало видео и аудио воспроизводятся синхронно.
  • В Windows, в которой используются разные проигрыватели (Groove, WMP, VLC), видео либо вообще нет, либо оно останавливается в первом кадре. Аудио всегда хорошо. Длина видео показана как 11 с. Некоторые проигрыватели останавливаются в конце, некоторые продолжают увеличивать время воспроизведения после того, как ползунок воспроизведения на 100%.
  • В Google Chrome в Windows продолжительность видео отображается как 3,5 часа. Звук воспроизводится в течение первых 11 секунд. Видео показывает первый кадр почти все время, а затем 11 секунд после окончания воспроизведения видео.

Поведение Google Chrome лучше всего показывает, что происходит: в файле 11 с аудио и 11 с * 30 к / с = 330 кадров. Но первый кадр не 1/30 с, а около 3,5 часов.

Сначала я пытался использовать различные инструменты для восстановления видео, чтобы исправить файл mp4, но большинство из них ничего не меняли или не находили никаких проблем, которые могли бы исправить, и не работали в первую очередь.

После небольшой пробной ошибки я нашел первое рабочее решение . Я использовал FFmpeg с setptsопцией фильтра: .\ffmpeg.exe -i "broken.mp4" -vf setpts=N/FRAME_RATE/TB "fixed.mp4". После этого исправленный файл работает нормально (и намного меньше).

Проблема такого подхода заключается в том, что она занимает примерно столько времени, чтобы закончить, как длина видео, которое я хочу исправить. Но видео, которое я хочу сделать с приложением, может занять около часа в будущем.

Поэтому мне интересно, есть ли возможность отрегулировать продолжительность, для которой показан первый кадр? Теоретически, это должно означать, что ffmpeg просто нужно заменить одно целое число и вообще не иметь дело с де- или кодированием. Можно ли это сделать и как?

0
Я уже разместил решение ffmpeg в теме вопроса. LWChris 5 лет назад 0

1 ответ на вопрос

0
Gyan

Поскольку, исходя из вашего рабочего решения, похоже, что вы согласны с согласованием вывода с постоянной частотой кадров, я предложу этот более быстрый двухшаговый метод. Нет перекодировки.

Извлечь сырой поток:

ffmpeg.exe -i "broken.mp4" -c copy broken.h264 

Remux:

ffmpeg.exe -i broken.h264 -i broken.mp4 -map 0 -map 1:a -c copy new.mp4 
Это правильно, что я не против установить видео на фиксированный FPS, если оно относительно синхронизировано со звуком (<100 мс). Ваш метод работает, но вывод ffmpeg говорит: «В пакете для потока 0 не установлены метки времени. Это устарело и в будущем перестанет работать. Исправьте код, чтобы правильно установить метки времени» LWChris 5 лет назад 0
Да, мой метод основан на том, что временные метки не установлены. Это сообщение было в течение многих лет, и никто не работает над патчем, чтобы изменить это. Если мы это сделаем, я обновлю ответ. Gyan 5 лет назад 0
Хм, вывод пока не совсем правильный. Во-первых, это вращается. Я исправил это с помощью `-metadata: s: v rotate =" - 90 "`. Во-вторых, частота кадров составляет всего 25 кадров в секунду, в то время как оригинал имеет 30 кадров в секунду. Это означает, что в видео-кадре слишком много кадров, что приводит к тому, что видео со временем отстает от звука. Я пробовал `-r 30` в обоих шагах в разных местах, но, похоже, это не сработало. LWChris 5 лет назад 0
Похоже, у вас старая версия ffmpeg; более новые версии должны читать неработающую частоту кадров. В любом случае, вы можете добавить `-r 30` перед` -i broken.h264` во 2-й команде. Gyan 5 лет назад 0

Похожие вопросы