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...