[FFmpeg] 如何通过实时摄像头帧图片生成 rtmp 直播流?

2018-03-08 20:23:29 +08:00
 ZoomQuiet

背景

分析

尝试

问题

动态固定图片

尝试将实时帧图像,另外输出到硬盘固定图片文件, 内容动态变化,

命令改变为: ffmpeg -f image2 -loop 1 -i "path/2/frame.png" ...

但是, 无论怎么调整参数,都只能工作十多帧就崩溃了, 报错都是类似:

...
Error while decoding stream #0:0: Invalid data found when processing input
    Last message repeated 1 times
Past duration 0.799995 too large
[flv @ 0x7fabfa001800] Failed to update header with correct duration.34.3kbits/s dup=0 drop=1120 speed=7.25x
[flv @ 0x7fabfa001800] Failed to update header with correct filesize.
frame= 1730 fps=109 q=5.5 Lsize=    3300kB time=00:01:55.40 bitrate= 234.3kbits/s dup=0 drop=1120 speed=7.24x
video:3273kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.832250%

系列静态图片

而将帧图像持续输出为一系列有命名规模的静态图片后, 参考:

无论怎么折腾参数, 都无法工作, 报错为:

...

  Metadata:
    encoder         : Lavf57.71.100
    Stream #0:0: Video: flv1 (flv) ([2][0][0][0] / 0x0002), yuv420p, 480x270, q=2-31, 200 kb/s, 25 fps, 1k tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.89.100 flv
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
[flv @ 0x7ff53d008600] Failed to update header with correct duration.
[flv @ 0x7ff53d008600] Failed to update header with correct filesize.
frame=   20 fps=0.0 q=9.7 Lsize=     173kB time=00:00:00.76 bitrate=1867.3kbits/s speed=10.1x
video:173kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.300397%

所以, 综合以上, 想知道如何能通过动态图片 /实时增长的系列图片 实时编译为 rmtp 直播流?

或是说, 思路上还有什么选择?

17730 次点击
所在节点    程序员
34 条回复
ZoomQuiet
2018-03-09 18:50:51 +08:00
@fgodt 是也乎 ╮(╯▽╰)╭

pkt 是指数值封装嘛?
ZoomQuiet
2018-03-09 18:53:41 +08:00
@gggxxxx 是也乎 ╮(╯▽╰)╭

已在看此模块

官方样例是从 rmtp 流拿帧的…
但文档中说能写…

但只接受 flv 封装的图片…
然有…找不到可用的… flv 封装模块

所以…你之前是乍写入上游直播流的?
nanhuo
2018-03-17 16:12:49 +08:00
@ZoomQuiet 方便透露一下使用这个方案延时最终能控制在什么范围吗?
ZoomQuiet
2018-03-17 17:35:48 +08:00
@nanhuo 是也乎 ╮(╯▽╰)╭

国内 3 秒内

海外 30 秒内

关键是上游 直播服务平台的资源分布了…
fqxyhdsy
2018-03-19 14:47:50 +08:00
@ZoomQuiet 您好,楼主!请问你这问题解决了吗!现在因为业务需求也要弄个类似的!这边现在的情况是,直播流通过 ffmpeg 切帧,将切完的帧存放在了服务器某个文件夹下,然后不停的覆盖该文件。应该就是您上面说的动态固定图片那种情况。请问具体如何结合 pipe,将这个动态固定图片推成一个视频流!刚接触 python 没多久,请详细讲解一哈!谢谢!
fqxyhdsy
2018-03-20 15:05:04 +08:00
@picone 您好!请问,动态图片+websocket+protobuf,这种方案怎么用 protobuf 来传输图片呀? 这边之前的解决方案是 socket 传输 base64 数据,前端用 websocket 接受数据然后绑定图片到视图层。但是太吃内存了,服务器承受不了!求解惑!万分感谢!
picone
2018-03-20 15:49:04 +08:00
@fqxyhdsy #26 不要转 base64 了,直接把图片 jpeg 编码,然后直接使用 protobuf 序列化就 OK 了,protobuf 接受二进制。如果是连续动态的图片,建议用 mpeg 编码
fqxyhdsy
2018-03-20 16:04:07 +08:00
@picone 首先万分感谢回复! 如果将 jpeg(mpeg)编码后的图片用 protobuf 序列化传过去,应该是没问题。但是现在前端是用 js 的 websocket 来链接的!那怎么来反序列化 protobuf 传过来的数据呢! js 这边是否能够支持 protobuf 和 jpeg(mpeg)解码!刚接触没多久,万分包涵!
picone
2018-03-20 16:09:16 +08:00
@fqxyhdsy #28 js 也提供了 protobuf,也可以做到。jsmpeg 网上也有项目
ZoomQuiet
2018-03-29 19:29:04 +08:00
@fqxyhdsy 是也乎 ╮(╯▽╰)╭

不好意思才看到…

已有流的话…

FFmpeg 本身就支持:
- 拖流为视频文件
- 或直接转播推流到其它协议流

进一步的…图片序列少 TPS 信息…体积也大…
不如存为 .mkv 需要时 --> 推为流
liu826250634
2018-08-21 19:27:14 +08:00
题主您好。
我也是遇到这样的问题,需要从海康摄像头抓取之后进行人脸识别,对视频进行处理之后进行 rtmp 进行推流。
我的代码:
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
sizeStr = str(size[0]) + 'x' + str(size[1])
fps = cap.get(cv2.CAP_PROP_FPS) # 30p/self
fps = int(fps)
rtmpUrl = 'rtmp://192.168.1.71:1935/live/app'
command = ['ffmpeg',
'-y',
'-f', 'rawvideo',
'-vcodec','rawvideo',
'-pix_fmt', 'bgr24',
'-s', sizeStr,
'-r', str(fps),
'-i', '-',
'-c:v', 'libx264',
'-pix_fmt', 'yuv420p',
'-preset', 'ultrafast',
'-f', 'flv',
rtmpUrl]

while True:
ret, frame = cap.read()
proc = sp.Popen(command, stdin=sp.PIPE, shell=False)
proc.stdin.write(frame.tostring())
if cv2.waitKey(1) & 0xFF == ord('q'):
break

运行是成功了(也不能说成功,有时候会崩溃),但是用 VLC 却是不能拉流观看。
然后再想是否是你说的这个问题,从 numpy.ndarray->cv2.cv.cvmat。
但是在网上查资料说 mat_array = cv2.cv.fromarray(frame),这个 opencv-python 2.4 之后就没了。
希望题主看到之后能解答一下!
ZoomQuiet
2018-12-01 17:46:42 +08:00
[FFmpeg] Python 2.7 怎样合理的包裹外部指令安定调用第三方工具并安全结束? - V2EX
https://www.v2ex.com/t/513363#reply0

新问题....
ZoomQuiet
2018-12-01 17:49:41 +08:00
@liu826250634 是也乎,( ̄▽ ̄)
这也是为什么, 我们一直没升级到 Py3+cv3 的原因,
py2.7.X+OpenCV2.4.X 的组合足够安定就没理由升级到可能更好的体系...

另外, VLC 版本也有不同的问题.
建议参考 FFmpeg 官方文档, 先用 ffplayer 来检验 rmtp 是否真正推流成功...

以及, 俺的经验, 这个 rmtp 最好还是先走 腾讯云的视频流服务,
完成一个安定的数据流....
否则, 本地局网的情况太复杂....不好判定
hellotiny
2019-03-26 11:31:12 +08:00
博主你好啊,我也遇到这个问题,不太理解基于 pipe 进行数据共享推流的这个原理,想问逻辑问题。
通过管道的方式实现的哪一种形式呢?
一是将处理过的图片缓存进 buff 中形成了有顺序的帧形成的视频流,使用 ffmpeg 推出的就是 buff 中缓存的视频流吗?
那么推流时抓图和处理图片的进程会不会暂停?
二是处理一帧放入管道,然后就通过 ffmpeg 推送一帧到 rtmp 服务器吗?
我没办法判断我通过 pipe 推流有没有成功,我在 RTMP 播放器中输入推流的 RTMP 地址是没有直播在播放的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/436280

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX