zoukankan      html  css  js  c++  java
  • RTSP H264/HEVC 流 Wasm 播放

    本文将介绍 RTSP H264/HEVC 裸流如何于网页前端播放。涉及 WebSocket 代理发送流数据, Wasm 前端解码等。

    相关模块:

    # RTSP WebSocket Proxy
    RTSP/Webcam/File > FFmpeg open > Packets > WebSocket
    # WS Wasm Player
    WebSocket > Packets > Wasm FFmpeg decode to YUV > WebGL display
                                                    > Wasm OpenGL display
    # WS Local Player
    WebSocket > Packets > FFmpeg decode to YUV > OpenGL display
    
    • RTSP WebSocket Proxy: 流代理服务器(C++)。HTTP 请求流信息(支持了跨域),WebSocket 传输流数据。
    • WS Wasm Player: 前端播放实现(ES6)。WebSocket, Wasm, WebGL 等封装,提供了 WsClient 接口。
    • WS Local Player: 本地播放实现(C++)。与前端流程一样,向流代理服务器请求数据,解码后 OpenGL 显示。

    前端效果:

    后端流代理服务

    主流程:

    # RTSP WebSocket Proxy
    RTSP/Webcam/File > FFmpeg open > Packets > WebSocket
    
    • FFmpeg 打开 RTSP/Webcam/File ,获取 packets (common/media/stream.cc)
    • FFmpeg bsf (bitstream filter) 获取 h264/hevc 裸流 packets (rtsp-ws-proxy/stream_handler.cc)
    • Boost.Beast 实现 WebSocket 服务,发送裸流 packets 给订阅的客户端 (rtsp-ws-proxy/ws_*)

    前端 FFMpeg Wasm 解码,需要的两个结构体为:

    • AVCodecParameters: 编码参数。序列化为 JSON, HTTP Get 请求获取 (common/net/json.h)
    • AVPacket: 流数据包。序列化为 binary , WebSocket 进行传输 (common/net/packet.h)

    服务支持了 HTTP 静态服务器,可直接部署 WS Wasm Player 页面。但前后端分离部署时,就要求服务允许跨域了 (common/net/cors.h)。

    最终,可配置项有:

    log:
      # true: stderr, false: logfiles
      logtostderr: true
      alsologtostderr: false
      colorlogtostderr: true
      # LOG(), 0: INFO, 1: WARNING, 2: ERROR, 3: FATAL
      minloglevel: 0
      # VLOG(N)
      v: 0
      log_prefix: true
      log_dir: "."
      max_log_size: 8
      stop_logging_if_full_disk: true
    
    server:
      addr: "0.0.0.0"
      port: 8080
      threads: 3
    
      http:
        enable: true
        doc_root: "../ws-wasm-player/"
    
      cors:
        enabled: true
        allowed_origins: "*"
        allowed_methods: [ GET ]
        allowed_headers:
          - Content-Type
        allowed_credentials: false
        exposed_headers:
          - Content-Type
        debug: false
    
      stream:
        http_target: "/streams"
        ws_target_prefix: "/stream/"
    
    streams:
      -
        id: "a"
        method: "file"
        input_url: "../data/test.mp4"
      -
        id: "b"
        method: "network"
        input_url: "rtsp://127.0.0.1:8554/test"
    
        max_delay: 1000000
        rtsp_transport: "tcp"
        stimeout: 5000000
      -
        id: "c"
        method: "webcam"
        input_url: "/dev/video0"
    
        input_format: "v4l2"
         640
        height: 480
        framerate: 20
        pixel_format: "yuyv422"
    
    # 25 = 1000 / 40 fps
    stream_get_frequency: 25
    
    # test only: multithreading glfw not coding stable now
    stream_ui_enable: false
    

    将想要代理的 RTSP 流配置进 streams,运行服务即可。

    前端解码与播放

    主流程:

    # WS Wasm Player
    WebSocket > Packets > Wasm FFmpeg decode to YUV > WebGL display
                                                    > Wasm OpenGL display
    
    • 前端页面填写服务地址,刷新并选择某流,再打开 (ws-wasm-player/index.html)
    • WebSocket 获取流数据,给到 Wasm FFmpeg 解码,再转码为 YUV420p (ws-wasm-player/src/decoder.h)
    • WebGL 显示 YUV420p ,或给到 Wasm OpenGL 进行显示 (ws-wasm-player/src/player.h)

    简单实测:

    • H264 1920x1080 25fps, 前端解码转码耗时 80~120 ms,来不及处理,引起卡顿
    • H264 1280x720 25fps, 前端解码转码耗时 10~30 ms,能够及时处理及显示

    所以于高分辨率的场景,考虑 MediaSource, WebCodecs 等硬解更好。

    此外 RTSP 建议用 TCP 。UDP 时,后端服务报丢包警告,前端解码则报 P 帧警告,容易花屏、OOM。

    结语

    除了 RTSP 流,也支持了 WebCam/File ,所以可以直播 WebCam 摄像头或轮播某 MP4 文件。

    目前想实际体验的话,需要依照代码 README 自己编译。以后可能会打包发布,能够快速体验。

    GoCoding 个人实践的经验分享,可关注公众号!

  • 相关阅读:
    (3)合并列值与分拆列值
    (2)SQL语句实现表的横向聚合
    (1)显示每个类别最新更新的数据
    【实践】WCF传输安全2:基于SSL的WCF匿名客户端
    超经典解释什么叫网关
    List集合操作一:遍历与查找
    RGB值及中文名称
    绑定树控件
    treeview的checkbox展开节点
    winform AutoScaleMode属性
  • 原文地址:https://www.cnblogs.com/gocodinginmyway/p/15243767.html
Copyright © 2011-2022 走看看