ijkplayer音视频同步

news2024/11/19 17:23:56

接上篇:

ijkplayer框架的集成( 从开始到优化秒开)

补充:

ijkplayer - 拓展:

 资料收集备用。

1、在弱网时使用

2、ijkplayer播放卡顿

3、如何支持https链接播放

4、如何降低ijkplayer延迟效应

5、ijkplayer中音视频同步,是如何做的?

一、在弱网时如何优化

好的网络下视音频能够得到及时的发送,不会造成视音频数据在本地的堆积,直播效果流畅,延时较小。而在弱网网络环境下,视音频数据发送不出去,则需要我们对视音频数据进行处理。差网络环境下对视音频数据一般有四种处理方式:缓存区设计、网络检测、丢帧处理、降码率处理。

1、缓冲区设计
视音频数据传入缓冲区,发送者从缓冲区获取数据进行发送,这样就形成了一个异步的生产者消费者模式。生产者只需要将采集、编码后的视音频数据推送到缓冲区,而消费者则负责从这个缓冲区里面取出数据发送。

视音频缓冲区

上图中只显示了视频帧,显然里面也有相应的音频帧。要构建异步的生产者消费者模式,java中使用LinkedBlockingQueue,可以对之后进行丢帧、插入、取出等处理。

2、网络检测
差网络处理过程中一个重要的过程是网络检测,当网络变差的时候能够快速地检测出来,然后进行相应的处理,这样对网络反应就比较灵敏,效果就会好很多。通过实时计算每秒输入缓冲区的数据和发送出去数据,如果发送出去的数据小于输入缓冲区的数据,那么说明网络带宽不行,这时候缓冲区的数据会持续增多,这时候就要启动相应的机制。

3、丢帧处理
当检测到网络变差的时候,丢帧是一个很好的应对机制。视频经过编码后有关键帧和非关键帧,关键帧也就是一副完整的图片,而非关键帧描述图像的相对变化。
丢帧策略多钟多样,可以自行定义,一个需要注意的地方是:如果要丢弃P帧(非关键帧),那么需要丢弃两个关键帧之间的所有非关键帧,不然的话会出现马赛克。对于丢帧策略的设计因需求而异,可以自行进行设计。如下我一个丢帧实例:
当CPU在处理视频帧的时候处理得太慢,默认的音视频同步方案是视频同步到音频, 导致了音频播放过快,视频跟不上。
在ff_ffplay_options.h中,找到如下代码:

 可以通过修改 framedrop 的值来解决不同步的问题,framedrop 是在视频帧处理不过来的时候丢弃一些帧达到同步的效果。具体设置,在上层Java层中IjkVideoView中

默认ijkplayer中是1,你可以自行,修改这个值。

4、降码率
在Android中,如果使用了硬编进行编码,在差网络环境下,我们可以实时改变硬编的码率,从而使直播更为流畅。当检测到网络环境较差的时候,在丢帧的同时,我们也可以降低视音频的码率。在Android sdk版本大于等于19的时候,可以通过传递参数给MediaCodec,从而改变硬编编码器出来数据的码率。

Bundle bitrate = new Bundle();bitrate.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, bps * 1024);
mMediaCodec.setParameters(bitrate);

二、ijkplayer播放卡顿如何优化

在做音频播放的时候,使用的是开源的ijkplayer播放器,ijkplayer解码使用的是ffmpeg,声音输出使用的是audiotrack,在某机型上面播放遇到锁屏、返回后台、点击home键的时候会出现声音卡顿的现象,会输出下面的log

W/AudioTrack: releaseBuffer() track 0xcce8b600 disabled due to previous underrun, restarting

我实现播放调用步骤是在AsyncTask中,查阅资料发现是因为在线程中播放造成的问题,经过查看asynctask构造方法发现,asynctask会把线程的优先级设置为THREAD_PRIORITY_BACKGROUND后台线程,于是我将线程的优先级设置为THREAD_PRIORITY_URGENT_AUDIO,解决了播放卡顿的问题,我猜测播放线程优先级降低,系统分配时间片会减少,会导致底层ijk读数据输出数据时得不到及时的回应,audiotrack频繁的releasebuffer,restarting声道,造成卡顿。

三、如何支持https链接播放?

如果你的项目要进行加密播放HLS协议的视频,要想支持https,须要在普通编译的基础上,进行一些配置。

接下来我们来编译openssl

1.init openssl

$ cd ..    进入到ijkplayer的目下
$ ./init-android-openssl.sh   去远程仓库拉取openssl的远程代码,如果是iOS的,这里是init-ios-openssl.h

2.compile openssl

$ cd android/contrib
$ ./compile-openssl.sh clean
$ ./compile-openssl.sh all

经过以上步骤已经编译好openssl了,然后我们执行一下方法

$./compile-ffmpeg.sh clean
     编译ffmpeg软解码库,这个过程会生成各种架构的ffmpeg 这个过程比较耗时
$./compile-ffmpeg.sh all

四、如何降低ijkplayer延迟效应

通过修改源文件,因为ijkplayer实际上是基于ffplay.c实现的: 

见上篇 ijkplayer框架的集成( 从开始到优化秒开)

五、ijkplayer中音视频同步,是如何做的?

对于播放器来说,音视频同步是一个关键点,同时也是一个难点,同步效果的好坏,直接决定着播放器的质量。通常音视频同步的解决方案就是选择一个参考时钟(主 clock),播放时读取音视频帧上的时间戳,同时参考当前时钟参考时钟(主 clock)上的时间来安排播放。如下图所示:

如果音视频帧的播放时间大于当前参考时钟上的时间,则不急于播放该帧,直到参考时钟达到该帧的时间戳;
如果音视频帧的时间戳小于当前参考时钟上的时间,则需要“尽快”播放该帧或丢弃,以便播放进度追上参考时钟。
参考时钟的选择也有多种方式:

选取视频时间戳作为参考时钟源
选取音频时间戳作为参考时钟源
选取外部时间作为参考时钟源
考虑人对视频、和音频的敏感度,在存在音频的情况下,优先选择音频作为主时钟源。

ijkplayer在默认情况下也是使用音频作为参考时钟源,我们可以找到ff_ffplay.c文件中,处理同步的过程主要在视频渲染video_refresh_thread的线程中

从上述实现可以看出,该方法中主要循环做两件事情:

  • 休眠等待,remaining_time的计算在video_refresh中
  • 调用video_refresh方法,刷新视频帧

可见同步的重点是在video_refresh中,下面看该方法一些关键部分:

lastvp是上一帧,vp是当前帧,last_duration则是根据当前帧和上一帧的pts(Presentation Time Stamp。PTS主要用于度量解码后的视频帧什么时候被显示出来),计算出来上一帧的显示时间,经过compute_target_delay方法,计算出显示当前帧需要等待的时间。

在compute_target_delay函数中,如果发现当前主Clock源不是video,则计算当前视频时钟与主时钟的差值:

如果当前视频帧落后于主时钟源,则需要减小下一帧画面的等待时间;
如果视频帧超前,并且该帧的显示时间大于显示更新门槛,则显示下一帧的时间为超前的时间差加上上一帧的显示时间
如果视频帧超前,并且上一帧的显示时间小于显示更新门槛,则采取加倍延时的策略。
回到video_refresh函数中,有如下逻辑:

frame_timer实际上就是上一帧的播放时间,而frame_timer + delay实际上就是当前这一帧的播放时间,如果系统时间还没有到当前这一帧的播放时间,直接跳转至display,而此时is->force_refresh变量为0,不显示当前帧,进入video_refresh_thread中下一次循环,并睡眠等待。

如果当前这一帧的播放时间已经过了,并且其和当前系统时间的差值超过了AV_SYNC_THRESHOLD_MAX,则将当前这一帧的播放时间改为系统时间,并在后续判断是否需要丢帧,其目的是为后面帧的播放时间重新调整frame_timer,如果缓冲区中有更多的数据,并且当前的时间已经大于当前帧的持续显示时间,则丢弃当前帧,尝试显示下一帧

否则进入正常显示当前帧的流程,调用video_display2开始渲染。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/541315.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

javaIO流之文件流

目录 简介一、File的构造方法二、File的常用方法1、获取功能的方法2、绝对路径和相对路径3、判断功能的方法4、创建、删除功能的方法5、目录的遍历6、递归遍历 三、RandomAccessFile1、主要方法 四、Apache FileUtils 类1、复制文件或目录:2、删除文件或目录&#x…

提高运算放大器输出功率

运算放大器的串联:如何同时实现高精度和高输出功率 复合放大器 复合放大器由两个单独放大器组合而成,分别具有不同的特性。 图1所示就是这种结构。放大器1为低噪声精密放大器ADA4091-2。 在本例中,放大器2为AD8397,具有高输出功率&#xff…

召回/粗排阶段 负样本常见构造方法

文章目录 1、曝光未点击2、全局随机选择负例3、batch内随机选择负例4、曝光数据随机选择负例5、基于popularity随机选择负例6、基于hard选择负例大佬的总结: 大佬的名言:“如果精排是特征的艺术,那么召回就是样本的艺术(负样本为王…

linux 用mv替代rm将文件移动到回收站,避免误操作

有时候在linux上操作rm -rf 删除命令时,不下心就会将不想删除的文件给删除了,删完后,顿时傻眼了,比如 ,文件夹test下面有 a ,a1 ,b ,b2四个文件,本来想删除test文件夹下面的a和a1连个文件, 输入…

TCP、UDP原理、DNS协议、CDN原理

1. 如何理解UDP 和 TCP? 区别? 应用场景? 一、UDP UDP(User Datagram Protocol),用户数据包协议,是一个简单的面向数据报的通信协议,即对应用层交下来的报文,不合并,不拆分,只是…

Win10搭建Docker Desktop

Win10搭建Docker Desktop 1 介绍 Docker Desktop是适用于Windows的Docker桌面,是Docker设计用于在Windows 10上运行。它是一个本地 Windows 应用程序,为构建、交付和运行dockerized应用程序提供易于使用的开发环境。Docker Desktop for Windows 使用 Wi…

ChatGPT 插件,组合后更妙了

ChatGPT 插件,组合后更妙 大家好,我是章北海mlpy 昨天极简介绍了一些热门的ChatGPT插件 我测试了一些组合玩法,感觉效率、效果都远超预期。 今天就演示一下如何利用多个插件,高速阅读、理解一篇论文。 备注:一个C…

HTB靶机013-Poison-WP

013-Poison 靶机IP: 10.10.10.84 Scan Nmap 快速扫描: ┌──(xavier㉿kali)-[~] └─$ sudo nmap -sSV -T4 10.10.10.84 -F Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-30 16:41 CST Nmap scan report for 10.10.10.84 Host is up (0.27s…

公牛车充拆解 | 拓尔微A+C双口快充方案IM2403+TMI3451

在快节奏的生活中,手机已成为人们不可或缺的工具。对于经常开车出门的人来说,在车上给手机充电已经成为刚需,因此车载充电器是很多车主的不二之选,它能便捷地解决手机在车内充电的问题,让车主在开车途中保持电量充足。…

MySQL高级_第10章_索引优化与查询优化

MySQL高级_第10章_索引优化与查询优化 1. 数据准备 学员表 插 50 万 条, 班级表 插 1 万 条。 步骤 1 :建表 CREATE TABLE class ( id INT ( 11 ) NOT NULL AUTO_INCREMENT , className VARCHAR ( 30 ) DEFAULT NULL , address …

FlinkKafkaProducer 源码分析

initializeState 先查询是否开启isCheckpointingEnabled配置,如果没开,但是使用了EXACTLY_ONCE或者AT_LEAST_ONCE语义,就报错。 然后从checkpoint中保存的state中读取nextTransactionalIdHintState。 NEXT_TRANSACTIONAL_ID_HINT_DESCRIPTOR…

表情、特殊字符、字符串截取

码元与码点 关于码元和和码点,通过一个例子进行介绍。 如图,字符串😊只有一个“笑脸”符号,但是通过length属性发现,“长度”为2,string.length到底表示什么? 答:码元的个数 什么是…

C语言爬取HTML-爬取壁纸 文末附源码

前言:这学期计算机软件课程设计的其中一个题目是使用C语言爬取HTML,本打算使用C语言的CSpidr库来实现,但是因为它的依赖liburi没有找到在哪里安装,所以放弃了这个想法,使用的是curl以及libxml2这两个库,能够…

这几款实用且有趣的软件不容错过

软件一:天若ocr 这款Windows平台的天若OCR文字识别工具一定更适合你。 软件作者来自天若游心,我爱破解。 发布一年半以来一直深受好评,更新速度也非常快。 最近,它增加了批次识别功能。 软件二:腾讯柠檬精简版 除了Q…

P2233 [HNOI2002]公交车路线

题目描述 在长沙城新建的环城公路上一共有 8 个公交站,分别为 A、B、C、D、E、F、G、H。公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另外一个公交站往往要换几次车,例如从公交站 A 到公交站 D,你就至少需要…

keycloak介绍与使用示例,超时时间设置

keycloak介绍 Keycloak是一款由Red Hat开源社区开发的开放源代码的身份和访问管理解决方案,它提供了安全的单点登录(SSO)、多因素身份验证、社交登录和基于角色的访问控制等功能Keycloak基于OAuth 2.0和OpenID Connect协议,并支持SAML 2.0,可…

spring Bean的循环依赖问题

public class Husband {private String name;private Wife wife;public void setName(String name) {this.name name;}public String getName() {return name;}public void setWife(Wife wife) {this.wife wife;}// toString()方法重写时需要注意:不能直接输出wif…

【计算机网络基础】章节测试2 物理层

文章目录 判断题选择题辨析题应用题 判断题 现在的无线局域网常用的频段是2.8GHz和5.4GHz。 多模光纤只适合于近距离传输。√ 数据在计算机内部多采用串行传输方式,但在通信线路上多采用并行传输方式。 统计时分复用可以按需动态分配时隙。√ 相对于同步时分复用…

卷麻了,新来的00后实在是太卷了...

在程序员职场上,什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事,我们可以帮他。 是技术太强的人吗?也不是。技术很强的同事,可遇不可求,向他学习还来不及呢。 真正让人反感的,是技术平平&…

geoserver切片数据本地缓存和层级配置

很多业务场景中,我们会用到图层切片功能,默认情况下,每次调用都是新的重新切片,这样在性能上存在一定问题;基于此我们可以进行本地缓存切片,及此地理位置只进行一次切片处理,数据缓存在本地磁盘…