使用 Gstreamer 进行网络直播
我正在尝试将实时输入流式传输到本地托管的网页。
我想这应该很容易,但我不明白我错在哪里。
这是我的设置:
- 具有良好视频功能的 DSLR 相机,
- 运行最新的 Raspbian 的 Rpi
在软件方面:
- Gphoto2(完美工作)捕获视频并将其传输到...
- ffmpeg,使用 v4l2 将其获取为/dev/video0
- Gstreamer 实际流式传输(在使用 ffserver 多次尝试失败后)
以下命令行捕获视频。它有效:
gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -threads 0 -f v4l2 /dev/video0
这工作得很好(有 2 秒的延迟,但我可以忍受,特别是如果我以后可以降低视频质量)。
我有一个在端口 8080 上运行的 http 服务器(我安装了几个用于测试目的:Apache、lighttpd,甚至是 python3 -m http.server 8080
命令),这似乎没有任何影响关于我的问题。
现在是有趣的部分。
我尝试了一种使用 m3u8 文件和多个小视频片段加载并在 js 播放器中顺序播放的方法。
这是 test1.html
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>My live video</title>
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
</head>
<body>
<h1>My live video - simple HLS player</h1>
<video-js id="video_id" class="vjs-default-skin" controls preload="auto" width="640" height="360">
<source src="http://192.168.1.179:8080/playlist.m3u8" type="application/x-mpegURL">
</video-js>
<script src="https://unpkg.com/video.js/dist/video.js"></script>
<script src="https://unpkg.com/@videojs/http-streaming/dist/videojs-http-streaming.js"></script>
<script>
var player = videojs('video_id');
</script>
</body>
</html>
和 gstreamer 调用:
gst-launch-1.0 v4l2src device="/dev/video0" ! queue leaky=1 ! \
videoconvert ! clockoverlay ! \
x264enc tune=zerolatency ! mpegtsmux ! \
hlssink playlist-location /home/pi/test/
playlist-root=http://192.168.1.179:8080 location=/home/pi/test/segment_%05d.ts target-duration=5 max-files=5
这实际上“有效”,但负载和延迟变得难以忍受(大约 30 秒以上的延迟)。
现在,我认为让事情变得简单会更好,所以我尝试简单地使用 HTTP 流。
所以我写了一个 test2.html,其中有一个 标签,指向我将在端口 9090 上传递的流:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>gst-stream</title>
</head>
<body>
<video width=320 height=240 autoplay>
<source src="http://192.168.1.179:9090">
</video>
</body>
</html>
And the Gstreamer invocation (I also tried the `udpsink` option, without success):
gst-launch-1.0 v4l2src device="/dev/video0" ! queue leaky=1 ! \
videoconvert ! videoscale ! video/x-raw,width=320,height=240 \
! clockoverlay shaded-background=true font-desc="Sans 38" \
! theoraenc ! oggmux ! tcpserversink host=127.0.0.1 port=9090
这只会带来一个空白页面(视频嵌入空间就在那里,只是空白) 。尝试通过 VLC 打开它,但是失败了,除了一条“无法打开媒体”消息之外什么也没有。 根据 HTTP 服务器日志,页面实际上已加载。
我想端口 9090 上实际上没有任何流式传输,但 Gstreamer 继续运行,就像它完美地完成了它的工作一样......
我做错了什么?
I'm trying to stream a live input to a web page, hosted locally.
I guess it should be pretty easy but I can't get where I'm wrong.
Here's my setup:
- a DSLR camera with decent video capabilities
- a Rpi running an up-to-date Raspbian
On the software side:
- Gphoto2 (works perfectly) to grab the video and pipe it to...
- ffmpeg, with v4l2 to get it as /dev/video0
- Gstreamer to actually stream it (after several unsuccessful attempts with ffserver)
The following command line captures the video. It works:
gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -threads 0 -f v4l2 /dev/video0
This works quite well enough (with 2sec latency, but I could live with that, especially if I can downgrade the video quality later).
I have a http server running on port 8080 (I have several installed for test purposes: Apache, lighttpd, or even the python3 -m http.server 8080
command), this does not seem to have any influence on my problem.
Now the interesting part.
I tried a method using m3u8 file and multiple small video snips loaded and played sequentially in a js player.
Here's the test1.html
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>My live video</title>
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
</head>
<body>
<h1>My live video - simple HLS player</h1>
<video-js id="video_id" class="vjs-default-skin" controls preload="auto" width="640" height="360">
<source src="http://192.168.1.179:8080/playlist.m3u8" type="application/x-mpegURL">
</video-js>
<script src="https://unpkg.com/video.js/dist/video.js"></script>
<script src="https://unpkg.com/@videojs/http-streaming/dist/videojs-http-streaming.js"></script>
<script>
var player = videojs('video_id');
</script>
</body>
</html>
and the gstreamer invocation:
gst-launch-1.0 v4l2src device="/dev/video0" ! queue leaky=1 ! \
videoconvert ! clockoverlay ! \
x264enc tune=zerolatency ! mpegtsmux ! \
hlssink playlist-location /home/pi/test/
playlist-root=http://192.168.1.179:8080 location=/home/pi/test/segment_%05d.ts target-duration=5 max-files=5
This actually "works" but the load and latency becomes unbearable (about 30+ seconds delay).
Now, I thought it would be better to keep things simple, so I tried to simply use a HTTP stream.
So I wrote a test2.html with a <video>
tag pointing to the stream I'll pass on port 9090:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>gst-stream</title>
</head>
<body>
<video width=320 height=240 autoplay>
<source src="http://192.168.1.179:9090">
</video>
</body>
</html>
And the Gstreamer invocation (I also tried the `udpsink` option, without success):
gst-launch-1.0 v4l2src device="/dev/video0" ! queue leaky=1 ! \
videoconvert ! videoscale ! video/x-raw,width=320,height=240 \
! clockoverlay shaded-background=true font-desc="Sans 38" \
! theoraenc ! oggmux ! tcpserversink host=127.0.0.1 port=9090
This only brings a blank page (the video embed space is there, just blank). Tried to open it through VLC, but this fails miserably with nothing but a "cannot open media" message.
The page is actually loaded, according to the HTTP server log.
I guess nothing is actually streamed on port 9090, but Gstreamer keeps going like it was doing its job flawlessly...
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论