From cfd0489d3df1afb4e13cfaa13991372a8df5df40 Mon Sep 17 00:00:00 2001 From: 86156 <823267011@qq.com> Date: Wed, 1 Oct 2025 23:12:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/video/device/component/flv.vue | 4 +-- ruoyi-admin/Dockerfile | 4 ++- .../thread/MediaTransferFlvByFFmpeg.java | 27 ++++++++++++++----- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/rtsp-vue/src/views/video/device/component/flv.vue b/rtsp-vue/src/views/video/device/component/flv.vue index 6a74657..395d2a2 100644 --- a/rtsp-vue/src/views/video/device/component/flv.vue +++ b/rtsp-vue/src/views/video/device/component/flv.vue @@ -70,8 +70,8 @@ const getDetails = async (deviceId) => { tableData.value = res.data; // 使用当前访问的域名和端口,通过Nginx代理访问视频流 // 注意:RTSP URL需要原样传递,不要编码,&&&作为特殊分隔符 - // 不使用 ffmpeg=true,让系统自动选择 JavaCV 模式(兼容 HEVC) - playUrl.value = `${window.location.origin}/live?url=${tableData.value.url}`; + // 使用 ffmpeg=true,系统 FFmpeg 包含完整的编码器支持(包括 libx264) + playUrl.value = `${window.location.origin}/live?url=${tableData.value.url}&&&ffmpeg=true`; console.log('播放地址:', playUrl.value); handlePlay(); } diff --git a/ruoyi-admin/Dockerfile b/ruoyi-admin/Dockerfile index 16895ef..11cb7a4 100644 --- a/ruoyi-admin/Dockerfile +++ b/ruoyi-admin/Dockerfile @@ -27,7 +27,7 @@ RUN mvn clean package -DskipTests -Denforcer.skip=true -pl ruoyi-admin -am # 运行阶段 - 使用Debian而不是Alpine以支持JavaCV/FFmpeg FROM eclipse-temurin:17-jre -# 安装必要的工具和JavaCV/FFmpeg完整依赖 +# 安装必要的工具和JavaCV/FFmpeg完整依赖(包含 libx264) RUN apt-get update && apt-get install -y \ curl \ libgomp1 \ @@ -40,6 +40,8 @@ RUN apt-get update && apt-get install -y \ libx11-xcb1 \ libasound2-dev \ ffmpeg \ + libx264-dev \ + libavcodec-extra \ && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo "Asia/Shanghai" > /etc/timezone \ && rm -rf /var/lib/apt/lists/* diff --git a/ruoyi-video/src/main/java/com/ruoyi/video/thread/MediaTransferFlvByFFmpeg.java b/ruoyi-video/src/main/java/com/ruoyi/video/thread/MediaTransferFlvByFFmpeg.java index a6bf1a0..9fe8067 100644 --- a/ruoyi-video/src/main/java/com/ruoyi/video/thread/MediaTransferFlvByFFmpeg.java +++ b/ruoyi-video/src/main/java/com/ruoyi/video/thread/MediaTransferFlvByFFmpeg.java @@ -14,6 +14,7 @@ import io.netty.util.concurrent.GenericFutureListener; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; @@ -83,7 +84,16 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer { } public MediaTransferFlvByFFmpeg(CameraDto cameraDto) { - command.add(System.getProperty(MediaConstant.ffmpegPathKey)); + // 优先使用系统 FFmpeg(包含 libx264),如果不存在则使用 JavaCV 的 + String ffmpegPath = System.getProperty(MediaConstant.ffmpegPathKey); + // 尝试使用系统 FFmpeg + if (new File("/usr/bin/ffmpeg").exists()) { + command.add("/usr/bin/ffmpeg"); + log.info("使用系统 FFmpeg: /usr/bin/ffmpeg"); + } else { + command.add(ffmpegPath); + log.info("使用 JavaCV FFmpeg: {}", ffmpegPath); + } this.cameraDto = cameraDto; this.enableLog = true; // 临时启用日志,用于调试 buildCommand(); @@ -125,8 +135,8 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer { /** * 构建ffmpeg命令 - * 注意:FLV 格式不支持 HEVC,需要转换 - * 使用 mpeg4 编码器(JavaCV FFmpeg 通常内置) + * 注意:FLV 格式不支持 HEVC,需要转换为 H.264 + * 使用 libx264 编码器(系统 FFmpeg 包含) */ private void buildCommand() { // 添加日志级别参数(临时调试用) @@ -136,10 +146,13 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer { .addArgument("-max_delay").addArgument("1") .addArgument("-g").addArgument("25") .addArgument("-r").addArgument("25") - // 使用 mpeg4 编码器(JavaCV FFmpeg 内置,兼容 FLV) - .addArgument("-c:v").addArgument("mpeg4") - .addArgument("-q:v").addArgument("5") // 质量参数(1-31,数字越小质量越好) - .addArgument("-b:v").addArgument("800k") // 视频比特率 + // 使用 libx264 编码器(系统 FFmpeg 包含,质量最好) + .addArgument("-c:v").addArgument("libx264") + .addArgument("-preset").addArgument("ultrafast") + .addArgument("-tune").addArgument("zerolatency") + .addArgument("-b:v").addArgument("1000k") // 视频比特率 + .addArgument("-maxrate").addArgument("1000k") + .addArgument("-bufsize").addArgument("2000k") // 音频编码 .addArgument("-c:a").addArgument("aac") .addArgument("-strict").addArgument("experimental")