javaCV系列文章:
javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)
javaCV开发详解之3:收流器实现,录制流媒体服务器的rtsp/rtmp视频文件(基于javaCV-FFMPEG)
javaCV开发详解之4:转流器实现(也可作为本地收流器、推流器,新增添加图片及文字水印,视频图像帧保存),实现rtsp/rtmp/本地文件转发到rtmp流媒体服务器(基于javaCV-FFMPEG)
javaCV开发详解之5:录制音频(录制麦克风)到本地文件/流媒体服务器(基于javax.sound、javaCV-FFMPEG)
javaCV开发详解之6:本地音频(话筒设备)和视频(摄像头)抓取、混合并推送(录制)到服务器(本地)
javaCV开发详解之7:让音频转换更加简单,实现通用音频编码格式转换、重采样等音频参数的转换功能(以pcm16le编码的wav转mp3为例)
javaCV开发详解之8:转封装在rtsp转rtmp流中的应用(无须转码,更低的资源消耗,更好的性能,更低延迟)
补充篇:
javaCV开发详解补充篇:基于avfoundation的苹果Mac和ios获取屏幕画面及录屏/截屏以及摄像头画面和音频采样获取实现
音视频编解码问题:javaCV如何快速进行音频预处理和解复用编解码(基于javaCV-FFMPEG)
音视频编解码问题:16/24/32位位音频byte[]转换为小端序short[],int[],以byte[]转short[]为例
javacv文字识别系列:
javaCV文字识别之1:基于google的tesserac ocr识别图片中的文字,跨平台支持英文中文简体繁体等各种字符识别
javacpp-ffmpeg系列:
javacpp-FFmpeg系列之1:视频拉流解码成YUVJ420P,并保存为jpg图片
javacpp-FFmpeg系列之2:通用拉流解码器,支持视频拉流解码并转换为YUV、BGR24或RGB24等图像像素数据
javacpp-FFmpeg系列之3: 图像数据转换(BGR与BufferdImage互转,RGB与BufferdImage互转)
javacpp-FFmpeg系列补充:FFmpeg解决avformat_find_stream_info检索时间过长问题
javacpp-opencv系列:
一、javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体、位置、大小、粗度、翻转、平滑等操作
二、javaCV图像处理之2:实时视频添加图片水印,实现不同大小图片叠加,图像透明度控制
三、javacv图像处理3:使用opencv原生方法遍历摄像头设备及调用(方便多摄像头遍历及调用,相比javacv更快的摄像头读取速度和效率,方便读取后的图像处理)
一、本地推送端
1、本地:采用javaCV(安卓和java平台推荐javaCV)、ffmpeg、openCV或者jmf可以很方便的获取到本地(windows、macos、安卓、ios、linux或者其他设备)摄像头画面或者视频文件以及其他流媒体。
以下几篇是视频源抓取/采集篇:
javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG、javaCV-openCV)
javaCV开发详解之5:录制音频(录制麦克风)到本地文件/流媒体服务器(基于javax.sound、javaCV-FFMPEG)
javaCV开发详解之6:本地音频(话筒设备)和视频(摄像头)抓取、混合并推送(录制)到服务器(本地)
javaCV开发详解之9:基于gdigrab的windows屏幕画面抓取/采集(基于javacv的屏幕截屏、录屏功能)
javaCV开发详解之10:基于dshow调用windows摄像头视频和音频,想要获取屏幕画面首选gdigrab
javaCV开发详解补充篇:基于avfoundation的苹果Mac和ios获取屏幕画面及录屏/截屏以及摄像头画面和音频采样获取实现
2、监控(第三方摄像头):通过设备sdk或者rtsp直播流获取流媒体源
以下是以摄像机的rtsp地址为例(其中第4章是转码,第8章是转封装):
javaCV开发详解之4:转流器实现(也可作为本地收流器、推流器,新增添加图片及文字水印,视频图像帧保存),实现rtsp/rtmp/本地文件转发到rtmp流媒体服务器(基于javaCV-FFMPEG)
javaCV开发详解之8:转封装在rtsp转rtmp流中的应用(无须转码,更低的资源消耗,更好的性能,更低延迟)
二、转流端
直播:通过ffmpeg(推荐),live555将接收rtsp或者字节码流并转为flv格式发布到rtmp流媒体服务器(流媒体服务器必须先建好)
hls原理同上
注意:rtmp只支持flv格式封装的视频流
ffmpeg服务实现方式实例请参考:
http://blog.youkuaiyun.com/eguid_1/article/details/51777716
http://blog.youkuaiyun.com/eguid_1/article/details/51787646
也可以参考javaCV的转流器实现:javaCV开发详解之4:转流器实现,实现rtsp/rtmp/本地文件转发到rtmp服务器
java封装FFmpeg命令,支持原生ffmpeg全部命令,实现FFmpeg多进程处理与多线程输出控制(开启、关闭、查询),rtsp/rtmp推流、拉流
转封装实现:
javaCV开发详解之8:转封装在rtsp转rtmp流中的应用(无须转码,更低的资源消耗,更好的性能,更低延迟)
三、流媒体服务器
目前主流的流媒体服务器有:srs、nginx-rtmp(以及nginx其他流媒体插件)、fms、red5(java)、flazr
本地视频:直接通过流媒体服务器解码并推送视频流
直播流:通过开启udp/rtp/rtsp/rtmp/hls等等流媒体服务,从ffmpeg/live555获取推送过来的实时视频流并发布到rtmp/hls直播流并推送(可以边直播边保存)
rtmp、flv这两种是web领域主流的直播协议,flv和hls是主流点播协议;使用rtp或rtsp协议的一般都是局域网监控设备。
流媒体协议选择:rtmp基于tcp协议,rtmp能够保持1-3秒左右延迟,flv等同于rtmp。hls(m3u8)是基于http协议,实时性特别差(苹果在设计这套协议的时候本来就不是用来作为直播流的,苹果官方也是推荐hls作为点播协议),想要用hls保证实时性是很难的,虽然可以把每个ts切的很小,但是每个ts的请求解析也是要耗时的,还有切ts分片本身也耗时耗资源,而且对硬盘要求也很高,大量碎片文件会让硬盘吃不消)。
实时性要求特高的,建议使用基于udp协议的一些流媒体协议,比如国内几家直播平台会自己定义一套udp私有协议流。
基于tcp和udp两种流媒体协议区别就是tcp会强制同步,udp是数据发出去就不管了。
所以最终的方案就是:强同步但是实时性要求不高用基于tcp协议的,强实时性弱同步就udp。外网尽量不用rtsp,丢包率高的让人瘆得慌,现在国内主流直播方案是:flv(首选)>rtmp>udp私有协议>hls,如果是点播则是hls>flv>mp4。
补充:nginx-rtmp流媒体服务器搭建实例:http://blog.youkuaiyun.com/eguid_1/article/details/51749830
nginx-rtmp配置指令详细含义和用法:http://blog.youkuaiyun.com/eguid_1/article/details/51821297
四、播放端(收流端)
直播:通过flex(flash)播放器或者第三方播放器(videoJS,ckplayer,VideoLAN 等...)调用流媒体服务器的流媒体源解码并播放,如果不需要兼容低版本IE,可以采用HTML5的webSocket播放器,videoJS是flash/html5双核播放器。
视频:通过html自带播放器、flex(flash)播放器或者第三方播放器(videoJS,ckplayer,VideoLAN 等...)进行播放
一般使用videoLAN播放器作为测试工具,用于测试音视频流发布状况
补充:
1、如果是采用nginx服务器,它提供的rtmp模块可以发布rtmp直播、录播及hls,nginx可以把ffmpeg整合进去方流媒体后期处理(加水印等)。
2、java是可以调用ffmpeg的,通过jni的方式有两种方法:
2.1、javaCV一直在更新,作者是deeplearning4j的成员,JavaCV已经更新到了1.5x版本,支持通过javacpp调用ffmpeg,javaCV目前整合了几十种流媒体处理框架,是跨平台的强大流媒体处理利器
2.2、javaAV(目前最新0.7,release最新0.5)提供了对java调用ffmpeg的支持,当前已停止更新
补充:为什么没有基于原生java(或者说自带GC的语言)的流媒体框架,原因来自GC,也就是java引以为豪的自动垃圾回收机制(真的是成也萧何,败也萧何)
为什么呢?
大家知道,直播(顾名思义,实时视频转发),这种实时性项目会产生大量的对象,这样会导致两种情况:
1、产生大量对象后占据的内存资源得不到及时释放,于是虚拟机内存溢出。
2、产生大量对象导致GC满负荷运行进行资源回收,会严重占用系统资源,导致系统运行迟滞,影响系统运行性能和实时性等等。