八、FFmpeg把音频流同步到视频流

本文介绍了如何使用FFmpeg将音频流同步到视频流。通过实现视频时钟、提取时钟、同步音频和修正样本数四个步骤,详细讲解了同步过程。文章提供了源码下载链接供读者实践。
摘要由CSDN通过智能技术生成

1、同步音频

现在我们已经有了一个比较像样的播放器了,最后让我们再来看一下剩下的一些简单的细节。在上章中我们说过也可以把音频同步到视频的,本章我们就来实现这个功能。这和把视频同步到音频是类似的:用一个内部视频时钟记录视频线程播放了多久,然后把音频同步到这个时钟上。最后我们再会进一步推广,把音频和视频都同步到外部时钟。

2、实现视频时钟

首先我们要实现一个类似音频时钟的视频时钟:一个给出当前视频播放时间的变量。可能你觉得这和使用上一帧的PTS来更新定时器一样简单。但是要注意了,当我们把视频帧间的时间间隔转化为毫秒的时候,这个间隔是很长的。所以我们采用另外一个办法,把视频时钟设置成我们为上一帧设置PTS的那个时间。于是当前视频时间值就是PTS_of_last_frame + (current_time -time_elapsed_since_PTS_value_was_set)。这种解决办法和get_audio_clock函数的方法很相似。 为此我们要在大结构体中,加上一个double型变量videoCurrentPts和一个int64_t型变量videoCurrentPtsTime,时钟更新将被放在refresh_video_timer函数中。

void refresh_video_timer(void *userdata) {
// ...
if(videoSate->pVAVStream) {
    if(videoSate->picQueueSi
int _tmain(int argc, _TCHAR* argv[]) { currentAudioClock = 0; currentVideoClock = 0; currentBufferClock = 0; //currentPlayClock=0; CurrentVolume = SDL_MIX_MAXVOLUME; if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); return 1; } SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); SDL_EventState(SDL_USEREVENT, SDL_IGNORE); atexit(SDL_Quit);// 注册SDL_Quit,当退出时调用,使得退出时程序自动清理 //flag=2; //给音视频队列分配空间 videoQueue = (VideoQueue *)av_mallocz(sizeof(VideoQueue)); audioQueue = (AudioQueue *)av_mallocz(sizeof(AudioQueue)); //初始化音视频队列 VideoQueueInit(videoQueue); AudioQueueInit(audioQueue); char* url = "G:/上海滩.mp4"; //char* url = "G:/2014年5月26日17 12 00至2014年5月26日17 14 59.avi"; //char* url = "H:/视频/不当交易.The.Unjust.BD.MiniSD-TLF.mkv"; //char* url = "E:/BaiduMusic/Songs/Love Story - Taylor Swift.mp3"; decodeTid = SDL_CreateThread(DecodePacket, "DecodePacket", (void*)url); PlayVideoTid = SDL_CreateThread(PlayVideo, "PlayVideo", NULL); PlayAudioTid = SDL_CreateThread(PlayAudio, "PlayAudioTid", NULL); int tid; SDL_WaitThread(decodeTid, &tid); printf("decodeTid %d\n", tid); SDL_WaitThread(PlayVideoTid, &tid); printf("PlayVideoTid %d\n", tid); SDL_WaitThread(PlayAudioTid, &tid); printf("PlayAudioTid %d\n", tid); SDL_DestroyMutex(audioQueue->audioMutex); SDL_DestroyCond(audioQueue->audioCond); SDL_DestroyMutex(videoQueue->videoMutex); SDL_DestroyCond(videoQueue->videoCond); av_free(videoQueue); av_free(audioQueue); return 0; }
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Storm-Shadow

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值