how stream video into html5 <video>
Hello,
I would like to stream the video from csi camera module to html5 page hosted by apache server on raspberry pi.
I have read this blog http://www.recantha.co.uk/blog/?p=4165 but i don't understand how adapt it for html5 video
ps : I'm a noob
Thank you
I would like to stream the video from csi camera module to html5 page hosted by apache server on raspberry pi.
I have read this blog http://www.recantha.co.uk/blog/?p=4165 but i don't understand how adapt it for html5 video
ps : I'm a noob
Thank you
Re: how stream video into html5 <video>
as far as i know the html5 video tag just requires a correctly formatted stream. mp4, webm, ogg are the three that appear to be supported. the playback is browser dependent as not all browsers will play all the formats.
here is a good description: http://www.w3schools.com/html/html5_video.asp
it has sample html code, so should work with supported formats.
i have some experience with it in a streaming envoronment using mp4 format files but not with the raspberry pi, yet.
<caveat> i'm a noob too </caveat>
here is a good description: http://www.w3schools.com/html/html5_video.asp
it has sample html code, so should work with supported formats.
i have some experience with it in a streaming envoronment using mp4 format files but not with the raspberry pi, yet.
<caveat> i'm a noob too </caveat>
Re: how stream video into html5 <video>
Hello,
thank you for your reply, i will continue to search.
jericho
thank you for your reply, i will continue to search.
jericho
-
- Posts: 7
- Joined: Tue May 21, 2013 7:46 pm
Re: how stream video into html5 <video>
What you want to accomplish is called HTTP Live Streaming.
First, you need to get ffmpeg.
Under archlinux run
and confirm the installation of the required packages.
Second, you need a tool released on GitHub by AndyA. In short, it prepares the output of raspivid for HTTP Live Streaming. If you want more details on that, read README.md.
After obtaining the tool, you need to compile it from source by simply running the following commands:
This could take some minutes on a Raspberry Pi.
Lastly, you need to do some configuration. Therefore edit examples/hls.hs with your preferred text editor, like this:
- Change base=… on line 2 to some directory shared by your http server.
- Change "-c:a libfaac -b:a 128k \" to "-c:a aac -b:a 128k \"
- Change ""live/%08d.ts" < /dev/null" to "-strict 2 "live/%08d.ts" < /dev/null"
Then run the hls.sh script.
Point your webbrowser to the given location and append /live to it. Work flawlessly on Safari and iOS.
This also works if store the output on a shared directory. This is especially important due to the low capacity of the raspberry pi. (In general, you wont to store the files on a server instead of hooking up large usb disks to the Raspberry Pi.)
Downside is that there will be a delay of around 15 - 30 seconds. Depending on your intention this could be more or less critical.
This would also work on Debian, but since Debian used to ship very old versions of their packages you will need to compile the latest version of ffmpeg by hand.
First, you need to get ffmpeg.
Under archlinux run
Code: Select all
pacman -S ffmpeg
Second, you need a tool released on GitHub by AndyA. In short, it prepares the output of raspivid for HTTP Live Streaming. If you want more details on that, read README.md.
Code: Select all
pacman -S git
git clone https://github.com/AndyA/psips.git
Code: Select all
cd psips
./configure
make
make install
Lastly, you need to do some configuration. Therefore edit examples/hls.hs with your preferred text editor, like this:
Code: Select all
vim examples/hls.sh
- Change "-c:a libfaac -b:a 128k \" to "-c:a aac -b:a 128k \"
- Change ""live/%08d.ts" < /dev/null" to "-strict 2 "live/%08d.ts" < /dev/null"
Then run the hls.sh script.
Point your webbrowser to the given location and append /live to it. Work flawlessly on Safari and iOS.
This also works if store the output on a shared directory. This is especially important due to the low capacity of the raspberry pi. (In general, you wont to store the files on a server instead of hooking up large usb disks to the Raspberry Pi.)
Downside is that there will be a delay of around 15 - 30 seconds. Depending on your intention this could be more or less critical.
This would also work on Debian, but since Debian used to ship very old versions of their packages you will need to compile the latest version of ffmpeg by hand.
-
- Posts: 1
- Joined: Tue Jun 04, 2013 1:21 pm
Re:how to place button on video tag in html5
Hi to all,
i need idea how to customized video tag in html5.
(for eg)we need to place video controls on the div tag background with image or place button on the video tag..when we clicked button it will be displayed some image or play another video..am confused..pls help
i need idea how to customized video tag in html5.
(for eg)we need to place video controls on the div tag background with image or place button on the video tag..when we clicked button it will be displayed some image or play another video..am confused..pls help
Re: how stream video into html5 <video>
Hi tried this out, and all seemed to go well, but get this output with error when trying to run.
my script is as follows
using ffmpeg compiled from source, which works OK with other projects to stream the camera output
Code: Select all
pi@raspberrypi ~/psips/examples $ ./hls.sh
+ rm -rf live live.h264 /usr/share/nginx/www/live
+ mkdir -p live
+ ln -s /home/pi/psips/examples/live /usr/share/nginx/www/live
+ mkfifo live.h264
+ sleep 2
+ psips
+ raspivid -w 1280 -h 720 -fps 25 -hf -t 86400000 -b 1800000 -o -
+ ffmpeg -y -i live.h264 -f s16le -i /dev/zero -r:a 48000 -ac 2 -c:v copy -c:a aac -b:a 128k -map 0:0 -map 1:0 -f segment -segment_time 8 -segment_format mpegts -segment_list /usr/share/nginx/www/live.m3u8 -segment_list_size 720 -segment_list_flags live -segment_list_type m3u8 '-strict 2 live/%08d.ts < /dev/null'
ffmpeg version N-53853-g16f3102 Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 5 2013 17:10:38 with gcc 4.6 (Debian 4.6.3-14+rpi1)
configuration:
libavutil 52. 35.100 / 52. 35.100
libavcodec 55. 15.100 / 55. 15.100
libavformat 55. 8.102 / 55. 8.102
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 75.101 / 3. 75.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
Unrecognized option 'strict 2 live/%08d.ts < /dev/null'.
Error splitting the argument list: Option not found
pi@raspberrypi ~/psips/examples $
Code: Select all
pi@raspberrypi ~/psips/examples $ cat hls.sh
#!/bin/bash
base="/usr/share/nginx/www"
set -x
rm -rf live live.h264 "$base/live"
mkdir -p live
ln -s "$PWD/live" "$base/live"
# fifos seem to work more reliably than pipes - and the fact that the
# fifo can be named helps ffmpeg guess the format correctly.
mkfifo live.h264
raspivid -w 1280 -h 720 -fps 25 -hf -t 86400000 -b 1800000 -o - | psips > live.h264 &
# Letting the buffer fill a little seems to help ffmpeg to id the stream
sleep 2
# Need ffmpeg around 1.0.5 or later. The stock Debian ffmpeg won't work.
# I'm not aware of options apart from building it from source. I have
# Raspbian packags built from Debian Multimedia sources. Available on
# request but I don't want to post them publicly because I haven't cross
# compiled all of Debian Multimedia and conflicts can occur.
ffmpeg -y \
-i live.h264 \
-f s16le -i /dev/zero -r:a 48000 -ac 2 \
-c:v copy \
-c:a aac -b:a 128k \
-map 0:0 -map 1:0 \
-f segment \
-segment_time 8 \
-segment_format mpegts \
-segment_list "$base/live.m3u8" \
-segment_list_size 720 \
-segment_list_flags live \
-segment_list_type m3u8 \
"-strict 2 "live/%08d.ts" < /dev/null"
Re: how stream video into html5 <video>
Remove the outer pair of quotes on the last line of your script. Why are they there?
Re: how stream video into html5 <video>
Sorted my first problem. Extra quotes in the script last line.
Changed
"-strict 2 "live/%08d.ts" < /dev/null"
to
-strict 2 "live/%08d.ts" < /dev/null
still didn't work..then changed the line to
-strict -2 "live/%08d.ts" < /dev/null"
and restarted as the camera module seemed to have got a bit confused, and it started to produce .ts files as expected.
Now working on the final problems which seems to be permission errors for accessing the live directory via the link
made here in the script, as I'm getting a 403 error from the web-browser
ln -s "$PWD/live" "$base/live"
Changed
"-strict 2 "live/%08d.ts" < /dev/null"
to
-strict 2 "live/%08d.ts" < /dev/null
still didn't work..then changed the line to
-strict -2 "live/%08d.ts" < /dev/null"
and restarted as the camera module seemed to have got a bit confused, and it started to produce .ts files as expected.
Now working on the final problems which seems to be permission errors for accessing the live directory via the link
made here in the script, as I'm getting a 403 error from the web-browser
ln -s "$PWD/live" "$base/live"
Re: how stream video into html5 <video>
To browse a directory in a web browser with the "Index of live" listing you usually need to enable directory listing in your web servers configuration.
Re: how stream video into html5 <video>
I think I have solved the problem.
The issue was with the index.html file in the examples folder. I had copied this to the webserver directory I was using, but then noticed that it refers to the file index.m3u8 (which is also in the examples directory). In fact a populated m3u8 file called live.m3u8 is generated by the script (see the tag -segment_list "$base/live.m3u8" )
Thus I had to modify the index.html file to contain the line
<source src="live.m3u8" type="application/x-mpegURL" /> instead of
<source src="index.m3u8" type="application/x-mpegURL" />
Once I had done this everything worked and it is streaming nicely to my iphone, albeit with a 20 sec or so delay.
Very good picture quality
The issue was with the index.html file in the examples folder. I had copied this to the webserver directory I was using, but then noticed that it refers to the file index.m3u8 (which is also in the examples directory). In fact a populated m3u8 file called live.m3u8 is generated by the script (see the tag -segment_list "$base/live.m3u8" )
Thus I had to modify the index.html file to contain the line
<source src="live.m3u8" type="application/x-mpegURL" /> instead of
<source src="index.m3u8" type="application/x-mpegURL" />
Once I had done this everything worked and it is streaming nicely to my iphone, albeit with a 20 sec or so delay.
Very good picture quality
Re: how stream video into html5 <video>
I think this will only work on Apple browsers/operating systems. Any idea on how to adapt it to work across any OS?
--
Michael Horne - @recantha on Twitter
Raspberry Pi Pod blog - http://www.recantha.co.uk/blog
Cambridge Raspberry Jam - https://camjam.me
Pi Wars - https://piwars.org
Michael Horne - @recantha on Twitter
Raspberry Pi Pod blog - http://www.recantha.co.uk/blog
Cambridge Raspberry Jam - https://camjam.me
Pi Wars - https://piwars.org
Re: how stream video into html5 <video>
Hello,
Thank you for your help and sorry to reply later.
i have try the pips script bu i have this error message : Unknown encoder 'libfaac'
The ffmpeg version on the repository is old, so i have compiled the last version with this option:
and before i did the same thing for x264 & libaac
and
please help me. thank you
jericho
Thank you for your help and sorry to reply later.
i have try the pips script bu i have this error message : Unknown encoder 'libfaac'
The ffmpeg version on the repository is old, so i have compiled the last version with this option:
Code: Select all
./configure --enable-gpl --enable-libx264 --enable-nonfree --enable-libaacplus
Code: Select all
$ cd libaacplus-2.0.2
./autogen.sh --enable-shared --enable-static
sudo make
sudo make install
sudo ldconfig
Code: Select all
./configure --enable-static --enable-shared
sudo make
sudo make install
sudo ldconfig
jericho
Re: how stream video into html5 <video>
You compiled with the wrong bad AAC encoder. There’s a range of bad AAC encoders of which faac is the worst. Nowadays the only decent quality AAC audio encoder if fdk-aac, but anyway.jericho63 wrote:i have try the pips script bu i have this error message : Unknown encoder 'libfaac'
Andy said he encodes empty audio because he thinks some players require audio even if the audio track is empty. I cannot confirm that.
If you want you can delete this
Code: Select all
-f s16le -i /dev/zero -r:a 48000 -ac 2 \
Code: Select all
-c:a libfaac -b:a 128k \
Code: Select all
-map 0:0 -map 1:0 \
Code: Select all
-map 0:0 \
Re: how stream video into html5 <video>
Hello,
Thank you for your help, the script seem work well, i see the files appear in 'live' directory, but the html page don't work, i have this message
"no video with supported format and mime type found"
i execute the script with sudo ./hls.sh otherwise the rights seem not enough
Thank you for your help, the script seem work well, i see the files appear in 'live' directory, but the html page don't work, i have this message
"no video with supported format and mime type found"
i execute the script with sudo ./hls.sh otherwise the rights seem not enough
Re: how stream video into html5 <video>
I had a problem with the index file too. I quote what I said in an earlier postjericho63 wrote:Hello,
Thank you for your help, the script seem work well, i see the files appear in 'live' directory, but the html page don't work, i have this message
"no video with supported format and mime type found"
i execute the script with sudo ./hls.sh otherwise the rights seem not enough
The issue was with the index.html file in the examples folder. I had copied this to the webserver directory I was using, but then noticed that it refers to the file index.m3u8 (which is also in the examples directory). In fact a populated m3u8 file called live.m3u8 is generated by the script (see the tag -segment_list "$base/live.m3u8" )
Thus I had to modify the index.html file to contain the line
<source src="live.m3u8" type="application/x-mpegURL" /> instead of
<source src="index.m3u8" type="application/x-mpegURL" />
Re: how stream video into html5 <video>
Hello,
Yes i have already seen your message and made the same change.
Do you execute the script with sudo also?
Yes i have already seen your message and made the same change.
Code: Select all
<html>
<head>
<title>PiVid</title>
</head>
<body>
<video controls="controls" width="1280" height="720" autoplay="autoplay" >
<source src="live.m3u8" type="application/x-mpegURL" />
</video>
</body>
</html>
Re: how stream video into html5 <video>
Which browser?jericho63 wrote: "no video with supported format and mime type found"
Re: how stream video into html5 <video>
with firefox
Re: how stream video into html5 <video>
Wouldn’t work. It was mentioned further up that this type of HTML5 streaming only works with Apple browsers and some Android versions.
Mozilla and Google refuse to back this standard and back a different standard called MPEG DASH that is even less supported. Next up is MediaSource Javascript API, also not implemented fully.
So for HTML5 live streaming HLS with Apple or Android is your only chance. Otherwise it’s flash plugin and RTMP.
Mozilla and Google refuse to back this standard and back a different standard called MPEG DASH that is even less supported. Next up is MediaSource Javascript API, also not implemented fully.
So for HTML5 live streaming HLS with Apple or Android is your only chance. Otherwise it’s flash plugin and RTMP.
Re: how stream video into html5 <video>
Hello,
ok thank you
Jericho
ok thank you
Jericho
Re: how stream video into html5 <video>
I am reviving an old thread in order to post an update and see if anyone else has encountered the same issue as me. I have successfully implemented the HLS streaming using information contained here as well as from AndyA's Github. Some changes were needed to the .sh script to get everything functioning but PSIPS/FFMPEG combo works as it should. The one question I had is handling of old .ts segments. The segment list can be of aribitrary length however it appears that additional work needs to go on in the background to clean up the old segments else you will just fill up your SD card. I haven't found any info as to whether this is the appropriate behavior or not however if anyone can shine some light on this it would be very helpful. I was going to start by writing a python script that will parse the .m3u8 list for current segments and delete the old ones in the background.
Re: how stream video into html5 <video>
Code: Select all
‘-segment_wrap limit’
Wrap around segment index once it reaches limit.
docs here: http://ffmpeg.org/ffmpeg-all.html#segme ... c-ssegment
There’s also the simpler -f hls muxer that does pretty much the same thing with less options
docs here: http://ffmpeg.org/ffmpeg-all.html#hls-1
Re: how stream video into html5 <video>
Yes this would be a useful addition. I must confess I take the easy way out just now and have an nfs share mounted where I store the segments so space is not currently an issue. I delete them manually from time to time.The one question I had is handling of old .ts segments. The segment list can be of aribitrary length however it appears that additional work needs to go on in the background to clean up the old segments else you will just fill up your SD card.
Re: how stream video into html5 <video>
Glad someone else asked this question. I have been following this thread for a bit and I ran into this same issue. I solved it by making a quick python script that runs in a separate process to perodically check up on the files and trim out the old ones. I simply parse the m3u8 playlist and remove the old ones. It uses the modules os, sys, time and csv which should all be part of the standard python install.rbn wrote:Yes this would be a useful addition. I must confess I take the easy way out just now and have an nfs share mounted where I store the segments so space is not currently an issue. I delete them manually from time to time.The one question I had is handling of old .ts segments. The segment list can be of aribitrary length however it appears that additional work needs to go on in the background to clean up the old segments else you will just fill up your SD card.
For operation, it parses the playlist and will look for files in the directory you designate that stores your TS segments. I have it set for the default /usr/share/nginx/www/live. It compares the active files in the playlist with the files in the directory and deletes the ones which aren't referenced in the playlist. I just realized while I was writing this that it may run into a case where if a file is written to the directory before it is added to the playlist then it could be deleted in error. I rearranged the code to change the order and perhaps give it some extra time.
You can call it by simply adding the line
Code: Select all
python m3u8.py &
Adding arguments to denote location of files.
Using a variable to set # of segments and wait time in both the sh and python scripts. It currently waits for 60 seconds and then checks every 60 seconds. Operation is pretty lightweight although I am running this all on a headless model A that is only connected via SSH so I don't really see CPU usage during operation.
I compare current and old playlists to see if ffmpeg is still running. If there are no changes then I have it look for all segments and delete them as well as the playlist before it exits. Once ffmpeg exits/breaks it will take up to a minute for the python script to reach this point however it will print to the command line when it does. This isn't helpful for troubleshooting so comment those lines out if you want to keep your old segments on exit.
I use the standard folders for hosting everything on my pi
/usr/share/nginx - hls.sh and m3u8.py are saved here.
Remember to run the script as
Code: Select all
sudo sh hls.sh
Code: Select all
chmod 777 hls.sh
/usr/share/nginx/www - index.html is here as well as live.m3u8 which python needs
/usr/share/nginx/www/live - where the ts segments are stored
If your folders are different you will need to change them as necessary in a few different places.
Huge thanks to AndyA for all of his work on this. Rockstar!
Code: Select all
## m3u8.py will parse an m3u8 playlist and remove files which aren't referenced in that playlist.
import os
import sys
import time
import csv
def main():
print 'm3u8.py running\n'
time.sleep(60)
www = '/usr/share/nginx/www'
live = www + '/live'
m3u8 ='/usr/share/nginx/www/live.m3u8'
old_playlist = []
while True:
loc = os.path.abspath(live)
segments = []
for files in os.listdir(loc):
if files.endswith('TS') or files.endswith('ts'):
segments.append(files)
with open(m3u8,'rb') as rawFile:
#Read in CSV object
newData = csv.reader(rawFile)
dataList = []
dataList.extend(newData)
playlist = []
for rows in dataList:
data = rows
if rows[0][-3:] == '.ts':
data = rows[0][5:]
#print data
#print ' '
playlist.append(data)
# print playlist
if old_playlist == playlist:
print 'stream failed'
if segments:
for files in segments:
segment = live + '/' + files
try:
os.remove(segment)
except OSError:
print 'Cannot remove ' + files
try:
os.remove(m3u8)
except OSError:
print 'cannot remove playlist'
sys.exit()
for files in segments:
if not files in playlist:
segment = live + '/' + files
try:
os.remove(segment)
except OSError:
print 'OSError'
old_playlist = playlist
time.sleep(60)
if __name__ == "__main__":
main()
Code: Select all
#!/bin/bash
base="/usr/share/nginx/www"
set -x
rm -rf live live.h264 "$base/live"
mkdir -p live
ln -s "$PWD/live" "$base/live"
# fifos seem to work more reliably than pipes - and the fact that the
# fifo can be named helps ffmpeg guess the format correctly.
raspistill -w 1280 -h 720 -t 100 -vf -hf -o "$base/poster.jpg"
mkfifo live.h264
raspivid -w 1280 -h 720 -fps 25 -hf -vf -t 86400000 -b 1800000 -o - | psips > live.h264 &
# Letting the buffer fill a little seems to help ffmpeg to id the stream
sleep 2
# Need ffmpeg around 1.0.5 or later.
python m3u8.py &
ffmpeg -y \
-i live.h264 \
-f s16le -i /dev/zero -r:a 48000 -ac 2 \
-c:v copy \
-c:a aac -b:a 128k \
-map 0:0 -map 1:0 \
-f segment \
-segment_list "$base/live.m3u8" \
-segment_time 8 \
-segment_format mpegts \
-segment_list_size 80 \
-segment_list_flags live \
-segment_list_type m3u8 \
-strict -2 "live/%08d.ts" < /dev/null
Code: Select all
<html>
<head>
<title>Raspberry Pi HLS streaming</title>
</head>
<body>
<video controls="controls" width="320" height="180" autoplay="autoplay" poster = poster.jpg >
<source src="live.m3u8" type="application/x-mpegURL" />
</video>
</body>
</html>
Re: how stream video into html5 <video>
You don’t need to delete old segments manually, -segment_wrap takes care of that.
If you set -segment_wrap 10 then it will keep incrementing until 10 and start over at 1.
If you set -segment_wrap 10 then it will keep incrementing until 10 and start over at 1.