2013-05-21 2 views
2

좋아, 원래 게시물을 만들 때 ffmpeg API에 대해 거의 알지 못했습니다. 디지털 미디어 및 변환 세부 정보를 배우기 시작하면 매우 압도적입니다. 꽤 많은 것을 읽고 ffmpeg 소스를 살펴본 후 mp4에서 mpeg 로의 작업 출력을 얻을 수있었습니다. 개념은 실행에 유사합니다MPEG4를 FFmpeg로 Android에서 MPEGTS로 변환

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

을하지만 내가 전에 언급 한 바와 같이 나는 플레이 .TS 파일을 생성 할 수 있어요하지만, 나는

그래서 C로는 FFmpeg API로 구현해야 그를 비디오 및 오디오 스트림이 동기화되지 않습니다. 즉, Android 태블릿에서 다시 재생하면 오디오가 정상 속도로 재생되는 동안 동영상이 매우 느리게 재생 된 다음 동영상이 끝까지 보통 속도로 재생됩니다 (오디오 스트림이 끝나면). VLC에서 생성 된 .ts 파일을 재생하면 매우 빠르게 압축 된 오디오가 재생되고 비디오는 잘 재생됩니다.

아직 익숙하지 않은 미디어 변환의 측면이 많이 있습니다. 나는 그들 중 일부가 성공적인 전환을 막을 것이라고 확신한다. 여기

는 파일에 대한 (ffprobe를 통해) 몇 가지 정보입니다 : - in.mp4 - 안드로이드 녹화를 통해 생성 된 파일 - 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에 영향을 미칠 수 없습니다.

[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

[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

ffmpeg.ts : 다음, 프로브의 -show_packets 출력을 검사에, 나는 다음을 보았다 .ts는 pts/dts가없는 비디오 패킷으로 시작합니다. 뒤 따르는 오디오 패킷에는 pts/dts가 포함됩니다. 이것은 끝날 때까지 반복됩니다. 모든 비디오 패킷에는 ffprobe 출력에 따라 pts/dts가 없습니다.

그러나 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

당신은 훌륭합니다. 나는 이것을 며칠 동안 고민해 왔으며 그것을 고치기 위해서 단지 두 줄 밖에 잡히지 않았다. 정말 고맙습니다! –