📌 本文解决的核心问题

如何将传统监控场景中的RTSP视频流转换为浏览器可直接播放的HLS流?

  • ✅ FFmpeg转码参数深度解析
  • ✅ Nginx流媒体服务器配置技巧
  • ✅ 前端播放器无缝对接方案
  • ✅ 生产环境进程守护方法
  • 🔥 高频问题排查指南

一、方案一:FFmpeg转HLS方案(推荐)

步骤一:创建视频控制器

// 在controller包下新建VideoController.java
@RestController
@RequestMapping("/video")
public class VideoController {
    
    @Autowired
    private VideoStreamService videoStreamService;

    // 启动转码并获取播放地址
    @GetMapping("/start/{streamId}")
    public ResponseEntity<String> startStream(@PathVariable String streamId) {
        String hlsPath = videoStreamService.convertRtspToHls("rtsp://your_stream_url", "/hls_output");
        return ResponseEntity.ok("/video/play/" + streamId);
    }

    // 播放HLS流
    @GetMapping("/play/{streamId}")
    public ResponseEntity<Resource> playStream(@PathVariable String streamId) {
        Resource resource = new FileSystemResource("/hls_output/stream.m3u8");
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"stream.m3u8\"")
                .body(resource);
    }
}

步骤二:创建转码服务类

// 新建service/VideoStreamService.java
@Service
public class VideoStreamService {
    
    public String convertRtspToHls(String rtspUrl, String outputDir) {
        try {
            String command = String.format(
                "ffmpeg -i %s -c:v libx264 -c:a aac -f hls -hls_time 4 -hls_list_size 6 %s/stream.m3u8",
                rtspUrl, outputDir
            );
            
            Process process = Runtime.getRuntime().exec(command);
            // 建议添加线程管理处理
            return outputDir;
        } catch (IOException e) {
            throw new RuntimeException("转码失败", e);
        }
    }
}

 步骤三:配置静态资源访问(在WebConfiguration添加)

// 在WebConfiguration类中添加
@Bean
WebMvcConfigurer webMvcConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/hls_output/**")
                    .addResourceLocations("file:/hls_output/")
                    .setCachePeriod(0);
        }
    };
}

 步骤四:前端播放器页面(新建resources/static/player.html)

<!DOCTYPE html>
<html>
<body>
    <video id="video" controls width="640" height="480"></video>
    
    <script src="https://cdn.jsdelivr.net/npm/hls.js@1.1.4"></script>
    <script>
        const video = document.getElementById('video');
        const hlsUrl = '/video/play/your_stream_id';

        if (Hls.isSupported()) {
            const hls = new Hls();
            hls.loadSource(hlsUrl);
            hls.attachMedia(video);
            hls.on(Hls.Events.MANIFEST_PARSED, () => video.play());
        } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
            video.src = hlsUrl;
            video.addEventListener('loadedmetadata', () => video.play());
        }
    </script>
</body>
</html>

部署注意事项
安装FFmpeg:确保服务器已安装FFmpeg(apt install ffmpeg)
创建输出目录:在项目根目录创建/hls_output目录
安全加固:

   // 在VideoStreamService中添加白名单验证
   private static final List<String> ALLOWED_STREAMS = List.of(
       "rtsp://trusted_source_1",
       "rtsp://trusted_source_2"
   );

   public String convertRtspToHls(String rtspUrl, String outputDir) {
       if (!ALLOWED_STREAMS.contains(rtspUrl)) {
           throw new IllegalArgumentException("非法的视频源地址");
       }
       // ...原有代码...
   }
   

 调用流程:

  1. 访问 http://localhost:8080/player.html
  2. 前端自动请求 /video/start/stream1
  3. 后端启动转码并返回播放地址
  4. Hls.js自动加载/video/play/stream1的m3u8文件

需要根据实际RTSP地址调整代码中的rtsp://your_stream_url,并确保防火墙开放相应端口。

    一、环境准备(XShell连接)

    1、 服务器连接步骤

    1.1
    1. **新建会话**  
       - 主机:`你的公网IP`(示例:123.123.123.123)
       - 端口:`22`(SSH默认端口)
       - 认证方式:选择Password验证
       
    2. **连接配置**  
       ```plaintext
       ➤ 用户名:root(或具有sudo权限的用户)
       ➤ 密码:*********

    Tips:建议使用密钥对认证更安全

    1.2  安装 FFmpeg
    FFmpeg 用于将 RTSP 流转换为 HLS 格式。

    • 下载并安装 FFmpeg:FFmpeg 官网
    • 验证安装:
        ffmpeg -version
        

    1.3 安装 Nginx
    Nginx 用于作为 HLS 流媒体服务器。

    • 下载并安装 Nginx:Nginx 官网
    • 验证安装 
        nginx -v
        

    2、将 RTSP 流转换为 HLS
    2.1 创建 HLS 输出目录
    在服务器上创建一个目录用于存放 HLS 文件:

    mkdir /path/to/hls/files
    

     2.2 使用 FFmpeg 转换 RTSP 流
    运行以下命令将 RTSP 流转换为 HLS 格式

    ffmpeg -i rtsp://your_rtsp_url -c:v copy -c:a copy -f hls -hls_time 2 -hls_list_size 3 -hls_flags delete_segments /path/to/hls/files/stream.m3u8
    
    • rtsp://your_rtsp_url:替换为实际的 RTSP 流地址。
    • /path/to/hls/files/stream.m3u8:HLS 文件的输出路径。
    • -hls_time 2:每个分片的时长(秒)。
    • -hls_list_size 3:保留的分片数量。
    • -hls_flags delete_segments:自动删除旧分片。

    2.3 多路流处理
    如果需要处理多个 RTSP 流,可以为每个流生成独立的 HLS 文件: 

    ffmpeg -i rtsp://stream1_url -c:v copy -c:a copy -f hls -hls_time 2 -hls_list_size 3 -hls_flags delete_segments /path/to/hls/files/stream1.m3u8
    ffmpeg -i rtsp://stream2_url -c:v copy -c:a copy -f hls -hls_time 2 -hls_list_size 3 -hls_flags delete_segments /path/to/hls/files/stream2.m3u8
    

    二、FFmpeg安装与转码实战

    2.1 跨平台安装指南

    # Ubuntu/Debian 系
    sudo apt update && sudo apt install ffmpeg -y
    
    # CentOS/RHEL 系
    sudo yum install epel-release -y
    sudo yum install ffmpeg ffmpeg-devel -y
    

    2.2 转码参数详解

    ffmpeg -rtsp_transport tcp -i "rtsp://your_stream_url" \
           -c:v copy -c:a aac -b:a 128k \
           -f hls \
           -hls_time 4 \
           -hls_list_size 10 \
           -hls_flags delete_segments \
           -hls_segment_filename "/output/path/stream_%03d.ts" \
           /output/path/stream.m3u8
    
    🛠️ 关键参数解析表
    参数 作用 推荐值
    -rtsp_transport tcp 强制TCP传输防丢包 必选
    -hls_time TS分片时长(秒) 2-6
    -hls_list_size 播放列表保留分片数 ≥5
    -hls_flags delete_segments 自动清理旧分片 建议开启

    三、Nginx流媒体服务配置

    3.1 服务安装与启停

    # Ubuntu
    sudo apt install nginx -y
    sudo systemctl enable nginx
    
    # CentOS
    sudo yum install nginx -y
    sudo systemctl start nginx
    

    3.2 核心配置模板

    server {
        listen 80;
        server_name your_domain_or_ip;
    
        location /hls {
            alias /path/to/hls_output; # 指向HLS生成目录
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            add_header Cache-Control no-cache; # 禁用缓存
            add_header Access-Control-Allow-Origin *; # 跨域支持
        }
    }
    
    🔍 配置验证命令
    sudo nginx -t          # 检查配置语法
    sudo systemctl reload nginx  # 热重载配置
    

    四、前端播放器集成

    4.1 播放器HTML代码

    <!DOCTYPE html>
    <html>
    <head>
        <title>HLS实时播放器</title>
        <link href="//unpkg.com/video.js/dist/video-js.min.css" rel="stylesheet">
    </head>
    <body>
        <video id="hls-player" class="video-js" controls width="1280" height="720">
            <source src="http://your_server/hls/stream.m3u8" type="application/x-mpegURL">
        </video>
        
        <script src="//unpkg.com/video.js/dist/video.min.js"></script>
        <script src="//cdn.jsdelivr.net/npm/hls.js@latest"></script>
        <script>
            const player = videojs('hls-player', {
                html5: {
                    hls: {
                        overrideNative: true
                    }
                }
            });
        </script>
    </body>
    </html>
    

    五、生产环境进程守护

    5.1 Systemd服务配置

    # /etc/systemd/system/rtsp2hls.service
    [Unit]
    Description=RTSP to HLS Transcoding Service
    After=network.target
    
    [Service]
    User=root
    ExecStart=/usr/bin/ffmpeg -rtsp_transport tcp -i "rtsp://your_stream" -c:v copy -c:a aac -f hls -hls_time 4 -hls_list_size 10 -hls_flags delete_segments -hls_segment_filename "/path/stream_%%03d.ts" /path/stream.m3u8
    Restart=always
    RestartSec=30
    
    [Install]
    WantedBy=multi-user.target
    
    服务管理命令
    sudo systemctl daemon-reload
    sudo systemctl start rtsp2hls
    sudo systemctl enable rtsp2hls
    

    🚨 高频问题排查指南

    Q1: 播放器显示加载但无画面

    • 检查项:
      1. ffmpeg进程是否存活:ps aux | grep ffmpeg
      2. Nginx目录权限:sudo chown -R www-data:www-data /output/path
      3. 防火墙状态:sudo ufw allow 80/tcp

    Q2: TS文件无法下载

    • 快速诊断:
      curl -I http://localhost/hls/stream.m3u8  # 查看HTTP状态码
      tail -f /var/log/nginx/error.log         # 实时监控错误日志
      

    Q3: 流延迟过高

    • 优化方案:
      -hls_time 2              # 缩短分片时长
      -preset ultrafast        # 启用快速编码预设
      -tune zerolatency        # 超低延迟调优
      

    六、效果验证

    访问测试地址:http://your_server/player.html
    成功效果:
    ✅ 实时视频流畅播放
    ✅ 控制台无报错信息
    ✅ 网络请求可见连续.ts文件加载


    技术总结:通过本方案,我们实现了:

    • 🛡️ 浏览器免插件播放RTSP流
    • ⚡ 转码服务异常自动恢复
    • 📈 支持高并发访问的分布式架构基础

    资料下载
    示例配置文件下载https://example.com/config.zip
    FFmpeg参数速查表https://example.com/ffmpeg-cheatsheet.pdf

    注意:具体项目视情况而定,非直接搬运!!!

    问题交流:欢迎在评论区留言讨论遇到的部署问题!✍️

    Logo

    火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

    更多推荐