前言java
从2016年6月开始写《javacv开发详解》系列,到而今的《javacv入门指南》,虽然仅隔了两年多时间,却也改变了不少东西。nginx
好比咱们的流媒体技术群从刚开始的两三我的发展到如今的三个500人群。又好比博主刚开始也想放弃,期间自行脑洞心里挣扎的场面也就不详说了,结果是如今还在坚持更新博客。固然这期间离不开群里小伙伴们一直以来的陪伴和支持,感谢你们一块儿默默为java流媒体技术踩坑,踩的多了也就真的成了路(也可能踩成深坑 )。另外感谢雷霄骅博士的ffmpeg博客,给予博主很大帮助,2016年刚开始接触ffmpeg就忽闻博士去世,甚为感慨,你们且行且珍惜吧。c++
之前历来不以为java能够作流媒体、音视频编解码这些,直到如今,顶多说java作流媒体是非主流。业界普遍应用的librtmp、live55五、ffmpeg也都是c/c++的库,刚开始也确实尝试过使用jni方式调ffmpeg,发现作起来吃力不讨好,后来在github发现了新大陆:javaCV。git
有,总比没有强。虽然连个API文档都没有,经过github项目描述的那可怜的几个字勉勉强强知道它对ffmpeg、opencv等等等十几个库作了封装,用javacpp方式为fmpeg、opencv等库编译了各个系统环境的包方便跨平台调用。github
一些题外话算法
踩坑到今天,可能还会有许多人踌躇疑惑javacv除了能够在音视频和图像处理这块稍微能够施展手脚外,还能够作什么?除了这些,在应对各类纷繁复杂的流媒体协议(rtp/rtsp/rtmp/flv/hls等等)也不在话下,固然一些小众和国产协议(好比sip/gb28181/jtt178等)可能须要依赖netty/mina等网络库来实现,编解码上结合javaCV,性能上也已经没有什么顾虑。另外在深度学习领域,deeplearning4j借助javaCV的东风令java在深度学习领域也一样引领风骚。数组
本系列将结合《javacv开发详解》系列做为实战教程,结合实例,力求简单易懂,快速上手。网络
1、老生常谈机器学习
javaCV能作什么,既然是"CV"大法,那天然是计算机视觉领域的库,诸如音视频、流媒体、图像处理、深度学习、机器学习、人工智能等等等(如今流行后面这三个,写上去应该能唬住很多人,deeplearning晓得不,里面一堆的javaCV库没发现吗)。tcp
2、入门基础
以上全是些空话,咱们无非就是要用javaCV采集视频和音频,给这些音视频编解码,而后是用什么封装格式封装这些音视频数据,以及用什么协议传输,可能还要对视频里的图像进一步进行处理(这个属于图像处理范畴),流程大体如此(音频方面了解很少,你们见谅):
拉流(采集)--->图像像素数据/音频数据<---->编/解码 <---->音/视频帧<---->解封装/封装---->推流
一、图像像素格式与图片封装格式
图像像素格式(简称像素格式),通常指的是没有通过编码的按照原始像素排列的数据。
举个栗子,一个完整图像的像素排列通常是这样的(以4*4像素的rgb像素格式为例):
rgbrgbrgbrgb
rgbrgbrgbrgb
rgbrgbrgbrgb
rgbrgbrgbrgb
固然咱们存储的时候通常使用一维数组来存这些数据,因此排列顺序就变成这样:rgbrgbrgbrgb.......以此类推。
图片封装格式指的咱们平常见到的png,jpg,bmp,gif等等图片格式,其中bmp是无损格式,里面的数据格式就是图片头信息加上rgb排列的像素数据,png/jpg这些都是有损压缩格式,可是压缩比仍是很高的,为何要压缩下面会讲到。
二、图像?视频帧?傻傻分不清楚
图像像素数据指的是yuv、rgb,rbga,bgr,gbra等图像像素格式,通过编码后才是视频帧。好比咱们常见的h264编码,编码其实就是对图像像素数据的压缩,(以rgb为例,假如当前图像像素尺寸为1920*1080,,每种颜色用一个字节表示,也就是说每一个像素点有红绿蓝三色共3字节,图像有1920*1080个像素点,也就是说这张图像大小为1920*1080*3字节,显然数据太大了),能够这样理解,h264编码本质上就是一种图像数据压缩算法。
三、编码?封装?傻傻分不清楚
编码上面已经讲了,是一种压缩算法;那么封装格式又是什么呢,封装格式就是咱们平常见到的视频文件了,好比mp4,avi,mkv,flv等等等,按照每种封装格式的规范把视频帧和音频按照必定顺序存起来就成咱们平常看到的视频文件了,这些封装格式通常都会包含一些头/尾标识和一些视频描述信息,这样播放器读取视频文件的时候就知道该怎么播放这些视频文件了(能够把封装格式理解成收纳箱,上面贴着小纸条说明里面放了哪些东西)。
压缩图片格式也能够参考视频编码格式,原理都同样,都是对图像数据作有损/无损压缩。
四、音/视频源
音/视频源能够是视频文件、音频文件,流媒体源,设备等等。
好比咱们要看电脑或手机摄像头视频,就得采集设备的图像数据(从源设备采集到的是像素数据,通常是bgr或者rgb像素数据)若是是某些厂商的商用摄像机,可能会支持rtsp/rtmp协议,要采集声音呢,就得采集录音/话筒设备里面的数据(通常是pcm采样数据)。
五、流媒体协议
rtsp协议栈,rtmp协议栈,hls,http-flv(理论上讲这个flv不能算是流媒体协议,它只是个无限大的flv文件)等等。
例如rtmp,对编码后的音视频帧,要对其进行封装成flv进行传输。
补充:说到底这些协议原理上依然是创建在tcp/udp基础上的应用层传输协议。
六、流媒体服务
支持音视频存储分发的服务均可以叫流媒体服务。
好比常见的srs(开源的rtmp流媒体服务,固然它支持rtmp/hls/http-flv的分发)和nginx(经过安装模块能够支持rtmp,hls,http-flv分发),除此以外的收费的和一些不太友好的开源流媒体服务就不一一介绍了。
下一章:javaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装了FFmpeg的音视频操做?
支持eguid原创