WebM格式视频流播放可以通过HTML5在浏览器中实现,目前Chrome和FireFox都已经支持了该视频格式。WebM解码器在VP8引擎中实现,并且针对互联网特点做了很多优化。优点是在HTML5中实现,真正的实现了平台无关性,所有采用VP8引擎的浏览器都可以直接播放WebM格式的视频。当然很多浏览器并非VP8引擎的,而且没有哪个知名的流服务器支持WebM。这也是WebM的窘境。现在介绍一下大名鼎鼎的如何用FFmpeg作为WebM的流服务器。

0. FFserver

FFserver是一个流服务器,可以帮你将音视频内容转换成流在互联网上传输。它能够收集多个输入流,并转码->重铸->广播每一个流。如下图所示,

多个输入源被“喂”到广播服务器,这些多媒体内容就会分发到多个客户端。上图的目的是显示地表明你的流系统能够被分成多个块部署到网络上,允许你广播不同的在线内容,而不需要改变流媒体系统的结构。

FFserver有以下四个组成部分:输入源(Input sources)、供稿方(Feeds)、流组件(Streams)、媒体播放器(Media Player)。如下图所示

输入源(Input Source)

输入源并非是ffserver内部结构的一部分,通常倾向于使用外部应用发送音视频流到ffserver。由于FFmpeg大多用于输入源,本文以ffmpeg为例。首先输入源将连接到服务器并将自己绑定给一个供稿方。这里一个供稿方只能绑定一个源,因此只有供稿方未绑定时,才能接入输入源。一个输入源可以允许绑定到多个供稿方,但是只有输入源需要产生多个流媒体时,这样做才是有意义的。输入源提供相同的流媒体给不同的供稿方是无意义的,因为ffserver可以将供稿方提供给不同的流媒体。

供稿方(Feed)

供稿方是ffserver内部的一个组件,他的目的是将一个输入流绑定给一个或者多个输出流。将一个供稿方绑定给多个输出流是有意义的,因为你可能会需要这个输出流同时输出不同的多媒体格式。简单来说,每一个供稿方逻辑上代表了一个输入流。

流组件(Stream)

一个流组件是ffserver的一个内部组件,表示一个接入点,任何一个希望观看这个流的客户端都可以接入。举例来讲,对于同一个输入流,如果你希望输出一个高清视频和一个小尺寸的手机视频,你就可以将这个供稿方绑定到两个流组件上。供稿方和刘组件最大的区别是一个流组件可以与客户端建立多条连接,而一个供稿方通常只连接一个流组件。

播放器不是ffserver的组成部分,他只是代表了连接到流媒体服务器关心媒体内容的客户端。

1. 配置FFserver

当客户端机器实际的接入时,FFserver将成为一个守护进程。它需要足够的带宽向所有连接的客户端传输视频流。视频流编码通过FFmpeg实现,所以运行FFserver的主机并不需要很强的计算能力。

下面是FFserver.conf的一个例子,服务器定义了一个Feed和一个Stream。Feed作为流的输入源头,向Stream输出视频。Stream接收来自Feed的流,转码为WebM格式,根据定义的比特率和编解码器实现编码。客户端通过访问Stream就可以获得WebM的直播流。服务器的另一个组件是status.xml,用于观察各个流的状态。

Port 8090                      # Port to bind the server to
BindAddress 0.0.0.0
MaxHTTPConnections 2000
MaxClients 1000
MaxBandwidth 10000             # Maximum bandwidth per client
                               # set this high enough to exceed stream bitrate
CustomLog -
NoDaemon                       # Remove this if you want FFserver to daemonize after start
<Feed feed1.ffm>               # This is the input feed where FFmpeg will send
   File ./feed1.ffm            # video stream.
   FileMaxSize 64M              # Maximum file size for buffering video
   ACL allow 127.0.0.1         # Allowed IPs
</Feed>
<Stream test.webm>              # Output stream URL definition
   Feed feed1.ffm              # Feed from which to receive video
   Format webm
   # Audio settings
   AudioCodec vorbis
   AudioBitRate 64             # Audio bitrate
   # Video settings
   VideoCodec libvpx
   VideoSize 720x576           # Video resolution
   VideoFrameRate 25           # Video FPS
   AVOptionVideo flags +global_header  # Parameters passed to encoder
                                       # (same as ffmpeg command-line parameters)
   AVOptionVideo cpu-used 0
   AVOptionVideo qmin 10
   AVOptionVideo qmax 42
   AVOptionVideo quality good
   AVOptionAudio flags +global_header
   PreRoll 15
   StartSendOnKey
   VideoBitRate 400            # Video bitrate
</Stream>
<Stream status.html>            # Server status URL
   Format status
   # Only allow local people to get the status
   ACL allow localhost
   ACL allow 192.168.0.0 192.168.255.255
</Stream>
<Redirect index.html>    # Just an URL redirect for index
   # Redirect index.html to the appropriate site
   URL http://www.ffmpeg.org/
</Redirect>

2. 向FFserver接入视频流

FFserver启动之后,需要向http://localhost:8090/feed1.ffm接入视频流。注意,这里不需要指定编码格式,FFserver会重新编码。

视频流的来源可以是文件、摄像头或者录制屏幕。

1 比如从文件获得一个视频流并接入到FFM中。

 ffmpeg -i testvideo.mp4 http://localhost:8090/feed1.ffm

 这样ffmpeg将从testvideo中获取视频,并发送到feed1.ffm中,然后Stream对feed1.ffm编码。如果希望ffmpeg以视频预设的帧率来feed数据,就需要用-re命令强制按照时间戳feed视频数据。如

ffmpeg -re -i testvideo.mp4 http://localhost:8090/feed1.ffm

 运行结果如下:

built on Sep
9 2013 15:23:52 with gcc 4.4.7 (Ubuntu/Linaro 4.4.7-2ubuntu1) configuration: --prefix=/usr/local/ffmpeg --enable-shared --enable-nonfree --enable-gpl --enable-pthreads --disable-yasm --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libvpx --enable-x11grab --extra-cflags=-I/usr/local/ffmpeg/include/ --extra-ldflags=-L/usr/local/ffmpeg/lib --enable-version3 --extra-version=syslin libavutil 52. 43.100 / 52. 43.100 libavcodec 55. 31.101 / 55. 31.101 libavformat 55. 16.101 / 55. 16.101 libavdevice 55. 3.100 / 55. 3.100 libavfilter 3. 84.100 / 3. 84.100 libswscale 2. 5.100 / 2. 5.100 libswresample 0. 17.103 / 0. 17.103 libpostproc 52. 3.100 / 52. 3.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'testvideo.mp4': Metadata: major_brand : isom minor_version : 1 compatible_brands: isomavc1 creation_time : 2013-07-14 17:16:27 Duration: 00:03:14.75, start: 0.000000, bitrate: 392 kb/s Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 255 kb/s, 20 fps, 20 tbr, 20k tbn, 40 tbc (default) Metadata: creation_time : 2013-07-14 17:16:27 handler_name : mctemp69368b9542f0253c7.264#video:fps=20:par=1:1 - Imported with GPAC 0.5.0-rev4065 Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 135 kb/s (default) Metadata: creation_time : 2013-07-14 17:16:27 handler_name : GPAC ISO Audio Handler [libvpx @ 0x9bd940] v1.1.0 Output #0, ffm, to 'http://localhost:8090/feed1.ffm': Metadata: major_brand : isom minor_version : 1 compatible_brands: isomavc1 creation_time : now encoder : Lavf55.16.101 Stream #0:0(und): Audio: vorbis (libvorbis), 22050 Hz, mono, fltp, 64 kb/s (default) Metadata: creation_time : 2013-07-14 17:16:27 handler_name : GPAC ISO Audio Handler Stream #0:1(und): Video: vp8 (libvpx), yuv420p, 720x576 [SAR 16:15 DAR 4:3], q=10-42, 400 kb/s, 1000k tbn, 20 tbc (default) Metadata: creation_time : 2013-07-14 17:16:27 handler_name : mctemp69368b9542f0253c7.264#video:fps=20:par=1:1 - Imported with GPAC 0.5.0-rev4065 Stream mapping: Stream #0:1 -> #0:0 (aac -> libvorbis) Stream #0:0 -> #0:1 (h264 -> libvpx) Press [q] to stop, [?] for help frame= 11 fps=1.9 q=0.0 size= 4kB time=00:00:00.41 bitrate= 78.9kbits/s frame= 13 fps=2.0 q=0.0 size= 4kB time=00:00:00.41 bitrate= 78.9kbits/s frame= 16 fps=2.2 q=0.0 size= 4kB time=00:00:00.41 bitrate= 78.9kbits/s frame= 18 fps=2.2 q=0.0 size= 4kB time=00:00:00.41 bitrate= 78.9kbits/s frame= 19 fps=2.1 q=0.0 size= 4kB time=00:00:00.43 bitrate= 74.8kbits/s frame= 22 fps=2.3 q=0.0 size= 4kB time=00:00:00.90 bitrate= 36.3kbits/s frame= 25 fps=2.4 q=0.0 size= 16kB time=00:00:00.90 bitrate= 145.2kbits/s frame= 26 fps=2.2 q=0.0 size= 20kB time=00:00:00.90 bitrate= 181.5kbits/s frame= 27 fps=2.2 q=0.0 size= 20kB time=00:00:00.90 bitrate= 181.5kbits/s frame= 35 fps=2.7 q=0.0 size= 24kB time=00:00:01.39 bitrate= 141.4kbits/ ......

2 录制屏幕并接入到FFM中

ffmpeg -f x11grab -r 25 -s 640x512 -i :0.0 -f alsa -i pulse http://localhost:8090/feed1.ffm

这里有两个-f,第一个指的是视频流,第二个指的是音频流。视频流是抓取屏幕形成视频,-r设置帧率为25帧/s,-s设置抓取图像大小为640x512,-i设置录制视频的初始坐标。音频流设置为alsa(Advanced Linux Sound Architecture),从Linux系统中获取音频。这其中这样ffmpeg可以录制屏幕feed到feed1.ffm中。运行结果如下:

built on Sep 9 2013 15 : 23 : 52 with gcc 4.4 . 7 (Ubuntu/Linaro 4.4 . 7 - 2ubuntu1) configuration: --prefix=/usr/local/ffmpeg --enable-shared --enable-nonfree --enable-gpl --enable-pthreads --disable-yasm --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libvpx --enable-x11grab --extra-cflags=-I/usr/local/ffmpeg/include/ --extra-ldflags=-L/usr/local/ffmpeg/lib --enable-version3 --extra-version= syslin libavutil 52 . 43.100 / 52 . 43.100 libavcodec 55 . 31.101 / 55 . 31.101 libavformat 55 . 16.101 / 55 . 16.101 libavdevice 55 . 3.100 / 55 . 3.100 libavfilter 3 . 84.100 / 3 . 84.100 libswscale 2 . 5.100 / 2 . 5.100 libswresample 0 . 17.103 / 0 . 17.103 libpostproc 52 . 3.100 / 52 . 3.100 [x11grab @ 0x221d280 ] device: : 0.0 -> display: : 0.0 x: 0 y: 0 width: 640 height: 512 [x11grab @ 0x221d280 ] shared memory extension found Input # 0 , x11grab, from ' :0.0 ' : Duration: N /A, start: 1378727353.224054 , bitrate: 314258 kb/ s Stream # 0 : 0 : Video: rawvideo (BGR[ 0 ] / 0x524742 ), bgr0, 64 0x512 , 314258 kb/s, 29.97 tbr, 1000k tbn, 29.97 tbc Guessed Channel Layout for Input Stream # 1.0 : stereo Input # 1 , alsa, from ' pulse ' : Duration: N /A, start: 1378727353.299919 , bitrate: 1536 kb/ s Stream # 1 : 0 : Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/ s [swscaler @ 0x21ff040 ] deprecated pixel format used, make sure you did set range correctly [libvpx @ 0x225e100 ] v1. 1.0 Output # 0 , ffm, to ' http://localhost:8090/feed1.ffm ' : Metadata: creation_time : now encoder : Lavf55. 16.101 Stream # 0 : 0 : Audio: vorbis (libvorbis), 22050 Hz, mono, fltp, 64 kb/ s Stream # 0 : 1 : Video: vp8 (libvpx), yuv420p, 72 0x576 , q= 10 - 42 , 400 kb/s, 1000k tbn, 29.97 tbc Stream mapping: Stream # 1 : 0 -> # 0 : 0 (pcm_s16le -> libvorbis) Stream # 0 : 0 -> # 0 : 1 (rawvideo -> libvpx) Press [q] to stop, [ ?] for help frame = 22 fps= 0.0 q= 0.0 size= 4kB time = 00 : 00 : 00.44 bitrate= 73 .0kbits/ s frame = 37 fps= 36 q= 0.0 size= 160kB time = 00 : 00 : 00.92 bitrate= 1411 .3kbits/ s frame = 51 fps= 33 q= 0.0 size= 220kB time = 00 : 00 : 01.28 bitrate= 1405 .5kbits/ s frame = 66 fps= 32 q= 0.0 size= 284kB time = 00 : 00 : 01.40 bitrate= 1660 .1kbits/ s ......

3 从摄像头获取视频发送到feed1.ffm中

ffmpeg -f video4linux2 -s 640x480 -r 25 -i /dev/video0 -f alsa -i pulse http://localhost:8090/feed1.ffm

 video4linux2是负责从摄像头中获取视频的插件,/dev/video0就是摄像头映射的文件。运行结果如下

built on Sep 9 2013 15:23:52 with gcc 4.4.7 (Ubuntu/Linaro 4.4.7-2ubuntu1) configuration: --prefix=/usr/local/ffmpeg --enable-shared --enable-nonfree --enable-gpl --enable-pthreads --disable-yasm --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libvpx --enable-x11grab --extra-cflags=-I/usr/local/ffmpeg/include/ --extra-ldflags=-L/usr/local/ffmpeg/lib --enable-version3 --extra-version=syslin libavutil 52. 43.100 / 52. 43.100 libavcodec 55. 31.101 / 55. 31.101 libavformat 55. 16.101 / 55. 16.101 libavdevice 55. 3.100 / 55. 3.100 libavfilter 3. 84.100 / 3. 84.100 libswscale 2. 5.100 / 2. 5.100 libswresample 0. 17.103 / 0. 17.103 libpostproc 52. 3.100 / 52. 3.100 [video4linux2,v4l2 @ 0xdc03c0] The V4L2 driver changed the video from 640x512 to 640x480 [video4linux2,v4l2 @ 0xdc03c0] The driver changed the time per frame from 1/25 to 1/30 Input #0, video4linux2,v4l2, from '/dev/video0': Duration: N/A, start: 415.173405, bitrate: 147456 kb/s Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x480, 147456 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc Guessed Channel Layout for Input Stream #1.0 : stereo Input #1, alsa, from 'pulse': Duration: N/A, start: 1378794986.966378, bitrate: 1536 kb/s Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s [libvpx @ 0xde7f20] v1.1.0 Output #0, ffm, to 'http://172.26.176.6:8090/video.ffm': Metadata: creation_time : now encoder : Lavf55.16.101 Stream #0:0: Audio: vorbis (libvorbis), 22050 Hz, mono, fltp, 64 kb/s Stream #0:1: Video: vp8 (libvpx), yuv420p, 720x576, q=10-42, 400 kb/s, 1000k tbn, 25 tbc Stream mapping: Stream #1:0 -> #0:0 (pcm_s16le -> libvorbis) Stream #0:0 -> #0:1 (rawvideo -> libvpx) Press [q] to stop, [?] for help frame= 15 fps=0.0 q=0.0 size= 4kB time=00:00:00.42 bitrate= 77.5kbits/s frame= 27 fps= 27 q=0.0 size= 16kB time=00:00:00.79 bitrate= 165.8kbits/s frame= 40 fps= 27 q=0.0 size= 32kB time=00:00:01.27 bitrate= 205.4kbits/s ......
WebM 格式 视频 流播放可以通过HTML5在浏览器中 实现 ,目前Chrome和FireFox都已经支持了该 视频 格式 WebM 解码器在VP8引擎中 实现 ,并且针对互联网特点做了很多优化。优点是在HTML5中 实现 ,真正的 实现 了平台无关性,所有采用VP8引擎的浏览器都可以直接播放 WebM 格式 视频 。当然很多浏览器并非VP8引擎的,而且没有哪个知名的流 服务器 支持 WebM 。这也是 WebM 的窘境。现在介绍一下大名... 1. 什么是 webM 要说 webM ,先说Matroska,Matroska是一个可扩展的,开源的多媒体容器(说简单点,容器的作用,就是把 视频 和音频封装到一个文件)。使用这种容器的常见文件,一个是MKV,一个就是 webM 。两者的区别,无非是支持的音 视频 编码不一样,但封装原理都一样。 更多的Matroska介绍,见官网:https://matroska.org/index.html webM 的音 视频 支持: 视频 编码:支持VP8或VP9 音频编码:支持Vorbis 或 Opus 要说Matroska,那又离不开E 推荐一个创新的JavaScript WebM 视频 编码器 - WebM Writer for JavaScript 项目地址:https://gitcode.com/thenickdude/ webm -writer-js 在这个数字化的时代,创作和分享动态视觉内容变得越来越便捷。如果你正寻找一种高效的方法将一系列Canvas帧转化为高质量的 WebM 视频 ,那么这个开源项目—— WebM Writer fo... 搭建流媒体 服务器 的方法有多种,前面介绍过在windows环境下使用VLC搭建流媒体服务(参见:Win10环境:使用VLC搭建RTSP 服务器 )。今天是第二篇,使用 ffserver ,下面是 ffserver 官网关于 ffserver 的介绍,详细见: ffserver document ffserver is a streaming server for both audio and video. I... 刚开始学习组播、 直播 方面的东西,简单总结一下利用ffmpeg+ ffserver 做电视信号流媒体实时 直播 。 总体架构就是dvb-IP网关将电视cable信号解扰解复用之后,读到ARM的内存缓冲区中,之后利用ffmpeg做 视频 推流, ffserver 作为流媒体 服务器 。而在客户端,可以通过VLC或者ffplay打开 直播 视频 ,也可以利用IE加载VLC activex控件 实现 网页上播放。这样的纯HTTP播放方式,由于ts封装在网页 实现 播放可能比较麻烦,hls的 实现 可以参考下一篇文章《ffmpeg+nginx搭建HLS服 在本文中,我们将介绍如何使用JavaCV库 实现 WebM 直播 服务,无需依赖流媒体 服务器 或MSE转封装插件。通过这种方式,我们可以直接在支持 WebM 格式 的浏览器中使用video标签播放RTSP、RTMP和桌面投屏的 视频 流。对象,指定了要推送到的RTMP流的地址、 视频 宽度和高度以及 视频 编码器的类型。在循环中,我们将每一帧屏幕图像推送到RTMP流,并使用。对象,指定了要推送到的RTMP流的地址、 视频 宽度和高度以及 视频 编码器的类型。在循环中,我们将每一帧图像推送到RTMP流,并使用。然后,我们创建了一个。 本文介绍了如何使用JavaCV库 实现 一个 WebM 直播 服务,该服务可以直接在浏览器的video标签中播放RTSP、RTMP和桌面投屏的 视频 流。通过JavaCV提供的功能,我们可以避免依赖复杂的流媒体服务和MSE转封装插件,而直接在浏览器的video标签中播放RTSP、RTMP和桌面投屏的 视频 源。通过以上步骤,我们可以轻松搭建一个 WebM 直播 服务,并在前端进行实时播放。注意:本文只是提供了一个在浏览器端播放RTSP、RTMP和桌面投屏的简单示例,实际应用中可能需要根据具体需求做相应的修改和优化。 RTSPServer主要是采集摄像头和麦克风数据,进行H.264编码以及aac编码,并对外提供RTSP 直播 流。市场上成熟的RTSPserver组件很少见,其中EasyRTSPServer就是一款稳定、高效、可靠、多平台支持的RTSPServer组件。 在我们开发RTSP 视频 流的分发阶段,我们也考虑过如何使用 ffserver 分发RTSP 视频 流,如何搭建RTSP 服务器 ,除了EasyRTSPServer之外,我们探寻出了另外一条由 ffserver 为基础的道路。 ffmpeg提供了 ffserver 可以搭建RTS 《1》、输入源    能将音/ 视频 传给 ffserver 的外部应用,通常是ffmpeg应用。输入源会和 ffserver 连接然后将自己绑定到一个或多个feed上。(同一时刻一个feed只能绑定一个输入源)。一个输入源能绑到多个f...