2013-05-21 7 views
2

Хорошо, поэтому, очевидно, что я знаю очень мало что касается API ffmpeg, когда я сделал оригинальное сообщение ... это совершенно потрясающе, когда вы начинаете узнавать о цифровых носителях и деталях преобразования. Прочитав еще немного и перейдя через источник ffmpeg, мне удалось получить рабочий выход от mp4 до mpegts. Концепция похожа на исполнение:Конвертировать MPEG4 в MPEGTS на Android с FFmpeg

ffmpeg -i in.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb out.ts 

Но, как я уже говорил ранее, мне нужно реализовать его с помощью FFmpeg API на C.

Таким образом, хотя я в состоянии генерировать воспроизводимый ts-файл, его видео и аудиопотоки не синхронизируются. То есть, воспроизведение их на Android-планшете воспроизводит видео очень медленно, пока звук воспроизводится с нормальной скоростью, а затем (как только поток аудио заканчивается) видео воспроизводится с нормальной скоростью до конца. Воспроизведение одного и того же сгенерированного файла .ts в VLC создает очень сжатый звук (как бы ускоренную перемотку вперед) и отлично воспроизводит видео.

Есть еще много аспектов преобразования СМИ, с которыми я не знаком. Я уверен, что некоторые из них препятствуют успешному обращению.

Вот некоторая информация (через ffprobe) о файлах: - in.mp4 - файл, созданный с помощью записи Android - MPEG4 (H.264 + AAC) - ffmpeg.ts - файл, созданный с помощью преобразования FFmpeg - MPEG2TS (H.264 + AAC) - out.ts - файл, созданный с помощью моего кода - MPEGTS (H.264 + AAC)

in.mp4

filename=in.mp4 
nb_streams=2 
format_name=mov,mp4,m4a,3gp,3g2,mj2 
format_long_name=QuickTime/MPEG-4/Motion JPEG 2000 format 
start_time=0:00:00.000000 
duration=0:00:09.961383 
size=4.730 Mibyte 
bit_rate=3.983 Mbit/s 
TAG:major_brand=isom 
TAG:minor_version=0 
TAG:compatible_brands=isom3gp4 
TAG:creation_time=2013-05-28 17:06:57 

ffmpeg.ts

filename=ffmpeg.ts 
nb_streams=2 
format_name=mpegts 
format_long_name=MPEG-2 transport stream format 
start_time=0:00:01.400000 
duration=0:00:09.741267 
size=5.132 Mibyte 
bit_rate=4.419 Mbit/s 

out.ts

filename=out.ts 
nb_streams=2 
format_name=mpegts 
format_long_name=MPEG-2 transport stream format 
start_time=0:00:00.000000 
duration=0:00:09.741267 
size=5.166 Mibyte 
bit_rate=4.449 Mbit/s 

Во-первых, я не смог повлиять start_time моего выходного файла. Далее, при рассмотрении -show_packets выход зонда, я увидел следующее:

ffmpeg.ts

[PACKET] 
codec_type=video 
stream_index=0 
pts=N/A 
pts_time=N/A 
dts=N/A 
dts_time=N/A 
duration=0 
duration_time=0:00:00.000000 
size=20.506 Kibyte 
pos=564 
flags=K 
[/PACKET] 
[PACKET] 
codec_type=video 
stream_index=0 
pts=N/A 
pts_time=N/A 
dts=N/A 
dts_time=N/A 
duration=0 
duration_time=0:00:00.000000 
size=11.727 Kibyte 
pos=22936 
flags=_ 
[/PACKET] 
... 
[PACKET] 
codec_type=audio 
stream_index=1 
pts=126000 
pts_time=0:00:01.400000 
dts=126000 
dts_time=0:00:01.400000 
duration=2089 
duration_time=0:00:00.023211 
size=285.000 byte 
pos=109416 
flags=K 
[/PACKET] 
[PACKET] 
codec_type=audio 
stream_index=1 
pts=128089 
pts_time=0:00:01.423211 
dts=128089 
dts_time=0:00:01.423211 
duration=2089 
duration_time=0:00:00.023211 
size=374.000 byte 
pos=-1 
flags=K 
[/PACKET] 
... 
[PACKET] 
codec_type=video 
stream_index=0 
pts=N/A 
pts_time=N/A 
dts=N/A 
dts_time=N/A 
duration=0 
duration_time=0:00:00.000000 
size=20.000 Kibyte 
pos=87232 
flags=_ 
[/PACKET] 
[PACKET] 
codec_type=video 
stream_index=0 
pts=N/A 
pts_time=N/A 
dts=N/A 
dts_time=N/A 
duration=0 
duration_time=0:00:00.000000 
size=16.852 Kibyte 
pos=112800 
flags=_ 
[/PACKET] 

out.ts

[PACKET] 
codec_type=audio 
stream_index=1 
pts=0 
pts_time=0:00:00.000000 
dts=0 
dts_time=0:00:00.000000 
duration=2089 
duration_time=0:00:00.023211 
size=285.000 byte 
pos=22936 
flags=K 
[/PACKET] 
[PACKET] 
codec_type=audio 
stream_index=1 
pts=1024 
pts_time=0:00:00.011378 
dts=1024 
dts_time=0:00:00.011378 
duration=2089 
duration_time=0:00:00.023211 
size=374.000 byte 
pos=23312 
flags=K 
[/PACKET] 
... 

[PACKET] 
codec_type=video 
stream_index=0 
pts=N/A 
pts_time=N/A 
dts=N/A 
dts_time=N/A 
duration=0 
duration_time=0:00:00.000000 
size=11.727 Kibyte 
pos=25004 
flags=_ 
[/PACKET] 
[PACKET] 
codec_type=audio 
stream_index=1 
pts=7168 
pts_time=0:00:00.079644 
dts=7168 
dts_time=0:00:00.079644 
duration=2089 
duration_time=0:00:00.023211 
size=299.000 byte 
pos=55460 
flags=K 
[/PACKET] 

Как вы можете видеть, FFmpeg .ts начинается с видеопакетов, у которых нет pts/dts. Последующие аудиопакеты содержат pts/dts. Это повторяется до конца. Все видеопакеты не имеют pts/dts в соответствии с выходом ffprobe.

Однако out.ts запускается со звуковыми пакетами и чередуется с видеопакетами. Здесь видеопакеты также не имеют pts/dts. Разница в том, что здесь есть один видеопакет между сериями аудиопакетов. Что случилось с остальными видеопакетами (ffmpeg.ts имеет ~ 5 аудио, а затем ~ 5 видео).

Очевидно, что я все еще участвую и не знаю слишком многого ... Что-нибудь выпрыгивает, как очевидная проблема для кого-либо? Я буду очень благодарен за любую информацию/предложения, но буду продолжать помогать!

ответ

2

Хорошо, как я и предполагал, это было очевидно, но не новичкам.В принципе, даже если вам не нужно перекодировать пакеты, потоки в исходном контейнере имеют собственную временную базу для каждого потока. Это нужно преобразовать или «перемасштабировать» в базу времени нового выходного потока.

packet.pts = av_rescale_q(packet->pts, inStream->time_base, outStream->time_base); 
packet.dts = av_rescale_q(packet->dts, inStream->time_base, outStream->time_base); 

Это правильно перемасштабирует пакеты для каждого потока. Конечно, это, вероятно, самое основное действие, которое можно предпринять, и может потребоваться выполнение дополнительных чередований/перерасчетов (у пакета нет dts/pts). Тем не менее, я контролирую входной файл, поэтому для меня это достаточно.

+0

Можно ли получить доступ к этому коду где-нибудь? Я работаю над чем-то, что нужно сделать практически в одном и том же, и у меня проблемы с работой кода. –

+0

Ты потрясающий. Я боролся с этим в течение нескольких дней, и мне кажется, что для его исправления потребовалось всего две строки. Спасибо огромное! –