i'm trying to play raw pcm data, which came from socket.io (using nodejs) with alsa. Recently i used node-speaker that solved my problem, but i can't install it to my target device. Now i'm trying to do it with nodejs "fs" module:
...
var pcm = fs.createWriteStream("audio.pcm");
socket.on('stream', function(data) {
console.log(data);
pcm.write(data);
});
....
Afterwards i'm trying to run aplay command immediately:
aplay -t raw -c 1 -r 48000 -f S16_LE audio.pcm
I able to listen my data with delay (2-3 seconds. It depends of how quickly I ran above command), but it crashes after 5-10 seconds without any messages. I guess it is not a right way to play live pcm. What is the best way to do that?
Related
I used to do this with omxplayer before, on Raspberry Pi, and it worked fine:
const ChildProcess = require("child_process");
ChildProcess.exec(command, function (err) {
if (err !== null) {
console.log("" + err);
}
});
I could pass any omxplayer-related arguments within the command string, without issues.
With VLC on the other hand, executing cvlc [pathToAudioFile] doesn't do anything.
Oh, and I tried the exact same command, i.e. using the same file path, from the CLI and it played the audio file perfectly.
So how do I start VLC (using cvlc) from within NodeJS and pass arguments to it as well?
The reason that the cvlc [pathToFile] command didn't produce an outcome was incorrect permissions on the media file. chmod-ing that file with 777 solved the problem.
I'm using a video stream on a raspberry pi with raspivid and ffmpeg in a node app. Using them in the terminal (without using node) will stream for hours, but when I use them in a node child_process (I spawn 2, one for each) it works great for a little over 3 minutes and then the stream stops. The child_processes are still running and I'm not seeing any errors.
The gist of my code:
let camera = spawn('raspivid', args)
let ffmpeg = spawn('ffmpeg', args)
camera.stdout.on('data', (data) => {
ffmpeg.stdin.write(data)
})
Any ideas why it is stopping after 3 minutes? Thanks!
use video.mkv format
It happened to me in mp4 format and when I switched to mkv it worked out
I have a POST function in which I am trying to start VLC player using the child_process. I am using the latest Raspbian version.
router.post('/', function (req, res) {
let spawn = require('child_process').spawn;
let vlc = spawn('vlc');
vlc.stderr.on('data', function(data) {
console.log(data.toString());
});
vlc.on('exit', function(code){
console.log('Exit code: ' + code);
});
res.send({success: true})
});
After triggering the request, I get this message:
VLC is not supposed to be run as root. Sorry. If you need to use
real-time priorities and/or privileged TCP ports you can use
vlc-wrapper (make sure it is Set-UID root and cannot be run by
non-trusted users first).
Since VLC cannot be run as root, I added the UID argument to the vlc start script, and it now looks like this:
let vlc = spawn('vlc' ,{uid: 1000});
Where UID: 1000 is the ID of the user I always use.
After triggering the request, I get another message in the log:
[016f9960] main libvlc error: cannot open config file
(/root/.config/vlc/vlcrc): Permission denied
Home directory not accessible: Permission denied
[01762eb0] vlcpulse audio output error: PulseAudio server connection
failure: Connection refused
[0176bde8] dbus interface error: Failed to connect to the D-Bus
session daemon: Unable to autolaunch a dbus-daemon without a $DISPLAY
for X11
[0176bde8] main interface error: no suitable interface module
[016f9960] main libvlc error: interface "dbus,none" initialization
failed
[0176c7a8] main interface error: no suitable interface module
[016f9960] main libvlc error: interface "globalhotkeys,none"
initialization failed
[016f9960] main libvlc: Running vlc with the default interface. Use
'cvlc' to use vlc without interface.
error: XDG_RUNTIME_DIR not set in the environment.
[0176c7a8] skins2 interface error: cannot initialize OSFactory
[017614e0] main playlist: playlist is empty
[0176c7a8] [cli] lua interface: Listening on host "*console".
The player doesn't run. But if I run the same command via ssh, it will run. What could cause node from not running it?
The problem was that my server was running using
nodemon
I literally tried everything, and then when I was about to give up, I accidentally started server the normal way using node command. The VLC is starting without any errors. I didn't have to pass any user ID in arguments. It works fine just like this:
let spawn = require('child_process').spawn;
let vlc = spawn('vlc');
I'm really curious why nodemon could cause such a behaviour.
I'm building app that uses Google-Cloud-API for speech recognition.
As it's said here it require node-record-lpcm16 to record speech.
This library require sox to be installed. On mac it works fine, but on windows it runs without errors but stops recording after 1 second.
I've installed binaries that provides in documentation and added folder path to PATH variable.
Initialisation:
const recognizeStream = speech.createRecognizeStream(request)
.on('error', reject)
.on('data', data => // process data);
record
.start({
sampleRateHertz,
threshold: 0.1,
verbose: true,
recordProgram: 'sox',
silence: '1.0',
})
.on('error', reject)
.on('end', resolve)
.pipe(recognizeStream);
It was an error like Error: spawn sox ENOENT. But it has missed after installing SOX.
I haven't found any advice how to fix or debug it.
Changing silence options to other value didn't change anything.
I'll be appreciate to any advice or thoughts how to fix this.
Sorry for my English
Thank you in advance
I had the same problem a while back. Look at "freund17 commented on Nov 23, 2016" comment on this link: https://github.com/gillesdemey/node-record-lpcm16/issues/8#issuecomment-332175548
After you add the extra variables to your index.js file in your node_modules > lpcm16 folder, you can add "Microphone" after -d such as
'-d', 'Microphone'
This worked for me. What I actually tried first was trying to record from sox using the sox -d waveaudio file.wav command. It only worked for me when I added Microphone as the device so I went ahead and added it to the index.js file in lpcm16.
Try installing sox with node-record-lpcm16.
Use this command to install sox: npm install sox
I'm trying to make mobile app that can play audio files, but, that audio files are big, more than 100 mb, and I don't want save this file into the device, I want make a stream to this file into the browser.
I'm building a prototype only with ionicframework and phonegap plugins this is my github of the project:
https://github.com/cmarrero01/famvoice
My server is in node.js, so my first intent was make the streaming of the audio file with node.js to the audio tag, something like this:
app.get('/record/:userId/:playListId/:recordName',function(req,res){
var userId = req.params.userId;
var playListId = req.params.playListId;
var recordName = req.params.recordName;
if(!userId || !playListId || !recordName){
res.end();
return;
}
var path = "./records/"+recordName;
if (!params.fs.existsSync(path)) {
res.end();
return;
}
res.setHeader("content-type", "audio/mpeg");
var stream = params.fs.createReadStream(path, { bufferSize: 64 * 1024 });
stream.pipe(res);
}
And in the ionic html the audio tag:
<audio controls preload="none" type="audio/mpeg" autoplay>
<source ng-src="{{audioPlay | trustAsResourceUrl}}" />
</audio>
This is was a bad, bad, bad Idea, when I add the src to the audio tag, this wait to download all file to start playing it, so this is really an streaming, this is the same that I download the file an run it.
So, my second thought was ffmpeg, ffserver. I install ffmpeg, and I run ffserver with this config file:
Port 8090
BindAddress 0.0.0.0
MaxHTTPConnections 2000
MaxClients 1000
MaxBandwidth 1000
CustomLog -
<Feed feed1.ffm>
File /tmp/feed1.ffm
FileMaxSize 200K
ACL allow 127.0.0.1
</Feed>
<Stream status.html>
Format status
ACL allow 127.0.0.1
ACL allow localhost
ACL allow 192.168.0.0 192.168.255.255
</Stream>
<Stream test.mp3>
Feed feed1.ffm
Format mp2
AudioCodec libmp3lame
AudioBitRate 128
AudioChannels 1
AudioSampleRate 44100
NoVideo
</Stream>
And then run the next command:
ffmpeg test.mp3 http://IP:PORT/feed1.ffm
This command send to the feed the audio file test.mp3, and if you access to the url: http://IP:PORT/test.mp3 you can listen.. BUT, HERES IS MY BIG PROBLEM...
My Problems are:
The ffmpeg send the file to the feed, when the the process finished if you can try to access to the that url, you can't listen anything and the URL is stay loading.
Is suppouse that the user can select a file to listen, how I make to stream a specific file to a spefic user and not change stream for all users. I suppouse that I need one feed per user?
Exist some way to send the stream to node.js and node.js send it to the app with the correct codecs and stuff?.
If the ffmpeg is not the best way, what it is?
Thanks.