当前位置: 代码迷 >> 多媒体/流媒体开发 >> 各位兄弟,请教怎么利用Ffmpeg进行音视频同步,非常感谢!(有代码)
  详细解决方案

各位兄弟,请教怎么利用Ffmpeg进行音视频同步,非常感谢!(有代码)

热度:9307   发布时间:2013-02-26 00:00:00.0
各位兄弟,请问如何利用Ffmpeg进行音视频同步,非常感谢!(有代码)
int main(int argc, char *argv[])
{
AVFormatContext *pFormatCtx;
int i, videoStream;
int audioStream;
AVPacket packet;

FILE *hVideo;
FILE *hAudio;

const char *input_file_name = "F:\\FFmpeg-full-SDK-3.2\\res\\src\\2.ts";// 2.ts为采用h264和mp3编码的文件
const char *output_file_name = "F:\\FFmpeg-full-SDK-3.2\\res\\dst\\2.h264";
const char *output_file_name2 = "F:\\FFmpeg-full-SDK-3.2\\res\\dst\\2.mp3";

hVideo = fopen(output_file_name, "wb+");
if(hVideo == NULL)
{
return 0;
}

hAudio = fopen(output_file_name2, "wb+");
if(hAudio == NULL)
{
return 0;
}

// Register all formats and codecs
av_register_all();

// Open video file
if(av_open_input_file(&pFormatCtx, input_file_name, NULL, 0, NULL)!=0)
return -1; 

// Retrieve stream information
if(av_find_stream_info(pFormatCtx) < 0)
return -1; 

// Dump information about file onto standard error
dump_format(pFormatCtx, 0, input_file_name, false);

// Find the first video stream
videoStream = -1;
audioStream = -1;
for(i = 0; i < pFormatCtx->nb_streams; i++)
{
if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
{
videoStream = i;
}
else if(pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
{
audioStream = i;
}
}
if(videoStream == -1)
{
return -1; 
}

while(av_read_frame(pFormatCtx, &packet) >= 0)
{
if(packet.stream_index == videoStream)
{
int len;
len = fwrite(packet.data, 1, packet.size, hVideo);
//fwrite(&packet.pts, 1, sizeof(int64_t), hVideo);
}
else if(packet.stream_index == audioStream)
{
fwrite(packet.data, 1, packet.size, hAudio);
//fwrite(&packet.pts, 1, sizeof(int64_t), hAudio);
}

// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}

av_close_input_file(pFormatCtx);

fclose(hVideo);
fclose(hAudio);

return 0;
}


如上代码可以分离出视频和音频,但有个问题,我想把2.h264和2.mp3分别放到不同的线程进行播放(解码)。要如何才能保证2.h264文件和2.mp3文件同步播放呢。非常感谢!


------解决方案--------------------------------------------------------
Ffmpeg sdk中有详细的同步代码,你可以借见。


不同的文件做同步,肯定需要手动。
因为,起点不一样,至少需要手动去对齐。
------解决方案--------------------------------------------------------
ffplay.c不就是个可以音视同步的播放器么
------解决方案--------------------------------------------------------
理论上是对的但是
pts不是真正的时间
pts *= av_q2d(is->video_st->time_base);
还要与一个基本的时间单位相乘
------解决方案--------------------------------------------------------
写包的时候pkt.pts就是控制同步的,这个必须弄对~
------解决方案--------------------------------------------------------
参考ffplay的定义的结构,用的是队列~
你可以看看AVPacketList这个结构~
------解决方案--------------------------------------------------------
typedef struct tag_VSTREAM_S 

HI_U8 pVBuffer[size2]; 
HI_U64 pts; 
HI_U32 len; // 这个长度是干嘛用的?
}VSTREAM_S,*pVSTREAM_S; 


typedef struct tag_VSTREAM_S 

HI_U8* pVBuffer; //用动态内存分配
HI_U64 pts; 
HI_U32 bufferLen;
}VSTREAM_S,*pVSTREAM_S;

可以参考TCP/IP 协议的处理。
------解决方案--------------------------------------------------------
ffmpeg为了支持最多格式 只是用av_read_frame实现了个音视频同步的框架而已,但完全照他的方式 效果肯定不好 。 另外你为什么要dump出音视频文件再同步? 可以搞个缓冲区试试。 当然这是流媒体播放器的思路了 呵呵
------解决方案--------------------------------------------------------
  相关解决方案