Table of Contents
need
accomplish
The front-end plays the picture of Hikvision camera
Record video
Method 1: HTMLVideoElement (obsolete)
Method 2: HTMLCanvasElement (obsolete)
Method three: javaCV
code
question
Requirement
The front end receives the hls stream converted from rtsp by webrtc-streamer
Click the start button to start recording for a while
Click the Stop button to stop recording
Click Upload to save the video to the server
implementation
Front-end playback of Hikvision camera images
Since surveillance equipment mostly uses rtsp streaming to transmit video, H5 cannot receive this type of video stream, so webrtc-streamer is used for streaming and playback.
Record video
Method 1: HTMLVideoElement (obsolete)
1. Use the caputure of HTMLVideoElement to capture the video stream being played in the video component.
2. Put the video stream into the list
3. Convert the list to blob data type
4. Use axios to transfer the stored blob data to the backend
5. The backend receives the blob data and stores it on the disk, and stores the path in the database.
Disadvantages: Traditional HTML can be implemented, but the HTMLElement in ts format adapted to vue3 does not yet provide the HTMLVideoElement.captureStreamer method.
Method 2: HTMLCanvasElement (obsolete)
1. Use the video component to play videos
2. Draw video to canvas
3. Capture canvas media stream
4. Use axios to transfer the stored blob data to the backend
5. The backend receives the blob data and stores it on the disk, and stores the path in the database.
Disadvantages: Draw the video to the canvas, and then capture the media stream of the canvas, suitable for second-level recording
Method 3: javaCV
1. The front-end obtains the timestamp and task information and transmits them to the back-end
2. The backend uses javaCV to pull the rtsp stream, read the frame, and record the angle frame according to the timestamp.
Benefits: Suitable for long-term video storage
code
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){ //Set rtsp stream address String rtspUrl = "rtsp://your username:your [email protected]:8554/stream"; //Set the save path String rootDir = "E:\ProgramSoftware\java\AIDetectCloudPlatform\recordVideo"; String fileName = taskName + ".mp4"; this.videoPath = Paths.get(rootDir, fileName).toString(); // Use the FFmpegFrameGrabber class to pull the rtsp stream try { grabber = FFmpegFrameGrabber.createDefault(rtspUrl); // disable audio grabber.setOption("rtsp_transport", "tcp"); grabber.start(); System.out.println("Start streaming"); // Set up video reader 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("Start recording"); //Create a new thread to handle the loop this.videoThread = new Thread(() -> { try { while (!this.videoThread.isInterrupted() & amp; & amp; !this.stopFlag) { Frame frame = grabber.grab(); if (frame == null) { System.out.println("End of record"); break; } long currentTimestamp = frame.timestamp; System.out.printf("frame timeStamp %s \ ", currentTimestamp); // Store to target address 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; // Close the thread if ( this.videoThread != null & amp; & amp; this.videoThread.isAlive()) { System.out.println("End of record"); this.videoThread.interrupt(); } //Associate the video with the task sceneMapper.collectTaskVideo(taskId, this.videoPath); } }
Question
1. Traditional HTML provides the media stream captureStream method for the video component. The HTMLELEMNT adapted to the ts used by vue3 does not yet provide a method for directly extracting the media stream from the video component.
2. Redraw the video to the canvas. HTMLELEMENT provides a method to obtain the media stream of the canvas, but it is only suitable for short-term recording.
3. Error: java.lang.UnsatisfiedLinkError: Could not find jniavutil in class, module, and library paths.
Only javacv dependency is introduced, and ffmepg-platform needs to be introduced.
4. Error: No audio output stream (Is audioChannels > 0 and has start() been called?)
setAudioChannels is not set for instance object of FFmpegFrameRecorder class