前言

javacv开发包是用于支持java多媒体开发的一套开发包,可以适用于本地多媒体(音视频)调用以及音视频,图片等文件后期操作(图片修改,音视频解码剪辑等等功能),这里只使用javacv来实现一些简单的功能,具体到项目中还需要大家自己磨合

重要:

建议使用最新javaCV1.5版本,该版本已解决更早版本中已发现的大部分bug     --博主目前使用的  javaCV1.5.4

javacv系列文章使用6个jar包:

javacv.jar,javacpp.jar,ffmpeg.jar,ffmpeg-系统平台.jar,opencv.jar,opencv-系统平台.jar。

其中ffmpeg-系统平台.jar,opencv-系统平台.jar中的系统平台根据开发环境或者测试部署环境自行更改为对应的jar包,比如windows7 64位系统替换为ffmpeg-x86-x64.jar

为什么要这样做:因为ffmpeg-系统平台.jar中存放的是c/c++本地so/dll库,而ffmpeg.jar就是使用javacpp封装的对应本地库java接口的实现,而javacpp就是基于jni的一个功能性封装包,方便实现jni,javacv.jar就是对9个视觉库进行了二次封装,但是实现的功能有限,所以建议新手先熟悉openCV和ffmpeg这两个C/C++库的API后再来看javaCV思路就会很清晰了。

上一章简单的介绍了 将远程的rtsp视频流录制保存成本地视频文件:javacv-03:录制流媒体服务器的rtsp/rtmp视频内容,保存为本地视频文件

下面将介绍如何 实时转发rtsp视频流至内网rtmp流媒体服务器:

1、依赖配置说明

maven和gradle方式如果想要减小依赖包大小,则需要手动进行排除不需要的平台依赖即可

(注意:从其他地方下载的依赖包请积极开心的替换为官方jar包和博主提供jar包;如果使用其他jar包版本而导致出错,不要急着找博主问为啥会报错,先把jar包替换了再试试看)

(1)使用maven添加依赖

  1. <dependency>
  2. <groupId>org.bytedeco</groupId>
  3. <artifactId>javacv-platform</artifactId>
  4. <version>1.5.4</version>
  5. </dependency>

(2)使用gradle添加依赖

  1. dependencies {
  2. compile group: 'org.bytedeco', name: 'javacv-platform', version: '1.4.4'
  3. }

(3)使用本地jar包方式

最新版实在太大,需要下载全量包的请到官方github.com/bytedeco/javacv下载

注:博主不太赞同使用这种方式!!!(但还是进行了相关介绍)

jar包使用须知:

1、windows x64平台用到的opencv依赖:opencv.jar;oepncv-windows-x86_64.jar(其他平台替换为对应的jar包即可)

2、苹果mac需要opencv-macosx-x86_64.jar 3、linux平台需要:opencv-linux-x86_64.jar  

4、安卓平台arm架构的需要opencv-android-arm.jar ,基于x86的需要opencv-android-x86.jar

2、为什么不需要安装opencv?

从javacv0.8开始,已经不需要本地安装opencv,直接通过引用opencv对应的系统平台的引用包即可。

(比如oepncv-windows-x86_64.jar就是典型的64位windows环境依赖包)

3、代码实现 

import javax.swing.JFrame;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.FrameRecorder;
import org.bytedeco.javacv.FrameGrabber.Exception;

/**
 * 最大的问题是:远程的rtmp流会出现延迟和丢包的情况 !
 * 
 * 
 * @author xiaoyutongxue6
 * @date 2021-03-11 
 */
public class SaveRecordRemote {

    public static void main(String[] args)
            throws Exception, org.bytedeco.javacv.FrameRecorder.Exception, InterruptedException {
        String inputFile = "rtsp://xxx";
        String outputFile = "rtmp://xxx"; 
        recordPush(inputFile, outputFile, 25);
    }

    public static void recordPush(String inputFile, String outputFile, int v_rs)
            throws Exception, org.bytedeco.javacv.FrameRecorder.Exception, InterruptedException {
        FrameGrabber grabber = new FFmpegFrameGrabber(inputFile);
        // FrameGrabber grabber = FrameGrabber.createDefault(0);
        grabber.setOption("rtsp_transport", "tcp");// 设置成TCP连接,网络会稳定很多,默认使用的是UDP
        try {
            grabber.start();
        } catch (Exception e) {
            throw e;
        }

        FrameRecorder recorder = FrameRecorder.createDefault(outputFile, 1280, 720);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 转码过程,如果不进行转码,则没有办法推送到远程rtmp
        recorder.setFormat("flv");
        recorder.setFrameRate(v_rs); // 设置最低视频帧率,最低25(即每秒25张图片,低于25就会出现闪屏)
        recorder.setGopSize(v_rs);
        // 该代码必须设置声频的通道,不然出报错
        recorder.setAudioChannels(1);
        try {
            recorder.start();
        } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
            e.printStackTrace();
            System.out.println("录制器启动失败");
        }

        // 本地预览
        CanvasFrame cFrame = new CanvasFrame("欢迎来到直播间", CanvasFrame.getDefaultGamma() / grabber.getGamma());
        cFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cFrame.setAlwaysOnTop(true);
        Frame frame = null;
        while ((frame = grabber.grab()) != null) {
            if (cFrame.isVisible()) {
                cFrame.showImage(frame);
            }
            recorder.setTimestamp(frame.timestamp);
            recorder.record(frame);
        }

        cFrame.dispose();
        recorder.close();
        grabber.close();
    }
}

至此,代码已经可以成功运行,在main函数中填写远程提供的rtsp视频流地址,并填写自己搭建的流媒体服务器地址(rtmp):远程直播时则可以通过VLC软件进行观看。  流媒体服务器的搭建可以参考:从零开始搭建流媒体服务器

注:此次代码是基于vscode编辑器进行开发,使用起来很是方便,也是轻量级的;jdk版本为1.8。