首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

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

2012-03-08 
各位兄弟,请问如何利用Ffmpeg进行音视频同步,非常感谢!(有代码)int main(int argc, char *argv[]){AVForma

各位兄弟,请问如何利用Ffmpeg进行音视频同步,非常感谢!(有代码)
int main(int argc, char *argv[])
{
AVFormatContext *pFormatCtx;
int i, videoStream;
int audioStream;
AVPacketpacket;

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出音视频文件再同步? 可以搞个缓冲区试试。 当然这是流媒体播放器的思路了 呵呵
------解决方案--------------------


网上有教程,http://www.dranger.com/ffmpeg/tutorial05.html
这个教程是用ffmpeg+SDL来实现视音频的插放与同步,同步还是要用到AVPacket的PTS和DTS、
[解决办法]
一般有三种办法
1.以音频为主进行同步
2.以视频为主进行同步
3.以一个外部参考时钟为同步
你可以参考下ffmpeg下的ffplay来做,还有
http://www.dranger.com/ffmpeg/tutorial05.html 和
http://www.dranger.com/ffmpeg/tutorial04.html 
具体如何实现还是要靠自己研究清楚代码后来解决的.

热点排行