1. Описание проблемы
1.1 Предыстория
ранее на основеffmpeg
Выполняйте вторичную разработку, выполняйте общие функции обработки видео и используйтеffmpeg
Командная строка делает свое дело. На этой основе также строится система доступа и планирования транскодирования для предоставления внешних услуг. Есть функция, которая должна быть такой: быстро обрезать суб-видео определенного временного диапазона из указанного видео, два требования: 1. Чтобы было быстро, не так долго, как перекодирование 2. Если быть точным, вы можно указать при редактировании, с какой секунды начинать и с какой секунды заканчивать.
1.2 Трудности
использоватьffmpeg
Легко отредактировать небольшое видео из длинного видео. например, командаffmpeg -i input.mp4 -ss 00:10:03 -t 00:03:00 -vcodec copy -acodec copy output.mp4
изinput.mp4
На 10-й минуте и 3-й секунде 3-минутное видео редактируется и сохраняется какoutput.mp4
документ. параметр-vcodec copy -acodec copy
Это прямое копирование аудио- и видеопотока исходного видео без кодирования и декодирования. Хотя описанный выше метод удобен, у него есть фатальный недостаток:Экран сначала зависает (но звук всегда нормальный), а через несколько секунд экран нормально прокручивается. Видео ниже является примером.
2. Анализ причин
Причина этого в том, что время начала клипа попадает в видеоGOP
среднее положение вместо первогоI
Рамка. Студенты, которые немного разбираются в кодировании видео, должны были это слышать.I
,B
,P
Рамка. Проще говоря,I
Кадр – это законченное изображение,P
кадр в соответствии сI帧
делать дифференциальное кодирование,B
каркас по переду и спинкеI
,P
,B
Кадры кодируются по-разному. то естьI
кадр имеет полное содержимое, в то время какP
а такжеB
рамки нет, так что если отсутствуетI
кадр, тоP
а такжеB
Кадры не могут нормально декодироваться. Вообще говоря,GOP
Первый кадр внутриI
кадр, а затем несколькоP
а такжеB
Рамка. ОдинGOP
Возможно до 10 секунд. На фото ниже реальное видеоI
,B
,P
Инфографика кадра, красное представлениеI
кадр, вы можете видеть дваI
Кадры далеко друг от друга (на самом деле 10 секунд).
Из вышеприведенного анализа видно, что время начала клипа, скорее всего, не совпадает сI
рамка из-за отсутствияI
кадр сделает следующееP
а такжеB
Кадры не могут быть декодированы, что приводит к зависанию изображения. Приведенный выше анализ основан на прямом копировании видеоконтента без кодирования и декодирования.Если вы рассмотрите декодирование изображений одно за другим, а затем кодируете изображения, соответствующие требованиям времени, время редактирования может быть очень точным. Но это слишком трудоемко: для выполнения операций кодирования и декодирования требуется много ресурсов процессора.
3. Решения
Решение все же есть: к первому, соответствующему требованиям времениGOP
кодек и послеGOP
Контент копируется непосредственно в целевое видео. Давай, первыйGOP
кадров перераспределяются из-за перекодированияI
кадр, чтобы его можно было воспроизвести, во-вторых, после этогоGOP
Контент копируется напрямую, поэтому он в основном не потребляет ЦП, а производительность увеличивается. Как показано ниже:
Конечно, в нем еще есть какие-то ямы, и ямы будут засыпаны ниже.
3.1 Сращивание
Исходное видео может удивить: я закодировал код своими способностями, почему вы можете декодировать его напрямую, скопировав? В общем декодирование зависит отSPS
а такжеPPS
, в то время как исходное видео и целевое видеоSPS
а такжеPPS
будет другим, поэтому прямая копия не будет правильно декодирована. заmp4
документ,SPS
а такжеPPS
Обычно ставится в заголовке файла. Файл может иметь только один заголовок, поэтому он не может хранить два разных заголовка.SPS
а такжеPPS
. Чтобы правильно декодировать целевое видео, исходное видео должно бытьSPS
а такжеPPS
. Если вы не можете поместить заголовок файла, куда вы можете его поместить? Можно ли его разместить перед копируемой рамкой? Как это сказать? Я был беспомощен и мне не с чего было начать, пока однажды я вдруг не вспомнил, что для того, чтобы заполнить дыру, я выследилh264_mp4toannexb
реализации, его роль заключается вSPS
а такжеPPS
Скопируйте в кадр (точнее, он должен бытьAVPacket
) перед ним. Приходить! Просмотрите конкретную реализацию h264_mp4toannexb: во всехAVPacket
увеличение спереди0x000001
или0x00000001
,существуетI
Вставить перед рамкойSPS
а такжеPPS
. то есть черезh264_mp4toexannb
для расшифровки нужногоSPS
а такжеPPS
Вставить правильно в видео.h264_mp4toannexb
Он также относительно прост в использовании, код выглядит следующим образом:
AVBSFContext* initBSF(const std::string &filter_name, const AVCodecParameters *codec_par, AVRational tb)
{
const AVBitStreamFilter *filter = av_bsf_get_by_name(m_filter_name.c_str());
AVBSFContext *bsf_ctx = nullptr;
av_bsf_alloc(filter, &bsf_ctx);
avcodec_parameters_copy(bsf_ctx->par_in, codec_par);
bsf_ctx->time_base_in = tb;
av_bsf_init(bsf_ctx);
return bsf_ctx;
}
AVPacket* feedPacket(AVBSFContext *bsf_ctx, AVPacket &packet)
{
av_bsf_send_packet(bsf_ctx, packet);
AVPacket *dst_packet = av_packet_alloc();
av_bsf_receive_packet(bsf_ctx, dst_packet);
return dst_packet;
}
void test()
{
AVBSFContext *bsf_ctx = initBSF("h264_mp4toannexb", video_stream->codecpar, video_stream->time_base);
AVPacket *packet = readVideoPacket();
AVPacket *dst_packet = feedPacket(bsf_ctx, packet);
}
Примечание: сначала кодекGOP
и оригинальное продолжение видеоGOP
Следует внимательно обращаться с временными метками во время сращивания, иначе при воспроизведении видео может возникнуть дрожание.
3.2 Хуапин
Думаете, все кончено? нет! ! Вы обнаружите, что некоторые видео будут выглядеть размытыми в последнюю секунду. . . .
Нетрудно догадаться, в чем причина Хуапина: последний кадрB
Рамка. Так как не во всех клипах есть последний кадр видеоB
кадр, так что Huaping не нужно. знаю даB
вызывается кадр, решение очевидно: убедитесь, что последний кадрP
Рамка. Даже если это немного с течением времени (аудиопоток должен немного следовать за видеопотоком). Однако, поскольку невозможно напрямуюAVPacket
Определить, является ли кадрP
кадр, так что последнийGOP
также должен быть декодирован (кодирование не требуется). Запишите первый после превышения диапазона времениP
обрамленныйpts
, скопируй позжеGOP
, скопируйте сюдаpts
может остановиться.
4. Резюме
Сначала я думал, что проблема трудно решить, в конце концовffmpeg
Есть проблема с обрезанием командной строки. Тем не менее, это всегда одно и то же, начиная с причины проблемы, шаг за шагом ища решение и разбивая проблемы, встречающиеся на пути, одну за другой. Помните, что вам нужно понять принцип, чтобы решить проблему.