1、搭建rtsp服务(docker方式)
docker pull aler9/rtsp-simple-server
docker run -d --restart=always \ --name rtsp-server \ -p 8554:8554 \ aler9/rtsp-simple-server
2、maven依赖
<dependency> <groupId>org.bytedeco</groupId> <artifactId>Javacv-platform</artifactId> <version>1.5.11</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg-platform</artifactId> <version>7.1-1.5.11</version> </dependency>
3、新建RtspStreamer服务类
package com.example.superior_conjuncte_iot_rtspvideo.system_config.config; import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.bytedeco.ffmpeg.global.avcodec; import org.bytedeco.ffmpeg.global.avutil; impythonport org.bytedeco.javacpp.Loader; import org.bytedeco.javacv.FFmpegFrameRecorder; import org.bytedeco.javacv.FFmpegLogCallback; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter; import org.springframework.stereotype.Component; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.util.Base64; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @Component @Slf4j public class RtspStreamer { static { FFmpegLogCallback.set(); // 强制加载 FFmpeg 核心库 Loader.load(org.bytedeco.ffmpeg.global.avutil.class); Loader.load(org.bytedeco.ffmpeg.global.avcodec.class); Loader.load(org.bytedeco.ffmpeg.global.avformat.class); } private FFmpegFrameRecorder recorder; private ExecutorService executor = Executors.newSingleThreadExecutor(); private final Java2DFrameConverter converter = new Java2DFrameConverter(); /** * 启动 RTSP 流服务 * @param rtspUrl 例如: "rtsp://localhost:8554/live" * @param width 视频宽度 * @param height 视频高度 */ public void startStream(String rtspUrl, int width, int height) { 编程 try { recorder = new FFmpegFrameRecorder(rtspUrl, width, height); recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); recorder.setFormat("rtsp"); recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); recorder.setFrameRate(30); recorder.phpsetVideoBitrate(2_000_000); // 码率设为 2Mbps recorder.setVideoOption("preset", "medium"); recorder.setVideoOption("tune", "zerolatency"); recorder.setVideoOption("g", "30"); recorder.start(); } catch (Exception e) { log.error("启动 RTSP 失败"+e.getMessage()); throw new RuntimeException("启动 RTSP 失败", e); } } /** * 推送视频帧 * @param image 视频帧图像 */ public void pushFrame(BufferedImage image) { executor.submit(() -> { try { //转换格式 BufferedImage bgrImage = convertToBGR(image); Frame frame = converter.getFrame(bgrImage); recorder.record(frame); } catch (Exception e) { log.error("推送视频帧失败"+e.getMessage()); e.printStackTrace(); } }); } //转换格式,很关键 private BufferedImage convertToBGR(BufferedImage image) { BufferedImage bgrImage = new BufferedImage( image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR ); bgrImage.getGraphics().drawImage(image, 0, 0, null); return bgrImage; } @PreDestroy public void stopStream() { if (recorder != null) { try { recorder.stop(); recorder.release(); } catch (Exception e) { log.error("停止 RTSP 失败"+e.getMessage()); } } executor.shutdown(); } //字符串视频流解码 public BufferedImage getBufferedImage(String base64Image){ try { byte[] imageBytes = Base64.getDecoder().decode(base64Image); BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes)); return image; }catch (Exception ex){ log.error("视频解码错误"); return null; } } }
4、测试代码
package com.example.superior_conjuncte_iot_web.tj.project_video.service.impl; import com.example.superior_conjuncte_iot_web.system_config.videoConfig.RtspStreamer; import com.example.superior_conjuncte_iot_web.tj.project_video.service.IVideoRtspService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import java.awt.*; import j编程客栈ava.awt.image.BufferedImage; @Service @Slf4j public class VideoRtspServiceImpl implements IVideoRtspService, ApplicationRunner { @Resource @Lazy private RtspStreamer rtspStreamer; @Override public void run(ApplicationArguments args) { rtspStreamer.startStream("rtsp://localhost:8554/live", 640, 480); // 模拟生成视频帧(例如从摄像头或文件读取) Thread thread=new Thread(() -> { while (true) { BufferedImage image = generateTestFrame(); // 生成测试帧 rtspStreamer.pushFrame(image); try { Thread.sleep(33); // 约30帧/秒 } catch (InterruptedException e) { e.printStackTrace(); } } }); thread.setDaemon(true); thread.start(); } // 生成测试帧(渐变颜色) private BufferedImage generateTestFrame() { BufferedImage img = new BufferedImage(640, 480, BufferedImage.TYPE_3BYTE_BGR); Graphics2D g2d = img.createGraphics(); g2d.setColor(new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255))); g2d.fillRect(0, 0, 640, 480); g2d.dispose(); return img; } }
5、用VLC工具测试
测编程客栈试地址:rtsp://localhost:8554/live,其中localhost:8554为rtsp服务器的地址到此这篇关于springboot实现rtsp视频推流的示例代码的文章就介绍到这了,更多相关springboot rtsp视频推流内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论