视频播放指南

在阅读本节内容前,请确保你已经阅读并理解了臻云极致最佳实践。那么现在的问题是,你已经通过获取视频地址接口拿到了视频的播放地址,但究竟该如何播放呢?

RTSP和FLV该如何选择?

实时流传输协议(RTSP:Real Time Streaming Protocol)是一种网络传输协议,旨在发送低延迟流,是实时流视频的绝佳选择。在交通监控、安防、甚至家庭监控领域,RTSP都是使用最为广泛的一个协议。所以RTSP最大的一个优点就是延迟低、实时性高,但是缺点也很突出,就是不支持Chrome浏览器播放(或者无控件播放)。

FLV是被众多新一代视频分享网站所采用,是增长最快、最为广泛的视频传播格式,其最大的优点就是支持网页无控件播放。通常情况下,根据传输方式不同,分为HTTP-FLV(通过HTTP协议传输)和WS-FLV(通过WebSocket协议传输),臻识设备目前支持的是WS-FLV。

基于以上的介绍,在RTSP和FLV上如何选择,可以参考以下建议:

  • 如果开发的是PC端桌面程序,建议选择RTSP。
  • 如果开发的是浏览器网页程序、移动端APP,建议选择FLV。

如何播放RTSP?

如果您开发的是Windows桌面程序,建议您直接使用我们的一体机SDK,可以方便快速的完成视频播放。 image.png

如果您使用的是java开发语言,建议您直接使用javacv即可播放RTSP视频流,代码示例如下:

public static void main(String[] args) throws IOException {
  String file = "rtsp://192.168.6.171:8557/sub_stream_1";
  FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(file);
  grabber.setOption("rtsp_transport", "tcp");
  grabber.setImageWidth(960);
  grabber.setImageHeight(540);
  System.out.println("grabber start");
  grabber.start();

  CanvasFrame canvasFrame = new CanvasFrame("RTSP播放DEMO");
  canvasFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  canvasFrame.setAlwaysOnTop(true);
  OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
  while (true) {
    Frame frame = grabber.grabImage();
    opencv_core.Mat mat = converter.convertToMat(frame);
    canvasFrame.showImage(frame);
  }
}

如何在网页上播放FLV?

网上有非常多库都支持在网页上播放FLV,比如大名鼎鼎的由哔哩哔哩开发的flv.js、由青犀TSINGSEE开发的EasyPlayer.js、开源项目Jessibuca等等,但究竟该如何选择呢?

选择之前,我们要先了解一个最基本的事实,那就是原生的HTML5的<video>元素无法直接播放flv视频流,其实原生的HTML5的<video>元素能够播放的视频格式非常有限,比如mp4webmogg等格式。

那么,HTML5是不是就没办法播放FLV视频流了呢?肯定不是,不然怎么会出现这么多播放FLV的库呢?但所有这些播放FLV的库,其实现思路无非不过两种:MSE和WASM。

在介绍这两种技术之前,先要弄清楚两个概念:

  • 容器(Container):就是一种文件格式,比如flv、mkv、mp4等。
  • 编解码(Codec):就是一种视频的编解码方式,比如h264、h265等。

所以我们在播放FLV视频流时,是先将h264编码的流从flv这个容器中解析出来,这个过程叫Demux,然后再用h264的解码器将流解码为可直接观看的画面,这个过程叫Decode。相反的,设备在推送FLV视频流时,是先将摄像头采集到画面编码(Encode)为h264流,再放入flv的容器,这个过程叫Remux。

MSE

MSE(Media Source Extensions),提供了实现无插件且基于 Web 的流媒体的功能。使用 MSE,媒体串流能够通过 JavaScript 创建,并且能通过使用<audio><video>元素进行播放。简单点说,其播放FLV的流程如下:

  • 通过JS接收FLV的视频流;
  • 解析FLV封装,得到H264码流(Demux);
  • 将H264码流封装为一个个的MP4文件(Remux);
  • 再提供给HTML5进行播放(由浏览器进行Decode)。

WASM

WASM是WebAssembly的简称,是一种使用非 JavaScript 代码,并使其在浏览器中运行的方法。这些代码可以是 C、C++ 或 Rust 等。它们会被编译进你的浏览器,在你的 CPU 上以接近原生的速度运行。这些代码的形式是二进制文件,你可以直接在 JavaScript 中将它们当作模块来用。

我们已经知道如何通过MSE来播放FLV,但从流程上来,我们需要先Demux FLV,然后再Remux MP4,最后才能交由浏览器来Decode。那我们能不能Demux FLV得到h264流以后直接Decode呢?当然是可以的,这就是通过WASM来实现的方案。

要知道流的解码工作其实并不简单,其对CPU资源需求很大,那么JavaScript能不能担任这个解码工作呢?我认为或许可行,但是没有意义,因为我们写的JavaScript代码会被运行在浏览器的一个线程里,如果这个JavaScript代码占用大量的CPU资源,那么就无法响应我们在浏览器页面的各种事件,导致页面异常卡顿,其次JavaScript本身是解释型语言,拿来做视频流解码肯定不是最优方案,更何况去实现一套复杂的解码逻辑。

所以,WASM技术就能完美的解决这个问题,我们都知道FFmpeg是领先的多媒体框架,能够解码、编码、转码、混合、解密、流媒体、过滤和播放人类和机器创造的几乎所有东西。我们完全可以将FFmpeg编译为WASM为我们提供解码h264的能力,所以,通过这种方式播放FLV的流程如下:

  • 通过JS接收FLV的视频流;
  • 解析FLV封装,得到H264码流(Demux);
  • 通过WASM解码H264进行播放(Decode)。

抉择

在了解完MSE和WASM两种播放思路后,你很可能会问:WASM从流程上感觉比MSE精简不少,是不是可以说WASM比MSE更好? 答案就是,不能一概而论。

MSE虽然流程上更复杂,但是解码工作是交由浏览器来做,而浏览器在实现上会充分利用操作系统和硬件提供的能力来优化解码流程(简单点说,浏览器会充分利用硬件加速能力),所以我们也把此方式称为硬解

相反的,WASM虽然流程上更简单,但是解码工作全靠代码实现,同时它是运行在一个沙箱化的执行环境中,所以它无法利用硬件加速能力,我们也把此方式称为软解

所以,我们根据理论和实践,得出了如下的结论,供您参考:

  • 通过WASM方式来播放,其延迟相对较低(2s以内,甚至更小),但是CPU资源的占用相对较高,这就决定了同时播放多路视频对CPU的资源需求会很高,Jessibuca就是采用的这种方式。
  • 通过MSE方式来播放,因为其流程更复杂,所以延迟相对来说会更高(2s以上,甚至更大),但是由于其会利用硬件加速功能,所以CPU的占用会比WASM低,哔哩哔哩的flv.js就是采用的这种方式。

results matching ""

    No results matching ""