Java使用FFmpeg进行推流,SRS进行拉流,实现转码

 因为公司业务需要把监控摄像机的RTSP流放在浏览器上播放,但由于目前浏览器上播放RTSP协议的视频流需要集成插件,插件只能在固定的浏览器版本上使用,缺点比较大,所以想着通过转码的方式实现在浏览器上播放视频流,然后选择了FFmpeg通过RTMP协议将码流推送srs流媒体服务器,使用HTTP-FLV协议拉流播放这种方案,实现浏览器端播放。

以下是客户端拉流播放视频的三种媒流体协议,我这边选取的是HTTP-FLV,RTMP需要借住Flash插件,不建议使用。

1.HLS
HLS 全称是 HTTP Live Streaming。这是 Apple 提出的直播流协议,是通过视频流切片成文件片段来直播的。目前,IOS 和 高版本 Android 都支持 HLS。HLS 主要的两块内容是 .m3u8 文件和 .ts 播放文件。其中 .m3u8 作为索引文件(确保包的顺序)。接受服务器会将接受到的视频流进行缓存,然后缓存到一定程度后,会将这些视频流进行编码格式化,同时会生成一份 .m3u8 文件和其它很多的 .ts 文件。客户端首先会请求一个m3u8文件,里面会有不同码率的流,或者直接是ts文件列表,通过给出的ts文件地址去依次播放。在直播的时候,客户端会不断请求m3u8文件,检查ts列表是否有新的ts切片。这种方式的实时性较差,不过优势是H5、IOS、Android都原生支持。

2.RTMP

全称 Real Time Messaging Protocol,即实时消息传送协议。纯 RTMP 使用 TCP 连接,默认端口为 1935,是 Adobe Systems 公司为 Flash 播放器和服务器之间音频、视频和数据传输开发的开放协议。协议基于 TCP,是一个协议族,包括 RTMP 基本协议及 RTMPT/RTMPS/RTMPE 等多种变种。RTMP 由于借由 TCP 长连接协议,所以,客户端向服务端推流这些操作而言,延时性很低。它会将上传的流分成不同的分片,这些分片的大小,有时候变,有时候不会变。默认情况下就是,64B 的音频数据 + 128B 的视频数据 + 其它数据(比如 头,协议标签等)。但 RTMP 具体传输的时候,会将分片进一步划分为包,即,视频包,音频包,协议包等。因为,RTMP 在进行传输的时候,会建立不同的通道,来进行数据的传输,这样对于不同的资源,对不同的通道设置相关的带宽上限。RTMP 是一种设计用来进行实时数据通信的网络协议,主要用来在 Flash/AIR 平台和支持 RTMP 协议的流媒体/交互服务器之间进行音视频和数据通信。这种方式的实时性比较强,基本能保证延迟在 1-2s 内,是现在国内直播主要采用的方式之一。不过使用这种协议,就必须安装 flash,而 H5、IOS、Android 并不能原生支持 flash,因此这种协议能流行多久,就不得而知了。


3.HTTP-FLV
HTTP-FLV 就是对 RTMP 协议的封装,都是针对于 FLV 视频格式做的直播分发流。相比于 RTMP,它是一个开放的协议,因此他具备了 RTMP 的实时性和 RTMP 不具备的开发性。而且随着 flv.js 的出现,使得浏览器在不依赖 flash 的情况下,播放 flv 视频,从而兼容了移动端,所以现在很多直播平台,尤其是手机直播平台,都会选择它。因为 RTMP 发的包很容易处理,通常 RTMP 协议会作为视频上传端来处理,然后经由服务器转换为 FLV 文件,通过 HTTP-FLV 下发给用户。

SRS 是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT协议

需要的小伙伴可以从百度网盘中下载,里面包含了SRS包,Ffmpeg包,以及Ffmpeg所需要用到的类库包

链接:https://pan.baidu.com/s/1vftY_dzu4IQ2eY-Yuw4sJw?pwd=uqlg 
提取码:uqlg

1.在Liunx上编译安装SRS流媒体服务器

注:以配置文件方式启动的话,启动, 查看状态,停止,重启,查看日志都必须要到trunk目录下

#解压srs压缩包
unzip srs-4.0release.zip

#进入srs文件夹中的trunk目录下
cd srs-4.0release/trunk

​​​#使用配置文件srs.conf启动
./objs/srs -c conf/srs.conf
 
# 查看SRS的状态
./etc/init.d/srs status
 
#停止SRS
./etc/init.d/srs stop
 
#重启SRS
./etc/init.d/srs restart
 
# 或者看SRS的日志
tail -n 30 -f ./objs/srs.log

打开浏览器可以访问,有个控制台页面

http://192.168.13.170:8080/

SRS默认端口为8080 也可以在turnk目录下的conf目录下修改默认端口

修改完成之后重启SRS

#重启SRS
./etc/init.d/srs restart

进入SRS控制台

 

 

 2.编译安装FFmpeg

FFmpeg是一套由c语言编写的,可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序,自身采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案,包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

#需要在有互联网的机器上下载FFmpeg和对应的依赖库包。您可以在这个网站上下载
https://pkgs.org/download/ffmpeg。下载的文件包括FFmpeg源代码(ffmpeg-5.5.)、zlib-devel12.7-18.el7.x86_64.rpm)、freetype(freetype-devel-2.8-14.el7.x86_64.rpm)、x264(x264-devel-0.148-1.el7_4.1.x86_64.rpm)、x265(x265-devel-2.6-1.el7.x86_64.rpm)和opus(opus-devel-1.3-0.el7.x86_64.rpm)。通过USB、CD或其他传输介质将这些文件复制到没有互联网的CentOS 7系统上。

#下载的包复制到CentOS 7系统上,然后使用以下命令安装它们
yum local-.2.7-18.el7.x86_64.rpm freetype-devel-2.8-14.el7.x86_64.rpm x264-devel-0.148-1.el7_4.1.x86_64.rpm x265-devel-2.6-1.el7.x86_64.rpm opus-devel-1.3-0.el7.x86_64.rpm。

#解压下载的FFmpeg源代码包
tar -xf ffmpeg-5.5.1.tar.bz2。

#进入解压后的FFmpeg源代码目录
cd ffmpeg-5.5.1。

#配置编译参数:
./configure --prefix=/usr/local/ffmpeg --enable-shared --enable-gpl --enable-libx264 --enable-libx265 --enable-libmp3lame --enable-libopus --enable-libfreetype。

#运行make命令编译FFmpeg
make

#运行make install命令安装FFmpeg
make install。

#配置动态链接库 
"/usr/local/ffmpeg/lib" >> /etc/ld.so.conf.d/ffmpeg.conf && ldconfig

#查看版本是否安装成功 
ffmpeg -version

3.Linux上Java使用ffmpeg推流

{
        /** ffmpeg 命令详解
         *  ffmpeg [[options][`-i’ input_file]] {[options] output_file}
         *  options:
         *   -i: url 输入文件网址
         *   -vcodec: 设置视频编解码器 -codec:v  -c:v
         *   (强制使用codec编解码方式,如-vcodec xvid 使用xvid压缩 如果用copy表示原始编解码数据必须被拷贝)
         *   -acodec: 设置音频编解码器 -codec:a  -c:a
         *   -f: fmt 强制输入或输出文件格式
         */
  }

#推流代码
@Async("asyncTaskExecutor")
    public void plugFlow(String rtspUrl,String myStream) {
        BufferedReader br = null;
        try {
            String basePath = "/usr/local/ffmpeg/bin/";
            String command = basePath + "ffmpeg -re " +
                    "-rtsp_transport tcp " +
                    "-i " + rtspUrl +" "+
                    "-c:v copy -c:a copy -f flv " +
                    "rtmp://127.0.0.1/live/"+myStream;
            log.info("【command】:{}",command);
            log.info("rtmp://127.0.0.1/live/"+myStream);
            Process process = Runtime.getRuntime().exec(command);
            br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line = null;
            while ((line = br.readLine()) != null) {
                log.info("视频推流信息{}", line);
            }
        } catch (Exception e) {
            log.error("ffmpeg推流失败:",e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    log.error("RequestUtil,IOException:",e);
                }
            }
        }
    }

#拉流代码 
@SneakyThrows
public  String getPlayBackUrl(String rtspUrl) {
    String myStream = IdUtil.simpleUUID();
    asynchronization.plugFlow(rtspUrl,myStream);
    return "http://127.0.0.1:8080/live/" + myStream + ".flv";
}

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值