Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture current image from youtube live stream

I'd like to process the output of a youtube live stream every few seconds. With help from others I've come up with a solution to capture an image for processing later, but it tends to break and is much too slow:

youtube-dl --prefer-ffmpeg -f worst "https://www.youtube.com/watch?v=Gy5PC5Auoak" -o - | dd count=32 bs=4096 | ffmpeg -i - -f image2 -frames:v 1 img22.jpeg

(grabs 128 KB of stream data and extracts one frame from that into a jpg). The fastest run of this took about 30 seconds. Other attempts involved piping youtube-dl into mplayer, but the approach shown above seems to make more sense because it explicitly limits the amount of data received.

  • Why is that taking so long? Also, might some advertisement have come in the way that just took the first 25 seconds or so?
  • Are there faster solutions to this?
  • an equal stream is available via ustream, if that makes it easier.

I would like the result to run on a raspberry pi.

like image 964
Christoph Avatar asked Sep 09 '16 09:09

Christoph


1 Answers

The youtube-dl command first resolves the stream to a .m3u8. This happens every time you run the youtube-dl command. If you are processing the image on an interval, it can be faster to save the resolved .m3u8 URL and then use that directly with ffmpeg.

First, resolve the .m3u8 stream by using the -g flag and saving it to a file, like stream-url. You only have to do this once, until the m3u8 link is no longer valid (see below).

youtube-dl -g -f worst "https://www.youtube.com/watch?v=Gy5PC5Auoak" > stream-url

Then, you can simply use the url in ffmpeg. This is the command you would run on an interval:

ffmpeg -i $(cat stream-url) -f image2 -frames:v 1 img22.jpeg

I've found that the .m3u8 stream also has an expiry time. This means you will have to renew the URL every few hours. You can see it as part of the stream-url where it says .../expire/1559856313/... where 1559856313 is just the Unix time at which the stream will expire. A simple bash script could be used to do check on this and renew as needed.

I've ran this on my Raspberry Pi 2 with an HD stream (i.e. 'without -f worst') every 10 seconds, and it seems to work just fine.

like image 79
Matt Schlosser Avatar answered Sep 27 '22 23:09

Matt Schlosser