Java小强个人技术博客站点    手机版
当前位置: 首页 >> 开源 >> 使用FFmpeg通过RSTP协议拉取视频保存到本地

使用FFmpeg通过RSTP协议拉取视频保存到本地

180 开源 | 2025-11-12

FFmpeg是领先的多媒体框架,能够解码、编码、 转码、复用、解复用、流、过滤和播放 几乎所有人类和机器创建的东西。它支持最模糊的古老格式,直到最前沿。无论它们是由某个标准委员会、社区还是公司设计的。它还具有高度的可移植性:FFmpeg 在各种构建环境、机器架构和配置下跨 Linux、Mac OS X、Microsoft Windows、BSD、Solaris 等 编译、运行和通过我们的测试基础架构 FATE 。

FFmpeg.png

官网:

https://ffmpeg.org/ 

https://ffmpeg.p2hp.com/index.html (中文) 


FFmpeg除了做转码外,也支持通过TCP或者UDP协议,拉取RSTP视频流,实时将视频流转为MP4文件存到本地,支持直接拉取H264和H265。

例如,当前我们使用海康相机来进行测试,拉取的为H265视频流,拉取到视频流后,本地再转为H264格式,然后把音频同时转化,然后按照时间存为Mp4。

因为H265占用宽带更小,因此我们优先采用该格式,在不考虑宽带时,也可以考虑直接拉取H264。


海康相机是支持直接拉取视频流的,例如我们使用VLC软件(https://www.videolan.org/vlc/index.html),就可以直接预览视频

VLC打开网络视频.jpg

此时我们使用的是RSTP流, URL格式为:rtsp://用户名:密码@IP:RSTP端口/h265(或h264)

VLC打开网络视频URL格式.jpg

然后我们就能预览到视频了

VLC打开网络视频预览视频.jpg


下面我们通过FFmpeg的rtsp_transport命令,拉取RSTP视频流,并转码存到本地。

下载FFmpeg并配置到环境变量,如何配置可以自行查询相关资料。

先看完整代码,这里写了一个Main方法,如何集成到项目,自行考量

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 利用ffmpeg实时拉取视频流并保存到本地MP4
 */
@Slf4j
public class FfmpegWatcher {
    private static final String FFMPEG_PATH = "ffmpeg";
    private static final String OUTPUT_DIR = "D:\\temp";
    private static final long RESTART_DELAY_MS = 5_000;
    private static final String CAMERA_IP = "192.168.110.114";
    private static final String CAMERA_PASSWORD = "111111";
    private static final String CAMERA_USER = "admin";
    private static final String CAMERA_RTSP_PORT = "554";

    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private volatile Process ffmpegProcess = null;

    // 关键:使用 volatile 确保线程可见性
    private volatile Long lastLog = null;
    // 新增:是否已因超时触发过 destroy(防止重复 kill)
    private volatile boolean destroyedDueToTimeout = false;
    private Thread watchdog = null;

    public static void main(String[] args) {
        FfmpegWatcher watcher = new FfmpegWatcher();
        watcher.addShutdownHook();
        watcher.monitor();
        watcher.startWatchdog();

        try {
            new CountDownLatch(1).await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 启动看门狗线程:每 N 秒检查一次 lastLog 是否超时
     */
    private void startWatchdog() {
        watchdog = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(1000); // 每N秒检查一次
                    if (ffmpegProcess != null && ffmpegProcess.isAlive() && !destroyedDueToTimeout) {
                        if (lastLog != null) {
                            long now = System.currentTimeMillis();
                            if (now - lastLog > 10_000) { // 超过10秒无日志
                                log.info("检测到 ffmpeg 超过 10 秒无输出,疑似卡死,正在强制重启...");

                                // 尝试发送 'q' 信号优雅退出
                                // 这样已经录制的视频文件,会停止录制,保留当前录制不完成的MP4文件
                                try {
                                    ffmpegProcess.getOutputStream().write('q');
                                    ffmpegProcess.getOutputStream().flush();
                                } catch (IOException e) {
                                    log.error("发送 'q' 信号给 ffmpeg 失败", e);
                                }

                                destroyedDueToTimeout = true; // 防止重复 kill
                                ffmpegProcess.destroy(); // 触发 waitFor 返回
                                lastLog = System.currentTimeMillis(); // 重新计时
                            }
                        }
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt(); // 恢复中断状态
                    break; // 退出循环
                } catch (Exception e) {
                    log.error("看门狗线程异常", e);
                }
            }
        }, "ffmpeg-watchdog");
        watchdog.setDaemon(true);
        watchdog.start();
    }

    /**
     * 构建 ffmpeg 命令
     */
    private List<String> buildCommand() {
        List<String> cmd = new ArrayList<>();
        cmd.add(FFMPEG_PATH);

        cmd.add("-rtsp_transport");
        cmd.add("tcp");

        String password = URLEncoder.encode(CAMERA_PASSWORD, StandardCharsets.UTF_8);
        cmd.add("-i");
        cmd.add(StrUtil.format("rtsp://{}:{}@{}:{}/h265", CAMERA_USER, password, CAMERA_IP, CAMERA_RTSP_PORT));

        cmd.add("-c:v");
        cmd.add("libx264");
        cmd.add("-preset");
        cmd.add("veryfast"); // 更“慢”的 preset 通常能获得更好的压缩率(即相同质量下文件更小)。可选值从快到慢:ultrafast → superfast → veryfast → faster → fast → medium → slow → slower → veryslow
        cmd.add("-crf");
        cmd.add("23"); // 取值范围一般为 0–51:0 = 无损(文件极大)18–23 = 视觉无损到高质量(推荐范围)28 = 较低质量,较小体积(适合网络传输或对画质要求不高)51 = 最差质量

        cmd.add("-c:a");
        cmd.add("aac");
        cmd.add("-b:a");
        cmd.add("128k");

        cmd.add("-f");
        cmd.add("segment");
        cmd.add("-segment_time");
        cmd.add("60");  // 分割时长
        cmd.add("-strftime");
        cmd.add("1");

        cmd.add(OUTPUT_DIR + File.separator + CAMERA_IP + "_%Y%m%d_%H%M%S.mp4");
        return cmd;
    }

    /**
     * 启动 ffmpeg 进程
     */
    private void startProcess() throws IOException {
        new File(OUTPUT_DIR).mkdirs();

        List<String> command = buildCommand();
        ProcessBuilder pb = new ProcessBuilder(command);
        pb.redirectErrorStream(true);
        ffmpegProcess = pb.start();
        lastLog = System.currentTimeMillis(); // 重新计时

        Thread logForwarder = new Thread(() -> {
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(ffmpegProcess.getInputStream(), StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    log.debug("[FFMPEG] {}", line);
                    lastLog = System.currentTimeMillis(); // 更新最后日志时间

                    if(line.contains("Opening") && line.contains("for writing")) {
                        String fileName = extractFileName(line);
                        log.info("开始录制文件:{}", fileName);
                    }
                }
                log.debug("[FFMPEG] 日志读取线程结束,ffmpeg 进程已终止");
            } catch (IOException e) {
                log.error("读取 ffmpeg 输出流时异常", e);
            }
        }, "ffmpeg-log-forwarder");
        logForwarder.setDaemon(true);
        logForwarder.start();

        log.info("ffmpeg 录像开始, 进程号 = {}", ffmpegProcess.pid());
    }

    /**
     * 注册和控制 ffmpeg 进程
     */
    private void monitor() {
        executor.submit(() -> {
            while (!executor.isShutdown()) {
                try {
                    if (ffmpegProcess == null) {
                        destroyedDueToTimeout = false; // 重置标志
                        startProcess();
                    }
                    int exitCode = ffmpegProcess.waitFor();
                    log.error("ffmpeg 结束录像,退出信号 = {}", exitCode);
                    Thread.sleep(RESTART_DELAY_MS);
                    ffmpegProcess = null;
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (IOException e) {
                    log.error("ffmpeg 启动录像失败", e);
                    try {
                        Thread.sleep(RESTART_DELAY_MS);
                    } catch (InterruptedException ignored) {
                    }
                }
            }
        });
    }

    /**
     * 添加关闭钩子
     */
    private void addShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            log.info("JVM 关闭中,正在清理 ffmpeg 进程...");

            // 中断并等待 watchdog 结束
            if (watchdog != null && watchdog.isAlive()) {
                watchdog.interrupt();
            }

            if (ffmpegProcess != null && ffmpegProcess.isAlive()) {
                // 尝试发送 'q' 信号优雅退出
                // 这样已经录制的视频文件,会停止录制,保留当前录制不完成的MP4文件
                try {
                    ffmpegProcess.getOutputStream().write('q');
                    ffmpegProcess.getOutputStream().flush();
                } catch (IOException e) {
                    log.error("发送 'q' 信号给 ffmpeg 失败", e);
                }
                try {
                    if (!ffmpegProcess.waitFor(5, TimeUnit.SECONDS)) {
                        ffmpegProcess.destroyForcibly();
                    }
                } catch (InterruptedException ignored) {
                    Thread.currentThread().interrupt();
                }
            }
            executor.shutdownNow();
        }));
    }

    /**
     * 先取出完整路径,再用 Paths 获取文件名
     * */
    public String extractFileName(String logLine) {
        // 只取单引号之间的内容(完整路径)
        String pathRegex = "Opening\\s*'([^']+)'";
        Matcher m = Pattern.compile(pathRegex).matcher(logLine);
        if (m.find()) {
            String fullPath = m.group(1);               // D:\temp\192.168.110.114_20251110_143020.mp4
            // Paths 会自动识别 Windows 反斜杠
            return Paths.get(fullPath).getFileName().toString(); // 192.168.110.114_20251110_143020.mp4
        }
        return null;
    }
}


方法buildCommand是组装相关命令,相关命令解释已经备注。

这里特别要注意的是,要注意addShutdownHook方法,注册一个钩子,在程序退出时,终止录制。如果是强制停止,比如Linux上的Kill -9,那么程序不能完成处理当前的文件,导致最后一个文件不能播放。

还要注意的是,如果产生网络卡顿,就会堵塞,所以我这里采用看门狗(startWatchdog方法)来监控录制情况,如果长时间没有录制,则终止重启。


怎么知道在录制呢?就是方法startProcess里面的logForwarder线程,会实时接收ffmpeg的打印,实际上ffmpeg会一直打印每一帧的处理情况,如果有打印就说明在录制。

同时在该线程里面,通过正则来找到当前正在录制的是哪个文件。

执行能看到执行日志

19:23:54.054 c.g.o.c.FfmpegWatcher    : 168 ffmpeg 录像开始, 进程号 = 15092
19:23:54.155 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] ffmpeg version 6.0-full_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developers
19:23:54.156 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   built with gcc 12.2.0 (Rev10, Built by MSYS2 project)
19:23:54.156 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libvpl --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
19:23:54.156 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   libavutil      58.  2.100 / 58.  2.100
19:23:54.157 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   libavcodec     60.  3.100 / 60.  3.100
19:23:54.157 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   libavformat    60.  3.100 / 60.  3.100
19:23:54.157 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   libavdevice    60.  1.100 / 60.  1.100
19:23:54.157 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   libavfilter     9.  3.100 /  9.  3.100
19:23:54.157 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   libswscale      7.  1.100 /  7.  1.100
19:23:54.157 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   libswresample   4. 10.100 /  4. 10.100
19:23:54.157 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   libpostproc    57.  1.100 / 57.  1.100
19:23:54.422 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [hevc @ 000002f0a9aa5840] PPS id out of range: 0
19:23:54.422 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]     Last message repeated 1 times
19:23:54.422 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [hevc @ 000002f0a9aa5840] Error parsing NAL unit #0.
19:23:55.215 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] Input #0, rtsp, from 'rtsp://admin:Gtgj%402020@192.168.110.114:554/h265':
19:23:55.215 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Metadata:
19:23:55.215 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]     title           : Media Presentation
19:23:55.215 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Duration: N/A, start: 0.000000, bitrate: N/A
19:23:55.215 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Stream #0:0: Video: hevc (Main), yuvj420p(pc, bt709), 2688x1520, 50 fps, 25.08 tbr, 90k tbn
19:23:55.215 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Stream #0:1: Audio: pcm_alaw, 8000 Hz, mono, s16, 64 kb/s
19:23:55.220 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] Stream mapping:
19:23:55.220 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Stream #0:0 -> #0:0 (hevc (native) -> h264 (libx264))
19:23:55.220 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Stream #0:1 -> #0:1 (pcm_alaw (native) -> aac (native))
19:23:55.220 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] Press [q] to stop, [?] for help
19:23:55.221 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [aac @ 000002f0a9c113c0] Too many bits 16384.000000 > 6144 per frame requested, clamping to max
19:23:55.224 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [hevc @ 000002f0a9c117c0] Could not find ref with POC 0
19:23:55.283 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
19:23:55.288 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] profile High, level 5.0, 4:2:0, 8-bit
19:23:55.288 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] 264 - core 164 r3106 eaa68fa - H.264/MPEG-4 AVC codec - Copyleft 2003-2023 - http://www.videolan.org/x264.html - options: cabac=1 ref=1 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=2 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=30 lookahead_threads=10 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=1 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
19:23:55.289 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [segment @ 000002f0a9d5e800] Opening 'D:\temp\192.168.110.114_20251112_192355.mp4' for writing
19:23:55.292 c.g.o.c.FfmpegWatcher    : 157 开始录制文件:192.168.110.114_20251112_192355.mp4
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] Output #0, segment, to 'D:\temp\192.168.110.114_%Y%m%d_%H%M%S.mp4':
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Metadata:
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]     title           : Media Presentation
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]     encoder         : Lavf60.3.100
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Stream #0:0: Video: h264, yuvj420p(pc, bt709, progressive), 2688x1520, q=2-31, 25.08 fps, 19264 tbn
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]     Metadata:
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]       encoder         : Lavc60.3.100 libx264
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]     Side data:
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]       cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]   Stream #0:1: Audio: aac (LC), 8000 Hz, mono, fltp, 48 kb/s
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]     Metadata:
19:23:55.293 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG]       encoder         : Lavc60.3.100 aac
19:23:55.300 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=    0 fps=0.0 q=0.0 size=N/A time=00:00:00.25 bitrate=N/A dup=2 drop=0 speed= 4.4x    
19:23:55.833 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=    0 fps=0.0 q=0.0 size=N/A time=00:00:01.02 bitrate=N/A dup=2 drop=0 speed=1.74x    
19:23:56.317 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=    0 fps=0.0 q=0.0 size=N/A time=00:00:01.53 bitrate=N/A dup=2 drop=0 speed= 1.4x    
19:23:56.857 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=    5 fps=3.1 q=28.0 size=N/A time=00:00:02.04 bitrate=N/A dup=2 drop=0 speed=1.28x    
19:23:57.351 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=   18 fps=8.5 q=28.0 size=N/A time=00:00:02.56 bitrate=N/A dup=2 drop=0 speed=1.21x    
19:23:57.873 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=   31 fps= 12 q=28.0 size=N/A time=00:00:03.07 bitrate=N/A dup=2 drop=0 speed=1.17x    
19:23:58.405 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=   43 fps= 14 q=28.0 size=N/A time=00:00:03.58 bitrate=N/A dup=2 drop=0 speed=1.14x    
19:23:58.895 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=   57 fps= 16 q=28.0 size=N/A time=00:00:04.09 bitrate=N/A dup=2 drop=0 speed=1.11x    
19:23:59.434 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=   70 fps= 17 q=28.0 size=N/A time=00:00:04.73 bitrate=N/A dup=2 drop=0 speed=1.13x    
19:23:59.916 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=   82 fps= 17 q=28.0 size=N/A time=00:00:05.12 bitrate=N/A dup=2 drop=0 speed=1.09x    
19:24:00.587 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=   94 fps= 18 q=28.0 size=N/A time=00:00:05.63 bitrate=N/A dup=2 drop=0 speed=1.05x    
19:24:01.111 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=  111 fps= 19 q=28.0 size=N/A time=00:00:06.27 bitrate=N/A dup=2 drop=0 speed=1.07x    
19:24:01.608 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=  125 fps= 20 q=28.0 size=N/A time=00:00:06.91 bitrate=N/A dup=2 drop=0 speed=1.08x    
19:24:01.754 c.g.o.c.FfmpegWatcher    : 205 JVM 关闭中,正在清理 ffmpeg 进程...
19:24:01.855 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] 
19:24:01.855 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] 
19:24:01.855 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [q] command received. Exiting.
19:24:01.855 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] 
19:24:01.891 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] frame=  175 fps= 26 q=-1.0 Lsize=N/A time=00:00:07.29 bitrate=N/A dup=2 drop=0 speed=1.09x    
19:24:01.892 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] video:2412kB audio:24kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] frame I:2     Avg QP:15.71  size:227681
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] frame P:82    Avg QP:23.17  size: 23836
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] frame B:91    Avg QP:25.75  size:   652
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] consecutive B-frames:  1.7% 86.9%  0.0% 11.4%
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] mb I  I16..4: 57.3% 18.7% 24.0%
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] mb P  I16..4:  0.9%  0.9%  0.0%  P16..4: 14.8%  1.3%  0.8%  0.0%  0.0%    skip:81.2%
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  0.6%  0.0%  0.0%  direct: 0.6%  skip:98.8%  L0:29.5% L1:69.7% BI: 0.8%
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] 8x8 transform intra:31.1% inter:49.5%
19:24:01.893 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] coded y,uvDC,uvAC intra: 45.0% 11.2% 2.3% inter: 3.7% 0.9% 0.0%
19:24:01.894 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] i16 v,h,dc,p: 64% 17% 13%  6%
19:24:01.894 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 16% 28% 37%  4%  3%  2%  4%  3%  5%
19:24:01.894 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 23% 30%  8%  4%  3%  3%  4%  3% 23%
19:24:01.894 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] i8c dc,h,v,p: 74% 14% 11%  1%
19:24:01.894 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] Weighted P-Frames: Y:0.0% UV:0.0%
19:24:01.894 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [libx264 @ 000002f0a9d600c0] kb/s:2831.40
19:24:01.990 c.g.o.c.FfmpegWatcher    : 152 [FFMPEG] [aac @ 000002f0a9c113c0] Qavg: 61755.230
19:24:02.052 c.g.o.c.FfmpegWatcher    : 160 [FFMPEG] 日志读取线程结束,ffmpeg 进程已终止


可以看到,打印了正在执行文件夹的名称,同时在终止程序时,会清理相关进程,这样我们最后一个文件,虽然没有录制一分钟,但是会录制到程序停止时。

推荐您阅读更多有关于“ ffmpeg rstp 海康 视频流 mp4 h264 h265 ”的文章

上一篇:使用Java实现国密SM3算法 下一篇:内网下安装FTP第一次连接时卡顿

猜你喜欢

发表评论: