【java】使用javaCV对直播RTSP流实时转码,使用flvjs控件播放

javaCV,计算机视觉领域常用库与程序类

最近由于工作需要接触了直播视频RTSP流转码写出到前端的项目,需要使用其对监控视频RTSP流进行转码才能使用h5控件播放。主要用到的工具为JavaCV封装的FFmpeg,因此不必引入其所有的子依赖。pom文件部分内容如下:

<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>ffmpeg-platform</artifactId>
    <version>4.1.3-1.5.1</version>
</dependency>
<!-- rtsp视频流转码工具 -->
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.5.1</version>
    <!-- 简化依赖,排除不必要的依赖模块 -->
    <exclusions>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>opencv</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>flandmark</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>tesseract</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>leptonica</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>artoolkitplus</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>videoinput</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>librealsense</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>libfreenect</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>libfreenect2</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>libdc1394</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>flycapture</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>openblas</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>ffmpeg</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
        </exclusion>
    </exclusions>
</dependency>

其中platform的依赖可以在打包时选择具体应用的平台,精简依赖项。详情见:

https://github.com/bytedeco/javacpp-presets/wiki/Reducing-the-Number-of-Dependencies

使用FFmpeg抓流

读流器:FFmpegFrameGrabber
可设置参数:

//设置打开协议tcp / udp
grabber.setOption("rtsp_transport", "tcp");
//设置未响应超时时间 0.5秒
grabber.setOption("stimeout", "500000");
//设置缓存大小,提高画质、减少卡顿花屏
//grabber.setOption("buffer_size", "1024000");
//设置视频比例
//grabber.setAspectRatio(1.7777);

打开协议要注意,根据视频流的要求选择。如果是本地生成的RTSP视频流,就不要选择tcp协议了,会报错。(VLC控件可以将本地视频转化为RTSP流)
转码器:FFmpegFrameRecorder

实际工作过程为,后台不断从RTSP流链接读流,然后转码,写新转码的流到前台,前台可通过该长连接请求播放直播视频。

由于是一个耗时的过程,而每个视频又不能等待前面的转码结束后才开始,因此这里我使用了没有阻塞队列的线程池newCachedThreadPool来创建启动转码线程。
当前台每次销毁一个播放视频时,请求一次后台停止对应的视频转码线程。而当用户异常关闭页面、中止请求时,后台也会实时获取状态,停止对应的线程节省空间。

项目相关代码已上传github,注释已写的很清晰:

https://github.com/HolyDogs/RTSP-Video-Flv

有问题可以去官方项目提issues,作者回复很及时:

https://github.com/bytedeco/javacv/issues