文章
问答
冒泡
基于JavaCV向Zlmediakit推送rtsp流

前言

最近要实现将相机返回的照片合并成视频流并推送的功能,目前的话是通过JavaCV来实现对图片的合并以及推流,流媒体服务器选择Zlmediakit,一款基于C++的高性能流媒体服务器。

1. Zlmediakit搭建

官方提供docker镜像可以直接docker部署,就是需要注意把配置文件拷贝出来,方便修改
我是在Ubuntu22.04上部署的,参考指令如下:

# 创建 zlmediakit 目录
sudo mkdir -p /home/docker/zlmediakit 
sudo chmod 777 /home/docker/zlmediakit

# 先拉取镜像并运行 zlmediakit
sudo docker run -id -p 1935:1935 -p 8080:80 -p 8443:443 \
-p 8554:554 -p 10000:10000 -p 10000:10000/udp \
-p 8000:8000/udp -p 9000:9000/udp \
--name zlmediakit \
zlmediakit/zlmediakit:master

# 复制 zlmediakit 容器文件到指定目录
sudo docker cp -a zlmediakit:/opt/media /home/docker/zlmediakit

# 删除 zlmediakit 容器
sudo docker rm -f zlmediakit

# 自定义修改/home/docker/zlmediakit/media/conf/config.ini文件

# 重新创建容器并挂载自定义的配置
sudo docker run -id -p 1935:1935 -p 8080:80 -p 8443:443 \
-p 8554:554 -p 10000:10000 -p 10000:10000/udp \
-p 8000:8000/udp -p 9000:9000/udp \
--name zlmediakit \
-v /home/docker/zlmediakit/media/bin:/opt/media/bin \
-v /home/docker/zlmediakit/media/conf:/opt/media/conf \
zlmediakit/zlmediakit:master

2. JavaCV的demo代码

添加Maven依赖,整体jar包比较大需要耐心下载

<dependency>
  <groupId>org.bytedeco</groupId>
  <artifactId>javacv-platform</artifactId>
  <version>1.5.9</version>
</dependency>

demo代码,读取文件夹下的图片转成Frame对象并推流到流媒体服务器

这里推流的地址是:rtsp://192.168.10.80:8554/live/1

这里需要注意rtsp默认的端口号是554,默认端口号是不用加的,但是我用docker部署把554端口映射成了8554,这边必须要加上才行

package com.example;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FFmpegLogCallback;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;

public class RtspPusherDemo {
    public static void main(String[] args) {
        String imageDirectory = "D:\\temp\\images"; // 图片文件夹路径
        String rtspUrl = "rtsp://192.168.10.80:8554/live/1";

        FFmpegLogCallback.set(); //打印ffmpeg的日志

        int frameRate = 30; // 视频帧率
        int imageWidth = 384; // 图片宽度
        int imageHeight = 283; // 图片高度

        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(rtspUrl, imageWidth, imageHeight);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.setFormat("rtsp");
        recorder.setFrameRate(frameRate);
        recorder.setOption("rtsp_transport", "tcp"); // 设置 RTSP 传输协议为 TCP

        try {
            recorder.start();

            Frame capturedFrame = null;
            Java2DFrameConverter converter = new Java2DFrameConverter();

            File imageFolder = new File(imageDirectory);
            File[] imageFiles = imageFolder.listFiles();
            while (true) {
                for (File imageFile : imageFiles) {
                    if (imageFile.isFile()) {
                        BufferedImage image = ImageIO.read(new FileInputStream(imageFile.getAbsolutePath()));
                        capturedFrame = converter.getFrame(image);
                        recorder.record(capturedFrame);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行后用vlc播放器拉取流

拉流地址是:rtsp://192.168.10.80:8554/live/1

javacv
ffmpeg

关于作者

TimothyC
天不造人上之人,亦不造人下之人
获得点赞
文章被阅读