I am currently working on a project where I aim to stream my webcam over my LAN and read the stream in an HTML5 video element with minimal setup. My setup involves a server (192.168.0.1 dev/video0 -> ffmpeg) and a client (192.168.0.2 html5 browser). I am using ffmpeg with the codec set to h264.
Here is the ffmpeg command I am using:
ffmpeg -f video4linux2 -i /dev/video0
-an -c:v libx264 -b:v 1024k -video_size 800x600 -pix_fmt yuv420p -preset ultrafast
-tune zerolatency -g 16 -keyint_min 16 -f mpegts pipe:1
This command is spawned by a simple Node.js server that shares this stream without any transformation (just pipe ffpmeg stream to each incoming connection).
When I use vlc or ffplay with the following command, it works very well:
ffplay -fflags nobuffer -flags low_delay -probesize 32 -analyzeduration 0 -framedrop http://192.168.0.1:3000/stream
I can even run multiple instances of ffplay and the video is properly played. However, when I try to use the HTML5 element like this:
<video src="http://127.0.0.1:3000/stream" type="video/mp4"></video>
The video seems to "load forever" without any error, nothing suspect in chrome://media-internals
. I can see in the network tab that the network is reading the stream, but the video does not play (got same result using hljs and videojs).
I am looking for help to understand:
- What is wrong with the
<video>
element in this context? - Is there a better approach to achieve this?
Any help or guidance would be greatly appreciated.
Your video is not playing because of the
-f mpegts
option.This means (MPEG's) TS container format. This means that your
<video>
tag is receiving some bytes of.ts
file data, instead of bytes of the usually expected.mp4
file data.Possible Solution(s):
(1) Use Safari browser to test your video tag setup since it has built-in decoding of TS container format.
note: If still failing to decode a TS file, then it means Safari expects an M3U8 playlist file (listing the URL of the stored TS file) which will not be possible in the case of piping bytes.
(2) If using
<video src="http://127.0.0.1:3000/stream">
then try this FFmpeg setup first:That will give you a fragmented MP4 container (as supported by all browsers) that you can play in the video tag like how your shown code is expecting to do...