VUE3+javaCV实现长时间录制视频

目录

需求

实现

        前端播放海康摄像头的画面

        录制视频

        方法一:HTMLVideoElement(废弃)

        方法二:HTMLCanvasElement(废弃)

        方法三:javaCV

代码

问题

需求

        前端接收webrtc-streamer从rtsp转换来的hls流

        点击开始按钮开始录制一段时间

        点击停止按钮停止录制

        点击上传将视频存放到服务器

实现

        前端播放海康摄像头的画面

        由于监控设备多采用rtsp流传输视频,但H5无法接收该类型的视频流,使用webrtc-streamer进行转流播放

        录制视频
        方法一:HTMLVideoElement(废弃)

        1、使用HTMLVideoElement的caputure捕捉video组件中正在播放的视频流

        2、将视频流放入列表

        3、将列表转换成blob数据类型

        4、使用axios将存储的blob数据传向后端

        5、后端接收blob数据存储到磁盘中,并将路径存储数据库

        弊端:传统html可实现,vue3适配的ts格式的HTMLElement还未提供HTMLVideoElement.captureStreamer方法

        方法二:HTMLCanvasElement(废弃)

        1、使用video组件播放视频

        2、将video绘制到canvas

        3、捕捉canvas媒体流

        4、使用axios将存储的blob数据传向后端

        5、后端接收blob数据存储到磁盘中,并将路径存储数据库

        弊端:将video绘制到canvas,然后捕捉canvas的媒体流,适用于秒级的录制

        方法三:javaCV

        1、前端获取时间戳与任务信息传向后端

        2、后端使用javaCV拉取rtsp流,读取帧,根据时间戳记录角度帧

        好处:适合长时间存储视频

代码

public class SceneService {
    private volatile boolean stopFlag = false;
    private volatile String videoPath;
    private final SceneMapper sceneMapper;
    private FFmpegFrameGrabber grabber;
    private FFmpegFrameRecorder videoWriter;
    private Thread videoThread;
    @Autowired
    public SceneService(SceneMapper sceneMapper){
        this.sceneMapper = sceneMapper;
    }
    public void recordVideo(String taskName){
        // 设置rtsp流地址
        String rtspUrl = "rtsp://你的用户名:你的密码@127.0.0.1:8554/stream";
        // 设置保存路径
        String rootDir = "E:\\ProgramSoftware\\java\\AIDetectCloudPlatform\\recordVideo";
        String fileName = taskName + ".mp4";
        this.videoPath = Paths.get(rootDir, fileName).toString();
        // 使用FFmpegFrameGrabber 类拉取rtsp流
        try {
            grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
            // 禁用音频
            grabber.setOption("rtsp_transport", "tcp");
            grabber.start();

            System.out.println("开始拉流");
            // 设置视频读取器
            int width = grabber.getImageWidth();
            int height = grabber.getImageHeight();
            videoWriter = new FFmpegFrameRecorder(this.videoPath, width, height);
            videoWriter.setFormat("mp4");
            videoWriter.setAudioChannels(2);
            videoWriter.start();
            System.out.println("开始记录");
            // 创建新的线程来处理循环
            this.videoThread = new Thread(() -> {
                try {
                    while (!this.videoThread.isInterrupted() && !this.stopFlag) {
                        Frame frame = grabber.grab();
                        if (frame == null) {
                            System.out.println("记录结束");
                            break;
                        }
                        long currentTimestamp = frame.timestamp;
                        System.out.printf("frame timeStamp %s \n", currentTimestamp);
                        // 向目标地址存储
                        videoWriter.record(frame);
                    }
                    videoWriter.stop();
                    grabber.stop();
                    this.stopFlag = false;
                }catch (Exception e){
                    e.printStackTrace();
                }
            });
            this.videoThread.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void stopRecordVideo(String taskId) {
        this.stopFlag = true;
        // 关闭线程
        if ( this.videoThread != null && this.videoThread.isAlive()) {
            System.out.println("记录结束");
            this.videoThread.interrupt();
        }
        // 将录像与任务关联
        sceneMapper.collectTaskVideo(taskId, this.videoPath);
    }
}

问题

        1、传统html提供了对video组件的媒体流captureStream方法,vue3使用的ts所适配的HTMLELEMNT中的还没有提供直接对video组件提取媒体流的方法

        2、将video重绘到canvas,HTMLELEMENT提供了对canvas的媒体流获取的方法,但是只适用于短时间录制

        3、报错:java.lang.UnsatisfiedLinkError: Could not find jniavutil in class, module, and library paths.

        只引入了javacv依赖还需要引入ffmepg-platform

        VUE3+javaCV实现长时间录制视频_第1张图片

        4、报错:No audio output stream (Is audioChannels > 0 and has start() been called?)

        没有为FFmpegFrameRecorder类的实例对象设置setAudioChannels

你可能感兴趣的:(音视频)