Problem with using naudiodon / portaudio? - node.js

When I try the "playing audio streaming audio data" from the naudiodon library I only get noise on the speaker. I'm interested in how to get real sound from an app (for example when playing music from youtube). I wonder if the sound is then saved in my case in stream4800.wav?
I wonder what all the dependency I need for the project?
When I just record over a microphone with inOptions: {} I get a successfully saved stream (sound). But when I want to get the sound out of the speakers outOptions: {} then the story becomes unclear to me.
Here is an example of my code:
const portAudio = require('naudiodon');
const wav = require("wav");
const ao = new portAudio.AudioIO({
outOptions: {
channelCount: 2,
sampleFormat: portAudio.SampleFormat64Bit,
sampleRate: 44100,
}
});
const name = "stream4800.wav";
const file = fs.createReadStream(`./${name}`);
const reader = new wav.Reader();
ao.start();
reader.on("data",chunk=>ao.write(chunk));
file.pipe(reader);
Thanks for any help

Hi please check the audio file [stream4800.wav] is Mono or Sterio. I would recommend you to use sterio file with applicable sampleRate will help you out.

Related

Node.js : How can I add meta data to an audio file?

I have a .wav audio file that I would like to add meta data to, in Node.js:
let original = fs.readFileSync('./somewhere/something.wav').toString('base64')
let withMeta = addMeta(original)
fs.writeFileSync('./somewhere/something-more.wav', withMeta)
Is this possible ? Is there some Js library that allows you to write metadata (not just read/extract it) to an existing audio file.
Assuming you have ffmpeg on your system, you could use that in node via fluent-ffmpeg doing something like the following:
const ffmpeg = require('fluent-ffmpeg')
ffmpeg('./somewhere/something.wav')
.audioCodec('copy')
.outputOptions(
'-metadata', 'title=testtitle',
'-metadata', 'artist=testartist'
)
.output('./somewhere/something-more.wav')
.on('end', () => { console.log('done') })
.run()
Acceptable metadata keys for wave files in ffmpeg are: (source)
artist
comment
copyright
date
genre
language
title
album
track
encoder
timecode
encoded_by

How to convert wav file into 8000hz using Nodejs

I have tried to convert speech wav file to text using nodejs but it displays error like this:
Error:
data: '{\n "error": "This 8000hz audio input requires a narrow band
model."\n}',
Code :
let directory = `File Directory`;
let dirbuf = Buffer.from(directory);
let files = fs.readdirSync(directory);
// Create the stream.
// Pipe in the audio.
files.forEach(wav_files => {
//how can i convert that wav file into 8000hz and use that same wav file for speech to text convert
fs.createReadStream(wav_files).pipe(recognizeStream);
recognizeStream.on('data', function(event) { onEvent('Data:',event,wav_files); });
}
I am not sure whether you've already explored wav package or not. But I created a cheat like this:
const fs = require('fs');
const WaveFile = require('wavefile').WaveFile;
let wav = new WaveFile(fs.readFileSync("source.wav"));
// do it like this
wav.toSampleRate(8000);
// or like following way with your choice method
// wav.toSampleRate(44100, {method: "cubic"});
// write new file
fs.writeFileSync("target-file.wav", wav.toBuffer());
For complete running example clone node-cheat wav-8000hz and run node wav.js followed by npm i wavefile.

Extract Frames From a Video?

I want to extract frames from a Video and save the frames
var express = require("express"),
var video = "./s/video.mp4";
var storeOutput = "./store"
function getVideoFrames(){
// get frames
}
Generally, when it comes to work with video, ffmpeg is a great tool to use.
There is a ffmpeg-extract-frames package on the npm repository, based on fluent-ffmpeg, that perform exactly that.
const extractFrames = require('ffmpeg-extract-frames')
extractFrames({
input: 's/video.mp4',
output: './store/frame-%d.jpg'
})
If you need, you can pass an array of time, in milliseconds, to the offsets option to extract only specific frames.
extractFrames({
input: 's/video.mp4',
output: './store/screenshot-%i.jpg',
offsets: [
1000,
2000,
3000
]
})

How to solve output underflow error using naudiodon / portaudio?

I am writing a small node.js program that will be able to play wav sound files on a chosen audio device.
The sound starts well but it is stoped before the end of the file.
Here is my code :
const fs = require("fs");
const wav = require("wav");
const portAudio = require("naudiodon");
const ao = new portAudio.AudioIO({
outOptions: {
channelCount: 2,
sampleFormat: portAudio.SampleFormat24Bit,
sampleRate: 44100,
}
});
const name = "myfile.wav";
const file = fs.createReadStream(`./sounds/${name}`);
const reader = new wav.Reader();
reader.on("format", () => {
reader.pipe(ao);
ao.start();
});
file.pipe(reader);
process.on("SIGINT", ao.quit);
When I modify the highWaterMark option of fs.createReadStream, it slightly change the cut position in the sound but it never goes until the end of it.
I always get a portAudio status - output underflow log error.
Thanks for any help !
I have been experiencing a similar error, and my solution was to manually write to the AudioIO stream instead of using the pipe commands.
So instead of
reader.on("format", () => {
reader.pipe(ao);
ao.start();
});
You would use
ao.start();
reader.on("data",chunk=>ao.write(chunk));
Output underflow is generally not an issue, but to avoid it I initialised a new instance of PortAudio before playing every file, however that is only applicable if you don't care about slight latency.

Creating A MP4 clip with Node js

Can I create video clips from an mp4 video with node js streams? I am sure there are npms for this task, but is this something that can be done with just streams?
When I create a server, I can pipe a brief clip from the beginning of a video to an HttpResponse stream and pipe it to a file Stream with the following code: (It works!)
const fs = require('fs');
const http= require('http');
http.createServer(async (req, res) => {
// Creating clip from the beginning to 5% of the video
var { size } = fs.statSync('./Fun.mp4');
var start = 0
var end = .05*size;
var videoClip = fs.createReadStream('./Fun.mp4', { start, end })
var fileCopy = fs.createWriteStream('./Fun-Copy.mp4')
res.writeHead(200, {'Content-Type': 'video/mp4'})
videoClip.pipe(res)
videoClip.pipe(fileCopy)
}).listen(3000);
However, if I change the start position to the middle of the video, it doesn't work. I don't see the clip in the web browser, and Qucktime cannot play the copy that was produced.
// Attempting to create a clip from 50% to 60% of the video
var { size } = fs.statSync('./Fun.mp4');
var start = 0.5*size;
var end = 0.6*size;
It seems like mp4 is incomplete without the beginning. Is there a way that I can create clips from a larger video file with streams. Is there some meta elements or something, or a specific number of bytes that need to be copied from the beginning of an mp4 file?
Does node js handle audio the same way? Can I build audio clips from a larger file with node js streams?
There is not a specific number of bytes needed. MP4 uses an index like structure to organize the files. If you modify the file at all, the index (called the moov box) needs to be rewritten in its entirety.

Resources