Как эффективно установить продолжительность первого кадра фильма 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 просто нужно заменить одно целое число и вообще не иметь дело с де- или кодированием. Можно ли это сделать и как?
Я уже разместил решение ffmpeg в теме вопроса.
LWChris 5 лет назад
0
1 ответ на вопрос
0
Gyan
Поскольку, исходя из вашего рабочего решения, похоже, что вы согласны с согласованием вывода с постоянной частотой кадров, я предложу этот более быстрый двухшаговый метод. Нет перекодировки.
Это правильно, что я не против установить видео на фиксированный 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