本文将介绍 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"
width: 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 个人实践的经验分享,可关注公众号!

RTSP H264/HEVC 流 Wasm 播放的更多相关文章

  1. cuda+ffmpeg+opengl解码rtsp h264码流多路

    Cuda 解码 全尺寸 解码 .全尺寸窗口绘制测试( 分别 测试 视频 文件和 IP 相机 实时视频 ) 1080 p 视屏 文件 全尺寸 解码 全尺寸 显示 72 0p IP 相机 全尺寸 解码 全 ...

  2. ffmpeg学习(二) 通过rtsp获取H264裸流并保存到mp4文件

    本篇将使用上节http://www.cnblogs.com/wenjingu/p/3977015.html中编译好的库文件通过rtsp获取网络上的h264裸流并保存到mp4文件中. 1.VS2010建 ...

  3. 利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中

    既然已经可以通过 RTSP 获取h264 裸流了.那么通过 FFmpeg 将其保存到文件中怎么做呢? 一.首先RTSP获取 h264 裸流 我们上面两篇文章主要讲的是通过 rtsp://Your ip ...

  4. H264码流解析及NALU

    ffmpeg 从mp4上提取H264的nalu http://blog.csdn.net/gavinr/article/details/7183499 639     /* bitstream fil ...

  5. javaCV开发详解之8:转封装在rtsp转rtmp流中的应用(无须转码,更低的资源消耗)

    javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...

  6. 实现输出h264直播流的rtmp服务器 flash直播服务器【转】

    实现输出h264直播流的rtmp服务器 RTMP(Real Time Messaging Protocol)是常见的流媒体协议,用来传输音视频数据,结合flash,广泛用于直播.点播.聊天等应用,以及 ...

  7. H264码流打包分析(精华)

    H264码流打包分析 SODB 数据比特串-->最原始的编码数据 RBSP 原始字节序列载荷-->在SODB的后面填加了结尾比特(RBSP trailing bits 一个bit“1”)若 ...

  8. 实现输出h264直播流的rtmp服务器 flash直播服务器

    http://www.cnblogs.com/haibindev/archive/2012/04/16/2450989.html 实现输出h264直播流的rtmp服务器 RTMP(Real Time ...

  9. (转)MP4文件两种格式AVC1和H264的区别及利用FFMPEG demux为h264码流事项

    出自:http://www.mworkbox.com/wp/work/314.html 2013-05-04 MP4的视频H264封装有2种格式:h264和avc1,对于这个细节,很容易被忽略.笔者也 ...

随机推荐

  1. Web实时更新客户端数据

    1        轮询方式实现客户端数据及时更新 在基于Web的即时通信.股票行情这样的系统中,需要客户端能够及时更新内容.由于B/S架构的特性(Http连接是无状态连接, 即服务器处理完客户的请求, ...

  2. Spring Messaging 远程命令执行漏洞(CVE-2018-1270)

    影响版本 Spring Framework 5.0 to 5.0.4 Spring Framework 4.3 to 4.3.14 参考 https://www.it610.com/article/1 ...

  3. 破解网站码验证,Java实现,不调用任何平台api接口

    package image.images; import java.io.File; import java.io.IOException; import java.io.InputStream; i ...

  4. 论文笔记:(ICML2020)On Learning Sets of Symmetric Elements

    目录 摘要 一.引言 二.先前的工作 三.基础 3.1 符号和基本定义 3.2 G-不变网络 3.3 描述等变层 3.4 Deep sets 四.DSS层 4.1 对称元素集合 4.2 等变层的表征 ...

  5. 痞子衡嵌入式:ARM Cortex-M内核那些事(9.1)- 存储保护(MPU - PMSAv6/7)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Cortex-M存储保护模块(MPU). <ARM Cortex-M内核MCU开发那些事>的内核篇连载最早是 201 ...

  6. LeetCode通关:数组十七连,真是不简单

    分门别类刷算法,坚持,进步! 刷题路线参考:https://github.com/chefyuan/algorithm-base       https://github.com/youngyangy ...

  7. 浅谈Java迭代器

    迭代器Iterator 概述: 迭代器(Iterator):它不是一个容器,它是一种用于访问容器的方法,可用于迭代 List.Set和Map等容器. 迭代:一个一个的往外拿. 作用:帮我们遍历或者拿到 ...

  8. 使用POI导出Word(含表格)的实现方式及操作Word的工具类

    .personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...

  9. Golang语言系列-09-接口

    接口 接口的定义和实现 package main import "fmt" /* [接口] 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现 ...

  10. Java通过SSLEngine与NIO实现HTTPS访问

    Java使用NIO进行HTTPS协议访问的时候,离不开SSLContext和SSLEngine两个类.我们只需要在Connect操作.Connected操作.Read和Write操作中加入SSL相关的 ...