ffmpeg java 播放视频_Javacv使用ffmpeg实现音视频同步播放
最近用javaCV的ffmpeg包的FFmpegFrameGrabber帧捕捉器对捕捉到的音频帧和视频帧做了同步的播放。采用的同步方法是视频向音频同步。
具体的思路如下:
(1)首先介绍ffmpeg是如何捕捉视频文件的图像和声音的
FFmpegFrameGrabber fg = new FFmpegFrameGrabber("a video file path or a url);
得到帧捕捉器对象后,调用它的grab()方法就会返回捕捉到的Frame对象。这个Frame可以是视频帧或者是音频帧,这是因为音视频帧时按照时间戳在播放时间先上排列的。当然捕捉到的帧都是已经译码过的,并且存储在java.nio.Buffer对象中,对于视频帧,Buffer是储存图像的像素数据比如RGB,然后通过
BufferedImage bi = (new Java2DFrameConverter()).getBufferedImage(f);
就可以得到图片,得到的图片可以进行一系列的处理或者不处理直接显示在swing组件上。对应音频帧,Buffer是储存音频的PCM数据,这个PCM可以是float或者short的,然后用java.sounds.sample里面的sourceDataLine.write方法就可以将这些音频PCM数据写入到扬声器中。
(2)接着介绍如何不断得将得到的帧播放出来。首先是单独播放视频:
while(true)
{
Frame f = fg.grab();
if(f.image!=null)
label.setIcon(new ImageIcon((new Java2DFrameConverter()).getBufferedImage(f)));
Thread.sleep(1000/视频帧率);
}
单独播放音频同理,将数据写入到声卡即可。例子
(3)生产消费者模式。
上图是程序实现的方法,采用生产者模式将捕获到的帧进行判断,如果是视频帧就生产到视频FIFO中,如果是音频帧就生产到音频FIFO中,然后音频播放线程和视频播放线程分别从各自的帧仓库消费里面的帧。之所以采用生产消费者模式是因为帧捕获的速度是大于帧的消耗的,所以我们优先捕获帧来缓冲,或者进一步对捕获的帧进行预处理,而视频和音频播放线程只需要将处理过的帧直接播放显示即可。
(4)实现音视频同步的方法:播放两帧音频里面的所有视频帧。
想要实现音视频同步,必须要有帧的时间戳,这里捕获到的帧只有播放的时间戳PTS,没有译码时间戳DTS,所以我们只需要根据播放时间戳来决定播放即可。
程序的实现是根据上图来的, 当音频线程开始播放音频帧A1时,就调用视频线程的setRun方法,并且传递当前要播放的音频帧时间戳curTime和下一帧音频帧A2的时间戳nextTime给处于wait态的视频线程,然后视频线程启动,开始从视频FIFO中取出视频帧G1,然后计算G1和A1的时间差,作为播放的延时,Thread.sleep(t1)后,视频线程就将图片显示在swing组件上,比如JLabel.setIcon(image)。然后视频线程再取出一帧图像G2,比较G2的时间戳和A2的时间戳,如果G2时间戳小于A2,那么视频线程继续延时t2以后,播放这个G2图像,接着G3同理,直到取得G4,和A2比较发现G4时间戳大于A2,那么视频线程就进入wait态,等待下一次启动。然后音频线程播放完A1音频帧以后,就从仓库取出音频帧A3,然后将A2的时间戳和A3的时间戳传递给视频线程,然后开始播放A2,然后堵塞的视频线程同理继续播放。
(5)动态调节延时时间
由于个人PC都不是实时操作系统,也就是Thread.sleep是不精确的,并且受到声卡播放声音的制约,所以上面的基本实现思路是需要加以完善的。首先java的sourceDataLine的方法是依照一定的速度从内部缓冲区取出音频线程写入的数据,如果音频写入的数据被取光了,那么音频播放就会发生卡顿,但是如果一次音频数据写入过多,那么就会发生音视频可能就会不同步,所以要确保sourceDataLine的内部缓冲区是留有一定数据的,否则就会造成卡顿,但是数据量又不能过多,所以我们在G3到A2这段时间来进行声音播放的调节,由于延时的不精准性,写入的A1帧的数据可能时间还没满t6就可能被声卡取光了,所以在播放完G3图像以后,声音线程会判断根据sourceDataLine.available()返回的数据量进行判断,如果数据量快要完了,就减少G3到A2的延时时间t4。这样子就可以保证数据量是不会变为0造成声音卡顿。
(6)下面是程序在window64下测试和ubuntu14下测试的结果图: 播放是比较流畅的,同步也是可以的,但是开着播放比企鹅在IDE如IDEA中写代码的话,会卡,毕竟IDEA也是用java开发的,所以IDEA的运行会影响其他java程序,但是其他进程不会影响。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
ffmpeg java 播放视频_Javacv使用ffmpeg实现音视频同步播放相关推荐
- FFmpeg音视频解码同步播放流程
FFmpeg音视频解码同步播放流程 数据接收后处理流程及阶段示意图: 1.接收导数据(Trans Stage) 2.新建音.视频解码线程(Parse Stage) 3.将解码好的数据分别放入队列(St ...
- 音视频7——安卓软编音视频数据推送到rtmp服务器
音视频开发路线: Android 音视频开发入门指南_Jhuster的专栏的技术博客_51CTO博客_android 音视频开发入门 demo地址: videoPath/Demo8Activity.j ...
- 音视频7——安卓硬编音视频数据推送到rtmp服务器
音视频开发路线: Android 音视频开发入门指南_Jhuster的专栏的技术博客_51CTO博客_android 音视频开发入门 demo地址: videoPath/Demo8Activity.j ...
- SRS流媒体服务器架构设计及源码分析丨音视频开发丨C/C++音视频丨Android开发丨嵌入式开发
SRS流媒体服务器架构设计及源码分析 1.SRS流媒体服务器架构设计 2.协程-连接之间的关系 3.推流-转发-拉流之间的关系 4.如何手把手调试SRS源码 视频讲解如下,点击观看: SRS流媒体服务 ...
- 【音视频开发系列】盘点音视频直播RTSP/RTMP推流一定会遇到的各种坑,教你快速解决
聊聊RTSP/RTMP推流那些坑 1.推流架构分析 2.推流缓存队列的设计 3.FFmpeg函数阻塞问题分析 [音视频开发系列]盘点音视频直播一定会遇到的各种坑,教你快速解决 更多精彩内容包括:C/C ...
- 视频生产环境下的音视频解决方案
随着云剪辑.云导播.音视频生产在线协作的兴起, 生产环境下的音视频处理越发为人所关注.音视频处理在生产环境下,对控制精准性有着更高的要求.从服务端到客户端,精准的时间控制.画面控制都是生产环境音视频和 ...
- 【LiveVideoStack线上分享】— 视频生产环境下的音视频解决方案
随着云剪辑.云导播.音视频生产在线协作的兴起, 生产环境下的音视频处理越发为人所关注.音视频处理在生产环境下,有着更高的控制精准性的要求.从服务端到客户端,精准的时间控制.画面控制都是生产环境音视频和 ...
- 音视频基础(1)音视频处理流程
文章目录 音视频基础(1)音视频处理流程 1. 概要 2. 音频处理流程 3. 视频处理流程 4. 直播客户端处理流程 5. 音频数据流转 音视频基础(1)音视频处理流程 理解音频处理流程对我们做音视 ...
- 视频质量分析系统之音视频测试工具
Video Clarity视频质量分析系统 视频图像质量测试仪器ClearView是美国Video Clarity公司的产品.Video Clarity公司,美国专业音视频主观和客观质量测试系统提供商 ...
最新文章
- java jpa @joincolumn 字段不为空_拥抱开源从表设计到 JPA 实现
- 结语|日拱一卒无有尽,功不唐捐终入海
- python对列求和_对单个列求和的最快方法
- redis 任务队列
- Java自学网站推荐(整理好发给大家)
- android改手机名称,如何修改手机 App 的名称?「App Name Editor」可轻松自订(Android)...
- 2020.9.19hive函数和自定义UDF函数
- Java 统计文件ip_基于zxinc网站ipv6静态数据文件的JAVA查询实现
- 读《弗洛伊德:作家与白日梦》
- HTML <dfn> 标签
- Beam Search、GREEDY DECODER、SAMPLING DECODER等解码器工作原理可视化以及在自然语言生成领域的使用
- 前端背景图放置_html 多张背景图片并存
- linux查看日志文件内容命令tail、cat、tac、head、echo
- 大数据行业部署实战2:环境大数据统计
- 申报高新技术企业认定哪些地方需要注意?
- 易买网更多新闻代码_新闻 | 0516崔智友得女等更多资讯
- 金融时间序列分析:5. AR模型实例(Python)
- 【安全牛学习笔记】Smurf攻击、Sockstress
- EagleClouds专业网站建设和软件开发服务
- 软件著作权登记办理流程
热门文章
- 最简单解决maven依赖报红 | 不用执行maven命令
- 用CSS画个退出按钮
- Flutter--可拖拽组件封装,支持拖动到列表边缘时图自动滚动!!!基于EdgeDraggingAutoScroller
- Linux的ntp和firewalld服务_16
- C# Winfrom 自定义控件——带图片的TextBox
- 如何在vue3+vite+ts中使用require
- lz77优化_与熊论道(熊曰加密)算法更新和界面优化
- 电商用户购买行为数据分析
- 动网论坛8.X漏洞利用拿webshell总结
- Fluent 粘度计算方法总结