原地址:http://www.jianshu.com/p/27279255f67e

音视频播放器的工作的具体流程如下图所示:

播放器工作流程

简单的来说包括:解协议,解封装,对音频和视频分别进行解码,音视频同步播放这几个部分,各部分详细解释请看后面参考资料。由于我们是分别解码和播放音频和视频的,所以各自播放的节奏需要同步,否则会出现音画不一致的情况。本文主要介绍一个简单的音视频同步的方案。

准备工作

  1. 实现FFMpeg音频播放
  2. 实现FFMpeg视频播放

相关知识

  1. PTS和DTS
    音视频流中的每一帧都有时间相关的信息,其中PTS是播放时间,DTS是解码时间。音频的PTS和DTS是一致的,而某些视频各种中可能会存在DTS和PTS不一致的帧,我们这里主要通过PTS来控制播放时间。对解码后的AVFrame使用av_frame_get_best_effort_timestamp可以获取PTS。
  2. time_base
    我们注意到PTS是一个整形数据,time_base是PTS的单位,PTS乘以time_base即可得到实际时间。只有AVStream中获取的time_base才是对的,其他地方获取的可能会有问题。
  3. 音视频同步策略
    一般来说有三种方式,音频同步到视频,视频同步到音频,音视频同步到外部时间。一般各个参数设置正确音频就能够以正常的速度播放,所以把视频同步到音频在一般情况下,是一个简单有效的同步策略。本文主要采取这个方式同步音视频,来展示相关的基本思路。

同步视频到音频

  1. 获取解码的视频帧时间。

    AVFrame vFrame;
    AVStream vStream;
    //...解析视频获取vStream,解码视频帧获得vFrame...
    double timestamp = av_frame_get_best_effort_timestamp(&vFrame)*av_q2d(vStream->time_base);
  2. 获取解码的音频帧时间。
    AVFrame aFrame;
    AVStream aStream;
    //...将正在播放的音频时间点记录下来作为基准...
    audioClock = aFrame.pkt_pts * av_q2d(aStream->time_base);
  3. 音视频同步逻辑
    /* no AV sync correction is done if below the minimum AV sync threshold */
    #define AV_SYNC_THRESHOLD_MIN 0.04
    /* AV sync correction is done if above the maximum AV sync threshold */
    #define AV_SYNC_THRESHOLD_MAX 0.1
    /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
    #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
    /* no AV correction is done if too big error */
    #define AV_NOSYNC_THRESHOLD 10.0
    double timestamp;
    //判断是否有有效的pts
    if(packet.pts == AV_NOPTS_VALUE) {timestamp = 0;
    } else {timestamp = av_frame_get_best_effort_timestamp(&vFrame)*av_q2d(vStream->time_base);
    }
    //计算帧率,平均每帧间隔时间
    double frameRate = av_q2d(vStream->avg_frame_rate);
    frameRate += vFrame.repeat_pict * (frameRate * 0.5);
    if (timestamp == 0.0) {//按照默认帧率播放usleep((unsigned long)(frameRate*1000));
    }else {if (fabs(timestamp - audioClock) > AV_SYNC_THRESHOLD_MIN &&fabs(timestamp - audioClock) < AV_NOSYNC_THRESHOLD) {//如果视频比音频快,延迟差值播放,否则直接播放,这里没有做丢帧处理if (timestamp > audioClock) {usleep((unsigned long)((timestamp - audioClock)*1000000));}}
    }

工程代码

EasyPlayer

参考资料

  1. 视音频编解码技术零基础学习方法
  2. Tutorial 05: Synching Video

转载于:https://www.cnblogs.com/qcjd/p/9324894.html

FFmpeg 音视频同步相关推荐

  1. NDK学习笔记:FFmpeg音视频同步3(你追我赶,升级ffmpeg/libyuv支持neon)

    NDK学习笔记:FFmpeg音视频同步3 本篇内容说多不多,但如果要说得明明白白的,可能就有点难度了.所以我决定把我的调试过程日志都呈现出来,方便大家理解.继上一篇文末,我们学习到了什么是DTS/PT ...

  2. FFMPEG音视频同步-音视频实时采集并编码推流

    FFMPEG音视频同步-音视频实时采集并编码推流 //------------------------------------------------------------------------- ...

  3. FFmpeg音视频同步基础知识

    1. I帧/P帧/B帧 I帧:I帧(Intra-coded picture, 帧内编码帧,常称为关键帧)包含一幅完整的图像信息,属于帧内编码图像,不含运动矢量,在解码时不需要参考其他帧图像.因此在I帧 ...

  4. FFMPEG音视频同步-音视频实时采集并编码推流-优化版本

    https://blog.csdn.net/quange_style/article/details/90213392

  5. FFMPEG音视频同步-音频实时采集编码封装成MP4

    https://blog.csdn.net/quange_style/article/details/90083173

  6. ffmpeg源码中ffplay音视频同步原理及实现

    音视频指南 文章目录 音视频指南 前言 一.音视频同步简单介绍? 二.基本概念解释 1.为什么需要视频压缩 2.什么是I帧.p帧.b帧 3.什么是DTS,PTS 4.其他概念解释 三.常用同步策略 四 ...

  7. ffmpeg入门小结(二)——音视频同步

    1.H264格式简介(视频解码同步相关) ---------------------- 前言 ----------------------- H264是新一代的编码标准,以高压缩高质量和支持多种网络的 ...

  8. ffmpeg rtsp转hls_Qt音视频开发24-ffmpeg音视频同步

    ## 一.前言 用ffmpeg来做音视频同步,个人认为这个是ffmpeg基础处理中最难的一个,无数人就卡在这里,怎么也不准,本人也是尝试过网上各种demo,基本上都是渣渣,要么仅仅支持极其少量的视频文 ...

  9. 音视频同步原理[ffmpeg]

    音视频同步原理[ffmpeg] output_example.c 中AV同步的代码如下(我的代码有些修改),这个实现相当简单,不过挺说明问题. 阅读前希望大家先了解一下时间戳的概念. /* compu ...

最新文章

  1. prefixspan是挖掘频繁子序列,子序列不一定是连续的,当心!!!
  2. 8问8答,一篇文章读懂空间音效
  3. html复选框怎么转成数组,在HTML中将html表转换为数组
  4. MySQL索引类型 btree索引和hash索引的区别
  5. MySQL事务及锁机制大揭秘 - 公开课笔记
  6. 《犯罪心理学》读书笔记(part7)--犯罪心理的主观差异(中上)
  7. 使用签名保护基于HTTP的API
  8. [转]Unity3D新手引导开发手记
  9. “蚂蚁牙黑”太火,想玩就用ModelArts做一个!
  10. 【转】如何把Matlab中的m文件转化成C语言代码
  11. Pentest Wiki Part6 权限维持
  12. ISO 3166 2位国别编码
  13. 树莓派4b自带wifi_树莓派4B wifi开机启动
  14. 基于STM32的MLX90614(GY-906)人体红外测温
  15. 该怎么标注建筑图纸后进行保存?
  16. 十进制转换为N进制C语言
  17. 是的,你的AI技能正在“贬值”
  18. 一文详解 m3u8视频格式与视频秒开优化
  19. selenium闪退
  20. @MapKey用法说明

热门文章

  1. Java中new function另外新建个文件的写法
  2. spark的三种运行模式以及yarn-client和yarn-cluster在提交命令上的区别
  3. ./configure: error: the HTTP gzip module requires the zlib library.
  4. neo4j安装和启动
  5. 笔记本开机进入ubuntu16.04自动关闭触摸板
  6. pycharm的updating indices
  7. OpenCV3学习笔记二:图像的掩膜操作
  8. 【纯干货】Amoeba实现MySQL主从同步与读写分离
  9. GNU make manual 翻译( 一百七十五)
  10. 回顾-离开帝都半年了