ionic 2 how to play sound effects - audio

I'm actually developping an application with Ionic 2 / angular2.
It's an app to learn english tenses that runs with a SQLite database.
I would like to add a background sound that plays in loop all the time.
The users can exercice themselves with a quizz. I would like to play sound effects when the user submit his answer.
Two different sounds : one for good and one for bad answers.
I've already tried with Nativeaudio, angular-audio and Ionic audio modules but each times the documentation is based on javascript and not typescript, or it is not helpfull.
With native audio, I've succeed once playing the background sound but after it didn't work at all and came up with an error : EXCEPTION: Uncaught (in promise): A reference does not exist for the specified audio id.
For the other solutions (angular-audio and ionic-audio) either i didn't get how to install it either, once installed, I had nothing : no sound and no error.
Thank you very much for your help.

Install:
$ ionic plugin add --save cordova-plugin-nativeaudio
$ npm install --save #ionic-native/native-audio
Usage:
import { NativeAudio } from '#ionic-native/native-audio';
constructor(private nativeAudio: NativeAudio) { }
...
this.nativeAudio.preloadSimple('uniqueId1', 'path/to/file.mp3').then(onSuccess, onError);
this.nativeAudio.preloadComplex('uniqueId2', 'path/to/file2.mp3', 1, 1, 0).then(onSuccess, onError);
this.nativeAudio.play('uniqueId1').then(onSuccess, onError);
// can optionally pass a callback to be called when the file is done playing
this.nativeAudio.play('uniqueId1', () => console.log('uniqueId1 is done playing'));
Reference:
https://ionicframework.com/docs/native/native-audio/

Related

RangeError when playing audio through opusscript

I've been attempting to use electron to play sounds through a discord bot. However, I've come across three issues with this.
The first is that the code I'd usually use to play a sound file though discord returns an error stating that I am lacking opus.node and opusscript. This shouldn't be happening, as I have #discordjs/opus installed, and running this same code outside of the electron instance works perfectly fine.
message.member.voice.channel.join().then((connection) => {
const dispatcher = connection.play(ytdl("https://www.youtube.com/watch?v=ZlAU_w7-Xp8", { quality: "highestaudio" }));
dispatcher.on("finish", () => {
console.log("Song is finished.");
});
});
To get around the error, I installed opusscript. However, this is where the second issue comes in. I am able to run the sound - for the first 9 times. After the ninth time, the bot emits the following error:
(node:21064) UnhandledPromiseRejectionWarning: RangeError: offset is out of bounds
at Uint16Array.set (<anonymous>)
at OpusScript.encode (C:\Users\spiralio\Desktop\sb\node_modules\opusscript\index.js:67:16)
at Encoder._encode (C:\Users\spiralio\Desktop\sb\node_modules\prism-media\src\opus\Opus.js:60:25)
at Encoder._transform (C:\Users\spiralio\Desktop\sb\node_modules\prism-media\src\opus\Opus.js:157:30)
at Encoder.Transform._read (_stream_transform.js:191:10)
at Encoder.Transform._write (_stream_transform.js:179:12)
at doWrite (_stream_writable.js:403:12)
at writeOrBuffer (_stream_writable.js:387:5)
at Encoder.Writable.write (_stream_writable.js:318:11)
at VolumeTransformer.ondata (_stream_readable.js:716:22)
This error only occurs if the sound file I'm playing overlaps onto itself 9 times. If I let it finish before this error plays, I can continue playing sounds just fine. However, once the error plays, no matter how long I wait sound no longer plays.
A solution I tried was to have the bot run in the renderer process instead of the main process. However, this prompts me with the issue that the bot can't connect to a voice channel from a browser.
There seem to be a few issues at play here.
Firstly, the root issue here is that we're encoding a file that's too large. I suspect that the videos are snowballing to such a point where we hit a brick wall.
I'd try downloading only the audio to avoid sending files too large (see ytdl options).
message.member.voice.channel.join().then((connection) => {
const dispatcher = connection.play(ytdl("https://www.youtube.com/watch?v=ZlAU_w7-Xp8", { quality: "highestaudio", filter: "audioonly" }));
dispatcher.on("finish", () => {
console.log("Song is finished.");
});
});
Electron not detecting #discordjs/opus seems to be a deeper issue with native modules and your builder. Are you experiencing this in production, or do you have a recreation of your Electron setup somewhere?

Tensorflow-node not recognized with cocoSsd on node.js

I'm using #tensorflow-models/coco-ssd and #tensorflow/tfjs-node to do some object detection. It's working, but apparently could be faster. It's honestly not even that slow, it bangs through an image in about a second or two, but it just bugs me when something isn't working as well as it could.
You can find a live version of this at https://01014.org/wall-of-cats
Most current code at https://github.com/qozle/wall-of-cats
I get this on the first call to the model.detect():
============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up
dramatically, install our node backend, which binds to TensorFlow C++, by running
npm i #tensorflow/tfjs-node, or npm i #tensorflow/tfjs-node-gpu if you have CUDA.
Then call require('#tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of
your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
I'm on a linux ubuntu 20 LTS server. I tried downgrading tfjs-node, I saw some folks had a problem with the versions not matching for the faceAPI example, so I tried that.
"#tensorflow-models/coco-ssd": "^2.1.0",
"#tensorflow/tfjs-node": "^2.1.0",
I tried deleting node_modules and doing
npm install
so that it would rebuild the bindings. No beans. Tried making sure I have python installed- I'm running python3. EDIT tried making sure that I have 2.7 installed instead and that I'm using it as default. No beans.
EDIT I've also tried adding #tensorflow/tfjs-backend-cpu to the mix, and rebuilding bindings again by deleting node_modules and doing npm install. No beans.
Here's some of the code:
const tf = require("#tensorflow/tfjs-node");
const cocoSsd = require("#tensorflow-models/coco-ssd");
tf.enableProdMode();
preloading the model:
catModel = await cocoSsd.load();
Then later on, when I get some data:
const image = await tf.node.decodeImage(resp.body, 3);
const predictions = await nsfwModel.classify(image);
const catObjects = await catModel.detect(image);
image.dispose();
This is for a project that interfaces with the twitter API, pulls filtered data of all posts with images that have #cat or cat or kitten in the post, checks it against a NSFW model, and then does object detection to make sure there are cats in the pictures (I got a lot of random images and couldn't really refine the twitter API filter rules).
I'm out of beans and out of ideas.

Set multiple app views for many modules in ExpressJS

I have my code
app.set('views', path..);
originally placed in server.js and I tried to segregate/factor it into a config.server.js (see link), there I implemented underscoreJS each to loop through the modules by their folders' names in my modules/ directory. ['core', 'xt_syncs']. Problem with this trick I try playing is that, app.set('views',..) can't be a Singleton (which loads many things at once). The app.set('views',..) can only have 1 URI for 'views' (module specific, my app contains several modules: core, xt_syncs as you see in the structure), and the app.set appear to fail, and be overwritten by the static uri to modules/second_module.
I write the app myself, picking the middlewares/components I want. I'm trying to reuse some of the assets from MEANjs, mean-stack-relational (MVC, I prefer modules architecture to MVC, that's why my attempt is to build mine), and SEANjs (quite too complex, the stack requires Redis and MySQL5.7, I try building mine so I can get a good understanding of things flow on the fly and exclude Redis and MySQL upgrade).
Now back to the question, obviously, you see in MEANjs and SEANjs , they do in their default.js file:
views: ['modules/*/client/views/**/*.html'],
routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js']
QUESTIONS:
1/ How can I implement similar pattern in my app? Notice in the MEANjs and SEANjs, there is * as in modules/*/client and ! as in modules/!(core)/server. app design advices and coding help, please. (this part of the question is not yet addressed)
2/ How related the default.js is to the config.js (initGlobalConfigFolders,initGlobalConfigFiles,...)? I try to wrap my head around to understand config.js and find clues of the glueing. Maybe, my modules[module] as in
modules[module] = {
client: {},
server: {}
};
is one step closer to what they built in the initGlobalConfigFolders method.
3/ Is using build tool (Grunt, Gulp, or Webpack) a must here to achieve that? If so, Can you show me how? (build tool incorporation is in my planning). How can you
Thank you very much.
This patch hinted at implementing app.set('views', view_paths); // where view_paths can be an array of views folders.
2 & 3. Awaiting help and answers.

Nodejs global hotkey execution

I was wondering if anyone could point me in the right direction. I'm building a Node app that I want to execute some hotkeys on the computer it's running on to start & stop an OBS stream based on hotkeys.
I was wondering if this is possible as I've only been able to find out of date and non-working solutions.
Thanks.
You can do it easily in AutoHotKey, but if it is Node you need, Node you'll get.
Probably quite a few Node Package Managers (NPM's) that will fit the bill, if you check github, I'm betting someone has made a little something something.
Lo and behold, I did it for you : hott - Global hotkeys for Windows, with node
Seems a tad overkill to me, using "iohook" should work wonders; hook it up in the semi-old fashion JS way of the event, something like so :
The only way I am fairly certain will work is plain and simple event listening :
const ioHook = require('iohook');
ioHook.on("keypress", event => {
if(event.keychar == 'a') {
console.log(event);
} else {
console.log("Press a");
}
});
ioHook.start();

Play audio with Node.JS

I'm currently using child_process and command-line mplayer to play audio on the local machine, with my Node.JS application. This works, but it's not really an excellent solution. My biggest issue is that it takes 500ms from mplayer is started to audio starts playing.
Are there better ways to play audio? Preferably compressed audio, but I'll take what I can get.
I would suggest using node-speaker, which outputs raw PCM data to your speakers (so basically, it plays audio).
If you're playing something like mp3 files you might need to decode it first to PCM data, which is exactly what node-lame does.
Hope that helps.
Simplest I've found (on Mac OS) is to use
exec('afplay whatever.mp3', audioEndCallback)
Introducing, audic. It doesn't use any native dependencies so it can't break like in the answers higher up.
Observe:
import Audic from 'audic';
const audic = new Audic('audio.mp3');
await audic.play();
audic.addEventListener('ended', () => {
audic.destroy();
});
or more simply:
import {playAudioFile} from 'audic';
await playAudioFile('audio.mp3');
I think what you asking is there any good modules that work with audio in the nodejs ecosystem?
Whenever you have this type of question you should first go the npmjs and just type a appropiate keyword.
Here is list of modules that related to audio I found on the npmjs site.
substacks's baudio looks good to me.
You can use play-sound module also:
Install using npm, Run command:
npm install play-sound --save
Now use in your code:
var player = require('play-sound')(opts = {})
player.play('./music/somebody20.flac', function (err) {
if (err) throw err;
console.log("Audio finished");
});
Check out sound-play, it's a simple solution that works on Windows and MacOS without using external players:
const sound = require('sound-play')
sound.play('music.mp3')
Disclaimer: I'm the author of this package.
Check out node-groove - Node.js binding to libgroove:
This library provides decoding and encoding of audio on a playlist. It is intended to be used as a backend for music player applications, however it is generic enough to be used as a backend for any audio processing utility.
Disclaimer: I wrote the library, which is free, open source, and not affiliated with any product, service, or company.
You can use the play sound module and path to achieve this.
npm install play-sound
import path from 'path';
const __dirname = path.resolve();
import sound from 'sound-play';
const filePath = path.join(__dirname, "file.mp3");
sound.play(filePath);

Resources