springboot实现rtsp视频推流的示例代码
更新时间:2025年07月13日 10:49:23 作者:程序员阿明
本文指导通过Docker搭建RTSP服务,配置Maven依赖,创建RtspStreamer类并测试流地址rtsp://localhost:8554/live的实现过程,感兴趣的可以了解一下
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;
import 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.setVideoBitrate(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 java.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视频推流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
相关文章
SpringMVC框架使用 Apache POI实现导出Excel
Excel 作为最常用的数据处理工具之一,经常被用来存储和展示数据,本文将介绍如何在 SpringMVC 框架中使用 Apache POI 库来实现 Excel 文件的导出功能,有需要的可以参考一下2025-04-04
Mybatis-plus与Mybatis依赖冲突问题解决方法
,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧这篇文章主要介绍了Mybatis-plus与Mybatis依赖冲突问题解决方法2021-04-04
springboot+vue前后端分离项目中使用jwt实现登录认证
本文介绍了如何在SpringBoot+Vue前后端分离的项目中使用JWT实现登录认证,内容包括后端的响应工具类、JWT工具类、登录用户实体类、登录接口、测试接口、过滤器、启动类以及前端的登录页面实现,感兴趣的可以了解一下2024-10-10
Spring中的ContextLoaderListener详细解析
这篇文章主要介绍了Spring中的ContextLoaderListener详细解析,在web容器即Tomact容器启动web应用即servlet应用时,会触发ServletContextEvent时间,这个事件会被ServletContextListener监听,需要的朋友可以参考下2023-12-12
一文带你搞懂Java中Synchronized和Lock的原理与使用
这篇文章主要为大家详细介绍了Java中Synchronized和Lock的原理与使用,文中的示例代码讲解详细,对我们学习Java有一定的帮助,需要的可以参考一下2023-04-04


最新评论