ffmpeg Image2pipe command Stuck infinitely while taking image stream from PhantomJS - javascript

Let me Explain by my Code what issue i am facing...
This is my js file for using with PhantomJS. It simple tell it to open a page and take screenshots of it and store them in stdout.
var page = require("webpage").create();
page.viewportSize = { width: 640, height: 480 };
page.open("http://www.goodboydigital.com/pixijs/examples/12-2/", function() {
setInterval(function() {
page.render("/dev/stdout", { format: "png" });
}, 25);
});
And this is the cmd command I'm running to receive the captured images in ffmpeg in Windows Command Prompt.
phantomjs runner.js | ffmpeg -y -c:v png -f image2pipe -r 25 -t 10 -i - -c:v libx264 -pix_fmt yuv420p -movflags +faststart dragon.mp4
This command successfully starts the processes of PhantomJS and ffmpeg. But nothing happens for quite some time, after 15 minutes it gives an error saying:
"Failed to reallocate parser buffer"
thats it. I have referenced this code from this site on which the developer claims that it works
https://mindthecode.com/recording-a-website-with-phantomjs-and-ffmpeg/
Please see the attached Image for more explanation.
Image of Code

It could be related to stdout the ffmpeg process as it is being stdin through the pipe and after taking continuous image buffer is filled up and gives error.
You can review this from a well organized canvas recording application "puppeteer-recorder" on nodeJS
https://github.com/clipisode/puppeteer-recorder

Related

Why does ffmpeg fail to process streams?

I am struggling on a ffmpeg media conversion script.
I am using fluent-ffmpeg library with node.js.
My app is supposed to receive a stream as input, resize it using ffmpeg, and then outputing a stream.
However, I am absolutely unable to process an input stream with ffmpeg, even when specifying the input format (-f ffmpeg's option).
However, when execuyting the exact same ffmpeg command on an mp4 file (without extension), it works and converts properly the media !
Working code (no stream)
import * as ffmpeg from 'fluent-ffmpeg';
ffmpeg('myMp4File')
.inputFormat('mp4')
.audioCodec('aac')
.videoCodec('libx264')
.format('avi')
.size('960x540')
.save('mySmallAviFile');
Failing code (using stream)
import * as ffmpeg from 'fluent-ffmpeg';
import { createReadStream } from 'fs';
ffmpeg(createReadStream('myMp4File'))
.inputFormat('mp4')
.audioCodec('aac')
.videoCodec('libx264')
.format('avi')
.size('960x540')
.save('mySmallAviFile');
It generates the following ffmpeg's error:
Error: ffmpeg exited with code 1: pipe:0: Invalid data found when processing input
Cannot determine format of input stream 0:0 after EOF
Error marking filters as finished
Conversion failed!
This error explicitely says that ffmpeg could not identify the input format, in despite of argument -f mp4.
I read pages and pages of ffmpeg's man but I could find any relevant information concerining my issue.
Complementary information
Here is the output of command._getArguments(), showing the full ffmpeg command baked by the library:
[
'-f', 'mp4',
'-i', 'pipe:0',
'-y', '-acodec',
'aac', '-vcodec',
'libx264', '-filter:v',
'scale=w=960:h=540', '-f',
'avi', 'mySmallAviFile'
]
So the full ffmpeg command is the following:
ffmpeg -f mp4 -i pipe:0 -y -acodec 'aac' -vcodec 'libx264 -filter:v 'scale=w=960:h=540' -f 'avi' mySmallAviFile
I was getting the same error but only for files which had moov atom metadata at the end of a file.
After moving mov atom to the beginning of the file with:
ffmpeg -i input.mp4 -movflags faststart out.mp4
the error dissapeared.

Audio playback halts/stops on Chrome 64

Google just changed how Chrome preloads audio and video; see: https://googlechrome.github.io/samples/media/preload-metadata
It's my understanding that simply setting preload attribute to auto should fix the problem, however, I have been unable to do so:
https://jsfiddle.net/NinoSkopac/f4zscrdy/1/
let mp3 = 'https://s3-staging.read2me.online/audio/5a745d88483d86.76121223.mp3';
let audio = new Audio(mp3);
audio.preload = 'auto';
audio.play();
https://jsfiddle.net/NinoSkopac/rst8aspm/
<audio src="https://s3-staging.read2me.online/audio/5a745d88483d86.76121223.mp3" preload="auto" autoplay></audio>
Both of these will stop playing within a minute on Chrome 64 and Chrome 65-dev (other browsers and older Chromes are unaffected). I have replicated this issue on Mac, Windows and Android.
During my debug process, I have attached all possible media events to the JS object (i.e. audio.addEventListener('timeupdate', () => { console.log('timeupdate') })) and at first the events were firing like this:
progress
timeupdate
progress
timeupdate
[...]
Later like this:
timeupdate
timeupdate
timeupdate
[...]
When the audio playback stopped, I got a handful of error events, and dumping audio.error returns: PIPELINE_ERROR_DECODE: Failed to send audio packet for decoding: timestamp=81763265 duration=26122 size=201 side_data_size=0 is_key_frame=1 encrypted=0 discard_padding (ms)=(0, 0)
How do I fix this? Is this a Chrome bug?
UPDATE:
OGG plays fine: https://jsfiddle.net/NinoSkopac/2hktqcqt/1/
This does seem to be a Chrome bug: https://bugs.chromium.org/p/chromium/issues/detail?id=794782
A similar error on Github: https://github.com/video-dev/hls.js/issues/1529
UPDATE 2:
chrome://media-internals/ reveals this:
UPDATE 3:
This issue has been fixed in Chrome 65.
After a couple of days of trial and error and research, I have confirmed what doesn't and does work.
Doesn't work
mp3wrap
mp3wrap output.mp3 *.mp3
the output file is still corrupted and halts
ffmpeg
ffmpeg -i "concat:0.mp3|1.mp3" -acodec copy output.mp3
the output file is still corrupted and halts
Does work
mp3val with -f argument
Simply concatenate/implode your audio binaries (in PHP I do implode('', $audioBinaries) and then run mp3val -f concatenated-audio-file.mp3. The -f argument is essential and it means "try to fix errors".
How to install mp3val?
On MacOS: brew install mp3val
On Deb/Ubu: apt-get install mp3val
Same issue I am facing with concatenating technique. With ffmpeg, it works fine. Try ffmpeg with this command.
ffmpeg -f concat -i "{textfile}" -c:v copy -ab 48k -y "{output}"
textfile will have a list of files written per line.

Chrome Gapless WebM + FFMPEG

I'm trying to do gapless playback of segments generated using ffmpeg:
I use ffmpeg to encode 3 files from a source with exactly 240000 samples # 48kHz, i.e. 5 seconds.
ffmpeg -i tone.wav -af atrim=start_sample=24000*0:end_sample=240000*1 -c:a opus 0.webm
ffmpeg -i tone.wav -af atrim=start_sample=24000*1:end_sample=240000*2 -c:a opus 1.webm
ffmpeg -i tone.wav -af atrim=start_sample=24000*2:end_sample=240000*3 -c:a opus 2.webm
When looking at the meta data (using ffprobe and ffmpeg -loglevel debug) from the file I get the following which seems to me inconsistent values:
Duration: 5.01,
Start 0.007
discard 648/900 samples
240312 samples decoded
If I have several of these files how would I play them seamlessly without gaps?
i.e. in a browser I've tried:
sourceBuffer.timestampOffset = 5 * n - 648/48000;
sourceBuffer.appendWindowStart = 5 * n;
sourceBuffer.appendWindowEnd = 5 * (n+1);
sourceBuffer.appendBuffer(new Uint8Array(buffer[n]));
However, there are audible gaps.
How many samples am I actually supposed to discard? 0.007 * 48000, 648, or 240312 - 240000?
Here is a html page which can be opened in Chrome to test.
You need a simple http server to run it:
<< ls
>> index.html 0.webm 1.webm 2.webm
<< npm install -g http-server
<< http-server --cors

Forever.js doesn't restart my Node.js / Express app

I'm using forever.js to make sure my Node.js / Express app runs without a break. However, sometimes it crashes and forever doesn't restart it.
I'm using
forever start app.js
to start the app
and it starts fine, works, and then at some point crashes and when I do
forever list
it doesn't list anything, so it simply doesn't restart...
I also tried running it with a log file, using
forever start -l foreverlog.txt app.js
and the log file is fine, but it doesn't show any info about the end of the process - e.g. the crash or error report, which I usually have if I run the app.js from my console directly.
Do you know how I could make forever restart the app or at least get the errors into the log?
Thank you!
Forever splits the log
-l LOGFILE Logs the forever output to LOGFILE
-o OUTFILE Logs stdout from child script to OUTFILE
-e ERRFILE Logs stderr from child script to ERRFILE
Even if you didn't specify the -e file it should be somewhere. Users/{UserName}/.forever on windows.
You should check the ERRFILE. Maybe that will bring some light to why the process failed.
You need to use spinSleepTime:
forever --minUptime 1000 --spinSleepTime 1000 -w -l *.log -e *.log --port 1234 app.js
--minUptime not set. Defaulting to: 1000ms
--spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
Try killing the process manually by searching for the process with
ps axl | grep node
then
kill 24597
replace 24597 with your process number. Then reboot forever again.
http://blog.nodejitsu.com/keep-a-nodejs-server-up-with-forever/

Wscript.shell.run and Wscript.shell.exec do not display the same outputs

I use an ActiveXObject in Javascript.
var shell = new ActiveXObject("WScript.Shell");
exec = shell.exec('cmd /c ftp -i -A -s:file.ftp host);
var output = exec.StdOut.ReadAll();
I'm getting the expected error "Could not create file" because the file already exists on the server. Everything's ok here. But the output doesn't display the error codes of ftp, while the Run method does (553 Could not create file).
I do not use Run method because the only output possible consists in redirecting the output into a file, on the client machine.
Trust me, I read a lot of websites (including Windows official descriptions of Run, Exec)
How can I get the error codes of ftp command using WScript.Shell.Exec command?
More info:
exec.StdOut.ReadAll() output ->
"bin
cd my_dir/
mput file_path file_path
Could not create file.
Could not create file.
quit"
output file from WScript.shell.run ->
ftp> bin
200 Switching to Binary mode.
ftp> cd my_dir/
250 Directory successfully changed.
ftp> mput file_path file_path
200 PORT command successful. Consider using PASV.
553 Could not create file.
200 PORT command successful. Consider using PASV.
553 Could not create file.
ftp> quit
221 Goodbye.
Ok, I found the solution on a 8 years old post. (http://computer-programming-forum.com/61-wsh/813f07658378176c.htm)
In order to get the complete output from ftp command using Exec method, the -v option has to be added to ftp command.
Works like a charm.
var shell = new ActiveXObject("WScript.Shell");
exec = shell.exec(cmd /c ftp -i -v -A -s:file.ftp host);
var output = exec.StdOut.ReadAll();

Categories