qzhing 发表于 2022-6-19 11:32

ffmpeg 分段保存 rtsp 视频数据流

本帖最后由 qzhing 于 2022-6-19 11:34 编辑

最近买了个某品牌的家用摄像头,但是数据云存储还要额外花钱

作为一个程序员怎能让它赚这个钱,于是乎拿出了吃灰已久的树莓派,挂了个脚本

使用 FFmpeg 按分钟存储文件,并上传到云服务器

以下展示 FFmpeg 相关的指令

> 以 `ffmpeg 5.0.1` 为例

详细文档见官网:(https://ffmpeg.org/ffmpeg-all.html)

> 参数示例

```bash
ffmpeg -use_wallclock_as_timestamps 1 -rtsp_transport tcp -i rtsp://:@: -vcodec copy -acodec copy -f segment -reset_timestamps 1 -segment_atclocktime 1 -segment_time 60 -strftime 1 /outdir/%Y%m%d%H%M.mp4
```

> 参数格式

```
ffmpeg [全局设置] {[输入设置] -i 输入路径} ... {[输出设置] 输出路径} ...
```

> 部分参数介绍

参数 | 可选值 | 说明
--- | --- | ---
-use_wallclock_as_timestamps | 0<br>1 | 如果设置为1,则使用系统时间作为时间戳。<br>默认值为0。
-rtsp_transport | udp<br>tcp<br>udp_multicast<br>http | 设置 `rtsp` 传输协议<br>可以指定多个较低的传输协议,在这种情况下,它们一次尝试一个(如果一个设置失败,则尝试下一个)。<br>默认值为 `udp`
-vcodec || 设置视频编解码, `copy` 代表使用输入源的格式
-acodec || 设置音频编解码, `copy` 代表使用输入源的格式
-f || 强制输入或输出文件格式。 `segment` 代表分段
-reset_timestamps | 0<br>1 | 在每个段的开头重置时间戳,这样每个段将以接近零的时间戳开始。<br>默认为0。
-segment_atclocktime | 0<br>1 | 如果设置为“1”,则按从00:00开始的定时时钟间隔分割。<br>在 `segment_time` 中指定的时间值用于设置每段的长度
-segment_time || 每段时间的时长,单位:秒
-strftime | 0<br>1 | 使用 `strftime` 函数定义要写入的文件的名称。<br>如果选择此选项,输出段名称必须包含一个strftime函数模板。<br>默认值为0。


PS:该文档转载自自己的个人博客,这里就不放个人博客原文链接了

uruliang 发表于 2022-6-19 12:15

学习下,最近遇到一个问题:ffplay播放大华摄像头报404错误,VLC就可以正常播放,不知道怎么回事?有知道的大佬指教一下,先谢谢啦

Cool_Breeze 发表于 2022-6-19 13:24

不会丢包吗?

qzhing 发表于 2022-6-19 14:37

Cool_Breeze 发表于 2022-6-19 13:24
不会丢包吗?

简单测试下来,偶尔会丢包或卡住
丢包还好,只会有一个一分钟的视频无法播放
卡住就比较尴尬,必须关闭掉进程(摄像头重新开机FFmpeg就会卡住)

所以我在定时任务脚本里面加了判定,没有新文件产生,就断定为卡住,关掉进程重新开

bokecn 发表于 2022-6-19 14:37

丢包吗?

zxsbk 发表于 2022-6-19 14:54

个人博客发下

qzhing 发表于 2022-6-19 15:20

zxsbk 发表于 2022-6-19 14:54
个人博客发下

个人博客链接就不放了,根据论坛【编程语言区】总版规第七条规定,不能放
七、   严禁在帖子、源码中私留联系方式,推广链接、网址、广告、二维码等信息或则引导用户私聊和留下联系方式,

优乐美001 发表于 2022-6-19 16:15

这个挺不错的 但是有时候会报错

1e3e 发表于 2022-8-3 17:22

qzhing 发表于 2022-6-19 14:37
简单测试下来,偶尔会丢包或卡住
丢包还好,只会有一个一分钟的视频无法播放
卡住就比较尴尬,必须关闭 ...

判定没有新文件产生 的脚本可以分享一下吗

qzhing 发表于 2022-8-3 17:43

本帖最后由 qzhing 于 2022-8-3 17:46 编辑

1e3e 发表于 2022-8-3 17:22
判定没有新文件产生 的脚本可以分享一下吗
注意一下IP和里面用到的工具

#!/bin/bash
# 获取结果
result=$(nmap -p 554 10.0.8.3 | grep 554 | awk '{print $2}')
# 获取进程
pid=$(ps aux | grep ffmpeg | grep -v grep | awk '{print $2}')
# 如果端口是开放的
if [ $result = "open" ]; then
    # 获取当前时间
    now=$(date "+%Y%m%d%H%M")
    # 如果进程存在
    if [ $pid ]; then
      # 等待5秒
      sleep 5
      # 获取最新的文件名
      filename=$(ls -la /work/camera/video | awk 'END {print}' | awk '{print $9}' | cut -b 1-12)
      # 如果当前文件名和当前时间不相同,说明流卡住了
      if [ $filename != $now ]; then
            # 关闭进程并重新打开
            kill -9 $pid
            sleep 1
            nohup /usr/local/ffmpeg/ffmpeg -use_wallclock_as_timestamps 1 -rtsp_transport tcp -i rtsp://username:password@10.0.8.3:554 -vcodec copy -acodec copy -f segment -reset_timestamps 1 -segment_atclocktime 1 -segment_time 60 -strftime 1 /work/camera/video/%Y%m%d%H%M.mp4 >/work/camera/log/$now.log 2>&1 &
      fi
    # 否则进程不存在
    else
      # 开启进程
      nohup /usr/local/ffmpeg/ffmpeg -use_wallclock_as_timestamps 1 -rtsp_transport tcp -i rtsp://username:password@10.0.8.3:554 -vcodec copy -acodec copy -f segment -reset_timestamps 1 -segment_atclocktime 1 -segment_time 60 -strftime 1 /work/camera/video/%Y%m%d%H%M.mp4 >/work/camera/log/$now.log 2>&1 &
    fi
    # 删除旧文件
    cd /work/camera/video/
    # 获取文件夹大小
    size=$(du -s | awk '{print $1}')
    # 当文件夹大小超过40G
    while [ $size -gt 41943040 ]
    do
      # 删除最上方的一个文件
      rm -rf `ls -t | tail -n 1`
      # 重新获取文件夹大小
      size=$(du -s | awk '{print $1}')
    done
# 如果端口关闭或不存在
else
    # 如果进程仍未关闭
    if [ $pid ]; then
      # 关闭进程
      kill -9 $pid
    fi
fi
页: [1] 2
查看完整版本: ffmpeg 分段保存 rtsp 视频数据流