Been experimenting but there are some issue with starting at live #157 but al with if you stop piping then you can end up with a corrupted export file (or at least a file that just refuses to parse)
So what would the code look like if possible where you could fetch just a single frame from a live stream with that being the latest with the live stream as well due to length of stream youtube doesn't store any of it you can in browser only view live or not at all
Thanks
Try the fluent-ffmpeg
https://www.npmjs.com/package/fluent-ffmpeg#screenshotsoptions-dirname-generate-thumbnails
Might have to use 100% for the timestamp to refer to the end of the video, and then end the video right away.
So I've been trying out with it but by the looks it needs to be piped to a file then read out of file which would be nice if avoidable and also as its a live stream it means the stream never ends so destroying the stream still leaves an unreadable file, however, have got code working with a normal video any suggestions?
little example that works for both videos and streams
ffmpeg can already handle m3u8 streams so no reason to make it more complicated
may add it to examples 馃
PS.: not a fan of fluent-ffmpeg...
const bin = require('ffmpeg-binaries').ffmpegPath();
const cp = require('child_process');
const ytdl = require('ytdl-core');
const takeScreenshot = (url, outFile, position) => new Promise((resolve, reject) => {
ytdl.getInfo(url).then(info => {
let format = info.formats[0];
cp.exec(`${bin} -i "${format.url}"${!format.live && position ? ` -ss ${position}` : ''} -vframes 1 -an -y ${outFile}`, (error, stdout, stderr) => {
if(error) return reject({error, stdout, stderr});
resolve(outFile);
});
}).catch(reject);
});
// usage:
takeScreenshot('https://www.youtube.com/watch?v=livestream', 'stream.png').then(() => console.log('finished screenshot stream')).catch(console.error);
takeScreenshot('https://www.youtube.com/watch?v=regularVideo', 'video.png', '4:20').then(() => console.log('finished screenshot video')).catch(console.error);
Thank you so much that works amazing one note on it is changed cp.exec(${bin}to becp.exec("${bin}" as would give path errors
Again thanks so much this finally allows me to finish feature have been working on
also any suggestion as to returning it as a buffer/stream rather than file?
Thanks @TimeForANinja. I'd support adding that to the examples. As for the fluent-ffmpeg vs ffmpeg-binaries, I don't really have a preference. I had chosen fluent-ffmpeg in the examples because it the most used and supported.
But I'm not strictly set on it. If anything, we should have examples with multiple libraries since not all people use the same one.
its less of a fluent-ffmpeg vs ffmpeg-binaries
fluent-ffmpeg just doesn't support features like multiple input stream
one of the most common usecases for ffmpeg-binaries is:
const ffmpeg = require('fluent-ffmpeg');
const bin = require('ffmpeg-binaries').ffmpegPath();
ffmpeg .setFfmpegPath(bin);
Most helpful comment
little example that works for both videos and streams
ffmpeg can already handle m3u8 streams so no reason to make it more complicated
may add it to examples 馃
PS.: not a fan of fluent-ffmpeg...