关于直播视频流处理后再转播的技术架构选型 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mikulch
V2EX    Java

关于直播视频流处理后再转播的技术架构选型

  •  
  •   mikulch 2022-03-15 07:48:53 +08:00 4556 次点击
    这是一个创建于 1374 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近有一些需求都跟这个有关,以前都没做过这种实时视频流的处理,都是 crud boy 。目前后端语言是一定要选 java 的。 但是对于这一块基本上一片空白。大家有什么推荐的教程或者书籍么?网上自己搜了下,没什么特别满意的比较全面的教程。

    第 1 条附言    2022-03-15 10:21:39 +08:00
    需求是
    1. 将 A 源 ( hls ) 的流逐帧解码后,送到一个 api 处理(逐帧 /图片),处理后重新编码封装成新的视频流。
    2. 将封装好的新的视频流推给流媒体服务器,供他人观看。
    3. 没有并发要求,也就甲方在某几个特定的地址下,看下不同摄像头的视频监控。

    技术选型
    1. 后端 java
    2. 流媒体服务器:ssr

    遇到的问题:
    1. 因为推流端的解码、编码、封装、再推送的动作特别吃 cpu ,基本上一台机器的 cpu 吃掉 80%。
    2. 如果把推流端和拉流端弄到一台服务器,用户直接观看 ssr 分发的视频会速度很慢。
    3. 因为要把每一帧的图片,通过一个 api 处理,处理后推送到 ssr ,这时候造成 ssr 在观看直播时,画面非常容易卡着缓冲,等推流端推送足够多的帧。这方面的性能优化,在 java 应用层的层面还有什么可以做的吗?

    谢谢大家
    44 条回复    2022-03-16 18:52:58 +08:00
    RedBeanIce
        1
    RedBeanIce  
       2022-03-15 08:19:39 +08:00 via iPhone
    好像有什么 rtmp 还有什么鬼技术,不记得,等一个大佬回复
    smilzman
        2
    smilzman  
       2022-03-15 08:29:51 +08:00
    1. 使用云服务,有转码服务
    2. 用 ffmpeg
    3. 搜索 Java 流媒体
    ryanbuu
        3
    ryanbuu  
       2022-03-15 08:40:29 +08:00 via iPhone
    chenbokais3
        4
    chenbokais3  
       2022-03-15 08:41:25 +08:00
    gstreamer rtsp
    des
        5
    des  
       2022-03-15 08:56:07 +08:00 via iPhone
    估计问的是多流合并、水印这种东西,不是纯转码
    我也蹲一个答案
    des
        6
    des  
       2022-03-15 08:57:26 +08:00 via iPhone
    顺便多说一句,这个方面的 Java 是基本不要想了
    ybnsjl
        8
    ybnsjl  
       2022-03-15 09:49:32 +08:00
    ffmpeg + rtmp + nginx
    Huelse
        9
    Huelse  
       2022-03-15 09:49:58 +08:00
    Ant Media
    Huelse
        10
    Huelse  
       2022-03-15 09:51:50 +08:00
    darkengine
        11
    darkengine  
       2022-03-15 10:01:01 +08:00
    你们直播的音视频流处理都是自己做的吗?我们项目用的商用 SDK ,视频流处理这些都带了
    LLaMA2
        12
    LLaMA2  
       2022-03-15 10:01:52 +08:00   1
    需求不明,无法给到您更好的建议,
    hu8245
        13
    hu8245  
       2022-03-15 10:03:03 +08:00
    搞这个的,分推拉,推的话,国内主要用 rtmp ,( youtuebe twitch 也是),你可能需要在服务器段进行转封装或转码,这个想简单的话就 ffmpeg 了,或者有音视频开发资源的话,自己去开发,成本比较大。拉流就随意了,DASH/HLS 都支持 low latency ,还是有现成的方案的。主要还是在服务器这里,没有 C/C++ 技术栈去深入的话,基本上就只能用现成的。
    mikulch
        14
    mikulch  
    OP
       2022-03-15 10:10:10 +08:00
    @smilzman

    @andyskaura
    @darkengine
    @hu8245
    感谢各位大佬,我这边的需求其实是这样。
    有一个直播的 hs 格式来源,是个视频流的地址。这个地址可以通过 java 封装的 ffmpeg 抓取到帧,然后需求需要把每一帧的图片,通过另外一个图片 APi 做一下处理,然后重新转码封装成 rtmp 格式的视频流推到流媒体服务器。

    现在流媒体服务器用的国产的 ssr 。遇到的问题,是拉流端 即 -> 抓取直播 hls 数据,解码成图片,然后 api 处理后重新编码封装成视频格式这里,非常的耗费 cpu 资源。

    一台服务器起码吃掉 80%,不知道是否有可能可以解决?
    mikulch
        15
    mikulch  
    OP
       2022-03-15 10:22:07 +08:00
    @ye4tar
    @ybnsjl
    @des
    @q1angch0u

    谢谢各位大佬,详细内容已经补充到了问题中。
    locoz
        16
    locoz  
       2022-03-15 10:24:41 +08:00 via Android
    @mikulch #14 每一帧的图片调一次 API 做一次处理再重新拼成视频…这么处理吃 CPU 是必然的。建议描述一下这个图片 API 做了什么事,看看有没有什么更合适的解决办法。
    microxiaoxiao
        17
    microxiaoxiao  
       2022-03-15 10:26:09 +08:00 via Android
    编解码不吃 CPU 就吃 GPU 你这个方案可以有两个可能改善的效果。解码成 raw 数据,然后 api 处理 raw 数据,再编码,可以少编码解码过程。其次就是用硬件 GPU ,降低 CPU 使用。
    andyskaura
        18
    andyskaura  
       2022-03-15 10:28:01 +08:00
    @mikulch 加一块垃圾显卡 GPU 加速 能显著提升效率
    lakehylia
        19
    lakehylia  
       2022-03-15 10:33:11 +08:00
    软解软编非常吃 CPU ,上显卡吧。四路泰坦~~ [狗头]
    raysonlu
        20
    raysonlu  
       2022-03-15 10:36:07 +08:00
    云服务不香?
    nicevar
        21
    nicevar  
       2022-03-15 10:48:44 +08:00
    学习一下 twitch
    LLaMA2
        22
    LLaMA2  
       2022-03-15 11:13:44 +08:00
    解码 /编码确实很消耗 CPU ,这是 GPU 更擅长的领域,不过还有更专用的解码 /编码硬件,
    JAVA 层的优化空间,我能想到的是你使用的 FFMPEG 是 JAVA 实现还是 JNI/JNA 实现,
    理论上说 C++的实现会比 JAVA 的性能更好。还有你说的 API 处理是处理什么,加水印还是其他的
    图形识别?获取甲方的摄像头比你想象的更强大。你可以再展开说一说,我们的智慧是无穷的
    rb6221
        23
    rb6221  
       2022-03-15 11:44:51 +08:00
    吃资源的东西,还非要用 java ,这就不好弄了,要么找一下商用的,或者上云吧。云端转了传回你,你负责分发就行了
    mikulch
        24
    mikulch  
    OP
       2022-03-15 12:11:51 +08:00
    @locoz
    @ye4tar
    是一个百度的图片识别 api ,主要标注和统计当前图片中有哪些类型的车辆,和车辆所在图片的坐标的。
    mikulch
        25
    mikulch  
    OP
       2022-03-15 12:14:29 +08:00
    @andyskaura
    @ybnsjl
    @hu8245
    @ye4tar

    目前确实用的就是这个方案。java 用的是 org.bytedeco.javacv 这个库。
    mikulch
        26
    mikulch  
    OP
       2022-03-15 12:15:32 +08:00
    @janus77
    @raysonlu 感谢两位。我不太理解云服务是指?
    目前我们的项目就是部署到阿里云的。你们的意思是说,整个解码编码都不自己做了,直接把源链接扔给某个服务,然后他们转了返给我们,我们直接拿到以后分发就完事儿,连编码都不用了?
    wangyu17455
        27
    wangyu17455  
       2022-03-15 12:30:17 +08:00 via Android
    一定要拆开逐帧操作的话建议用云函数,一帧调用一次
    smilzman
        28
    smilzman  
       2022-03-15 12:51:49 +08:00
    @mikulch 可以看看 27 楼说的云函数,还有阿里云里面的 VEC 、媒体处理之类的。
    mayli
        29
    mayli  
       2022-03-15 13:01:43 +08:00
    ffmpeg 本身就可以做这个,拉取流,转码,然后推出去,一个 shell 脚本搞定
    rb6221
        30
    rb6221  
       2022-03-15 13:34:44 +08:00
    @mikulch #26 差不多就是这样,所有计算型的任务都是消耗云端的硬件资源。阿里云也是有类似服务的,像这种 https://www.aliyun.com/product/mts?spm=5176.100239.blogrightarea51182.6.4NU75C
    skiy
        31
    skiy  
       2022-03-15 13:52:16 +08:00
    插楼,C++ 我知道国人开发的一款比较不错的: https://github.com/ZLMediaKit/ZLMediaKit
    hu8245
        32
    hu8245  
       2022-03-15 14:01:47 +08:00
    还是交给云不错,只靠 java 很难做到高性能的音视频处理。推拉的过程带来的时延和卡顿一直都是业界研究的重点,比较靠谱的方案是推给 CDN ,这个 CDN 还是得支持 http chunck encoding 的,使用 low latency 的 DASH/HLS, 延迟能到 2s 左右,但是这都是商业方案才能做到的,开源方案基本上没有较好的办法
    LLaMA2
        33
    LLaMA2  
       2022-03-15 14:33:30 +08:00   1
    我仔细读了一下你补充的内容和原始的内容,由于你需要使用 opencv 做物体识别,我的建议你的 server 只处理推拉流,opencv 识别的部分放到客户 client 处理,好点的 android 设备,不带屏幕,2500 以内,用 opencv 做识别输出视频,如果甲方的摄像头能直连 android 识别的话性能更好,60FPS 没问题
    darkengine
        34
    darkengine  
       2022-03-15 14:42:13 +08:00
    先不说 CPU 使用率的问题,每帧都调用 API 怎么能保持实时性
    raysonlu
        35
    raysonlu  
       2022-03-16 09:25:17 +08:00
    @mikulch 阿里云的话,看看视频直播、视频点播提供的服务能否支持你们的整个业务流程
    zliea
        36
    zliea  
       2022-03-16 11:53:05 +08:00
    个人感觉肯定不能每帧都调用,在误差或者允许的情况下每秒调用 4-6 次足够了。
    如果必须要求每帧,我觉得需要考虑边缘计算。
    zliea
        37
    zliea  
       2022-03-16 11:56:51 +08:00
    当然非实时就随便搞了。
    mikulch
        38
    mikulch  
    OP
       2022-03-16 17:05:36 +08:00
    @zliea 刚刚新增了需求,不用实时,可以延迟 5 - 10 分钟。但是即使是这样子,问题还是存在,就是消费端看视频,看完推送过去的视频以后,就要等后续新推送的视频了。
    但是这边推送因为要走 api 处理推送会很慢,没有办法。
    mikulch
        39
    mikulch  
    OP
       2022-03-16 17:11:17 +08:00
    @darkengine 现在的问题就是这个,消费端的速度太快,生产端的速度跟不上。
    darkengine
        40
    darkengine  
       2022-03-16 17:28:05 +08:00
    所以这个方案有问题啊,搞个本地的 SDK 还差不多。
    zliea
        41
    zliea  
       2022-03-16 18:04:28 +08:00
    1. 不是每一帧数据都请求 API 。
    2. 并发请求 API ,要求 API 可以并发执行,然后等待固定延迟后再推数据。
    一个直播流就需要这么大的计算量,有没有考虑同时多个直播流,如果有趁早考虑边缘计算。
    mikulch
        42
    mikulch  
    OP
       2022-03-16 18:09:08 +08:00
    @zliea 并发请求 api 的话如何保证帧数返回的顺序呢?
    另外不是每一帧都请求的话,因为数据这边要做标注,如果不每一帧都请求的话,画面上就会出现上一帧标注了,下一帧不标注的情况,这样就感觉很奇怪。

    等待固定延时后再推送和一帧一帧的好像都差不多哇。速度还是那么慢。
    zliea
        43
    zliea  
       2022-03-16 18:30:04 +08:00
    1. 每一帧做一个标记 request id ,API 返回的时候把标记 request id 也要返回回来,然后重排。
    2. “不是每一帧数据都请求 API”,这个意味着标注不更新,就是假定每 4 帧取第 1 帧计算,那么 2-4 帧的标注也是第 1 帧的标注去合成。
    mikulch
        44
    mikulch  
    OP
       2022-03-16 18:52:58 +08:00
    @zliea 明白了,就是 2-4 帧都用第一帧的标注这个如果业务上要求,视频中的某一张图片上如果出现新的物品,需要标注出来。
    如果没标注出来的话,继续用下一个 4 帧的第一帧的标注来解决这个思路吗?这样子有图片在 4 个帧间隔之间出现又消失,不然好像没啥问题。似乎确实是个好办法,大佬有在业务上使用过这种做法吗,实际观看的时候会有啥效果影响吗?


    另外第一点确实是个好方法,相当于一个线程拉取了再一个一个的处理,确实可以节约一些 io 等待的时间。谢谢大佬。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1176 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 17:46 PVG 01:46 LAX 09:46 JFK 12:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86