Nodejs: I want to use url as source of ffmpeg - node.js

I want to use url as source of ffmpeg. url is like https://192.168.1.103:6666/stream.mjpg.
I checked ffmpeg working on MacOS shell
ffmpeg -f mjpeg -y -use_wallclock_as_timestamps 1 -i 'http://192.168.1.103:6535/stream.mjpg' -r 5 -reconnect 1 -loglevel 16 -c:v copy -an -qscale 10 '2.mp4'
But I want it to use in nodejs. So make it automatic. However it doesn't work when I put url in ffmpeg object as init.
var ffmpeg = new ffmpeg(url)
So this is my code
const imagePath = "http://192.168.1.103:6535/stream.mjpg"
function mjpegVideoRecoder () {
try {
var process = new ffmpeg({source: imagePath})
console.log("te");
process
.inputFormat('mjpeg')
.outputOptions([
'-y',
'-r 25',
'-c:v copy',
'-an',
'-qscale 10',
])
.ouput('testtest.avi')
.seek(30)
} catch {
console.log("errpr")
}
}
mjpegVideoRecoder()*/
and I tried this
1 var spawn = require('child_process').spawn
2 var request = require('request')
3 var args = "-f mjpeg -y -use_wallclock_as_timestamps 1 -i 'http://192.168.1.103:6535/stream.mjpg' -r 5 -reconne ct 1 -loglevel 16 -c:v copy -an -qscale 10 '3.mp4'"
4 var ffmpeg = require('fluent-ffmpeg')
5 var encoder = spawn('ffmpeg', args.split(' '));
6 encoder.stderr.pipe(process.stdout);
7
8 var interval = function(){
9 request('http://192.168.1.103:6535/stream.mjpg',function(er){
10 if(er){console.log(er)}
11 setTimeout(function(){interval()},1000)
12 }).pipe(encoder.stdin,{end:false})
13 }
14 interval();
But it also failed
this is error msg
'http://192.168.1.103:6535/stream.mjpg': No such file or directory
internal/streams/legacy.js:61
throw er; // Unhandled stream error in pipe.
^
Error: write EPIPE
at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:92:16) {
errno: -32,
code: 'EPIPE',
syscall: 'write'
}
How can I handle it. plz help me.

use option .fromFormat('image2pipe')

Related

ffmpeg nodejs lambda crop issue

I have a lambda function to crop videos with ffmpeg
I am installing the layer this way
#!/bin/bash
mkdir -p layer
cd layer
rm -rf *
curl -O https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz
tar -xf ffmpeg-git-amd64-static.tar.xz
mv ffmpeg-git-*-amd64-static ffmpeg
rm ffmpeg-git-amd64-static.tar.xz
I do not really which version but should be recent as I did it today for the last time
Then my node js lambda function is running with the following nodejs module https://github.com/fluent-ffmpeg/node-fluent-ffmpeg
return new Promise((resolve, reject) => {
ffmpeg(inputFile.name)
.videoFilters(`crop=${width}:${height}:${x}:${y}`)
.format('mp4')
.on('error', reject)
.on('end', () => resolve(fs.readFileSync(outputFile.name)))
.save(outputFile.name);
with for example videoFilters('crop=500:500:20:20')
And I have the folowing error
ffmpeg exited with code 1: Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
Conversion failed!
On my local computer I am running the following command on the exact same image
ffmpeg -i in.mp4 -filter:v "crop=500:500:20:20" out.mp4
my version of ffmpeg is 4.2.2 and this is working great
I do not have the issue with all videos, here one video which is causing me the issue https://ajouve-util.s3.amazonaws.com/earth.mp4
Here is slightly modified code that works:
var ffmpeg = require('fluent-ffmpeg');
var reject = function(something) {
console.error("got error", something);
}
var resolve = function() {
console.info("Good, job done. Now read output file");
}
var width = 500;
var height = 500;
var x = 20;
var y = 20;
var filter_string = `crop=${width}:${height}:${x}:${y}`;
console.log("filter_string", filter_string);
var onStart = function(commandLine) {
console.log('Spawned Ffmpeg with command: ' + commandLine);
}
var command = ffmpeg('earth.mp4')
.videoFilters(filter_string)
.format('mp4')
.on('error', reject)
.on('end', resolve)
.on('start', onStart)
.output('earth_cropped.mp4');
console.log("running..");
command.run();
console.log("Done");
With earth.mp4 downloaded from your link in same dir output is:
node main.js
filter_string crop=500:500:20:20
running..
Done
Spawned Ffmpeg with command: ffmpeg -i earth.mp4 -y -filter:v crop=500:500:20:20 -f mp4 earth_cropped.mp4
Good, job done. Now read output file
And we get earth_cropped.mp4 file as expected.
I bet the error is in input params, so add .on('start', onStart) in your code and check logs to see exact command used to validate it ;)

Restream hls(m3u8) using ffmpeg, hls-server and reactjs

I would like to create server with hls video (m3u8 file), so if I write in browser http://localhost:4000/stream/video.m3u8 I would like to get video.m3u8 file. I trying this, but it doesn't work for me live.js:
var ffmpeg = require('../index');
var HLSServer = require('hls-server')
var http = require('http')
var server = http.createServer()
var hls = new HLSServer(server, {
path: '/streams'
})
server.listen(4000, () => {
console.log('HLSServer ready on htpp://localhost:4000')
})
const command = ffmpeg('https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8')
.outputOptions([
'-hls_time 10',
'-hls_playlist_type event',
`-hls_segment_filename %03d.ts`,
'-hls_base_url http://localhost:4000/'
])
.output('/streams/outputfile.m3u8')
.on('progress', function (progress) {
console.log('Processing: ' + progress.percent + '% done')
})
.on('end', function (err, stdout, stderr) {
console.log('Finished processing!' /*, err, stdout, stderr*/)
// console.log(stdout)
})
.run()
UPDATE:
Console log:
HLSServer ready on htpp://localhost:4000
Processing: 1.213% done
Processing: 4.231% done
...
But file outputfile.m3u8 is nowhere created, files with .ts extensions too. If I delated line '-hls_base_url http://localhost:4000/'. File outputfile.m3u8 is saving on disk (but VLC still can't open file...nothing doing)...I would like to can get outputfile.m3u8 from writing in browser : http://localhost:4000/streams/outputfile.m3u8. Because now I get 404 error (no page)
UPDATE2 :
logs from console when I running :
ffmpeg.exe -i "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8" -hls_time 10 -hls_playlist_type event -hls_segment_filename %03d.ts -hls_base_url http://localhost:4000 outputfile.m3u8 -loglevel verbose in cmd :
Log1 Log2 Log3
UPDATE3:
When I changed command to : .\ffmpeg.exe -i https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8 -hls_time 10 -hls_playlist_type event -hls_segment_filename %03d.ts -hls_base_url http://localhost:4000 http://localhost:4000/outputfile.m3u8 -loglevel verbose
in log I got error : URL read error: Error number -10053 occurred

FFMPEG command works in shell ! but not in my node.js

When my ffmpeg command is built by my node.js application it does not run.
error
Unrecognized option 'ss 3.2 -t 1.9 -i videoplayback.mp4 -vf fps=15,scale=240:-1:flags=lanczos,palettegen palette.png'.
command
ffmpeg -ss 3.2 -t 1.9 -i videoplayback.mp4 -vf \ fps=15,scale=240:-1:flags=lanczos,palettegen palette.png
this is my code
var child_process = require('child_process')
function recordVideo() {
var spawn = child_process.spawn;
var args = [
'-y',
'-ss', '3.2',
'-t', '1.9',
'-i', '../getback/bin/videos/videoplayback.mp4',
'-vf', ' \\ ',
'fps=', '15',
'scale=', '320:-1',
'flags=','lanczos,palettegen palette.png',
];
var ffmpeg = spawn('ffmpeg', args);
ffmpeg.stdout.on('data', function (data) {
console.log(data);
});
ffmpeg.stderr.on('data', function (data) {
console.log('grep stderr: ' + data);
});
ffmpeg.on('close', (code) => {
console.log('child process exited with code ' + code);
});
};
recordVideo();
what is this error?
I think.. 'fps=', '15', In the following code
'=' options a problem.
I am still learning English.
I'm sorry if it was hard to understand.
Node will put a space between every argument in the array you give to child_process.spawn function, as the second argument, when it's building your command. Try replacing the argument pairs like "fps=" and "15" with a single argument: "fps=15".
For future reference one can view the spawned arguments by reading the spawnargs property from the created child process.

ffmpeg jpeg stream to webm only creates a file .webm with 1 frame (snapshot) or empty .webm file (mjpeg)

my problem is that when i try to turn a series of jpegs into a webm video. I either get a webm file with a single frame or a webm file with nothing in it (0 kb).
var fs = require('fs');
var path = require('path');
var outStream = fs.createWriteStream(__dirname+'/output.webm');
var ffmpeg = require('fluent-ffmpeg');
this one is a mjpeg stream URL. it produces a file with nothing.
//var proc = new ffmpeg({source:'http://xxx.xxx.xxx.xxx/goform/stream?cmd=get&channel=0',timeout:0})
this one is a snapshot URL. it produces a file with a single frame.
var proc = new ffmpeg({source:'http://xxx.xxx.xxx.xxx/snapshot/view0.jpg',timeout:0})
.fromFormat('mjpeg')
.size('2048x1536')
.toFormat('webm')
.withVideoBitrate('800k')
.withFps(20)
I have tried to use pipe instead but no dice :(
//.pipe(outStream,{end:false});
.writeToStream(outStream,{end:false})
any help is appreciated.
at this point i am up for using a basic shell command with exec but when i try that i just get errors also. Yes, it goes without saying I am a noob.
Side note:
I have tried things like zoneminder but it just breaks with our cameras and the number of cameras. so i am making a bare bones solution to record them. With our current cloud service we are missing very important moments and its costing more in energy and time.
thanks everyone that had a look and tried to figure it out :)
i have had some success with this method. It essentially works off a snapshot URL instead of the MJPEG. this uses request. but you could technically use anything since the method is using a pipe. image2pipe.
var spawn = require('child_process').spawn;
var request = require('request');
var args = '-f image2pipe -r 1 -vcodec mjpeg -i - -f webm -r 1 test3.webm';
var encoder = spawn('ffmpeg', args.split(' '));
encoder.stderr.pipe(process.stdout);
var interval = function(){
request('http://xxx.xxx.xxx.xxx/snapshot/view0.jpg',function(er){
if(er){console.log(er)}
setTimeout(function(){interval()},1000)
}).pipe(encoder.stdin,{end:false})
}
interval();
i could have used setInterval but i only wanted it to try again after it finished the request.
EDIT:
it turns out my camera was down when i was trying to use the method in the initial questions so im not sure if it works... but i know this does for MJPEG
var spawn = require('child_process').spawn;
var args = '-f mjpeg -framerate 1 -i http://xxx.xxx.xxx.xxx/goform/stream?cmd=get&channel=0 -vcodec libvpx -framerate 1 -bitrate 256k video_file.webm -y';
console.log(args)
var encoder = spawn('ffmpeg', args.split(' '));
encoder.stderr.pipe(process.stdout);

FFmpeg Stream RTSP input and save to file at the same time using nodejs

I am using node-rtsp-stream module to stream RTSP to web with nodejs.
I am streaming RTSP source with ffmpeg, for example RTSP SOURCE - EXAMPLE
I know that I can save one or many inputs to many outputs but I dont know if there is option to stream the input and save it to file at the same time without executing two process of ffmpeg.
With the following example I am able to stream the RTSP source
ffmpeg -i rtsp-url -rtsp_transport tcp -f mpeg1video -b:v 800k -r 30
On the module is look like that:
this.stream = child_process.spawn("ffmpeg", [ "-i", this.url, "-rtsp_transport", "tcp",'-f', 'mpeg1video', '-b:v', '800k', '-r', '30', '-'], {
detached: false
});
ff =child_process.spawn("ffmpeg", [ "-i", this.url, '-b:v', '800k', '-r', '30', '1.mp4'], {
detached: false
});
this.inputStreamStarted = true;
this.stream.stdout.on('data', function(data) {
return self.emit('mpeg1data', data);
});
this.stream.stderr.on('data', function(data) {
return self.emit('ffmpegError', data);
});
As you can see I am using two process of ffmpeg to do what I want but
If anyone faced with this issue and solve it with one command ( process ), I would like to get some suggestions.
How to stream RTSP source and save it to file at the same time.
for more information about the module I use:
node-rtsp-stream
try the code: (it will read RTSP and save to a jpg file (overwrite it every 3 seconds))
var fs = require('fs');
var spawn = require('child_process').spawn;
var rtspURI = 'rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov';
var fps = 1/3;
//avconv -i rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov \
// -r 1/3 -an -y -update 1 test.jpg
var ffmpeg = spawn('avconv', ['-i',rtspURI,'-r',fps,'-an','-y','-update','1','test.jpg']);
// var ffmpeg = spawn('avconv',
// ['-i','rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov',
// '-r','1/3','-an','-y','-update','1','test.jpg']);
ffmpeg.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
ffmpeg.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
ffmpeg.on('close', function (code) {
console.log('child process exited with code ' + code);
});

Resources