Hi I am looking for a stream audio solution. I tried Asterisk External Media
index.js
//Start the server that receives audio from Asterisk.
console.log('Starting audio listener');
let audioServer = new rtp.RtpUdpServerSocket(process.env.listenServer, false, process.env.audioOutput || false);
result
Starting audio listener
server error:
Error: getaddrinfo ENOTFOUND http
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:108:26)
server socket closed
Thanks for your quick help, I can connect listenServer but I still cannot stream audio.
I am following the “Asterisk External Media Sample” to stream the audio from asterisk. Here is my goal:
run index.js → Create ARI Controller → Cretae a bridge and a local channel → call a number (local/1234) → stream the channel audio to “output path”
All the conenction work well and it called local/1234, however no audio stream to the output path. I didnot got any warning and error.
Am i missing something?
index.js
'use strict';
// import
const client = require('ari-client');
const ari = require('.//AriController');
const wss = require('.//websocketServer');
const mq = require('.//mqttClient');
const rtp = require('.//RtpUdpServerSocket');
let channels = new Map();
console.log('Starting');
async function main() {
// Create the ARI Controller instance but don't start it yet.
console.log(`Creating ARI Controller to Asterisk instance ${process.env.ariServerUrl}, but not yet start`);
let ariController = new ari.AriController();
ariController.on('close', () => {
audioServer.close();
process.exit(0);
});
ariController.connectARI();
//Start the server that receives audio from Asterisk.
console.log('Starting audio listener');
let audioServer = new rtp.RtpUdpServerSocket(process.env.listenServer, process.env.audioOutput);
}
main();
AriController.js
const EventEmitter = require('events');
const ari = require('ari-client');
class AriController extends EventEmitter {
constructor() {
super();
}
async close() {
if (this.closing) {
return;
}
this.closing = true;
if (this.localChannel) {
console.log("Hanging up local channel");
try {
await this.localChannel.hangup();
} catch (error) {
}
delete this.localChannel;
}
if (this.externalChannel) {
console.log("Hanging up external media channel");
try {
await this.externalChannel.hangup();
} catch (error) {
}
delete this.externalChannel;
}
if (this.bridge) {
console.log("Destroying bridge");
try {
await this.bridge.destroy();
} catch (error) {
}
delete this.bridge;
}
await this.ari.stop();
this.emit('close');
}
//this function start the ARI (connect to PBX)
async connectARI() {
this.ari = await ari.connect(process.env.ariServerUrl, process.env.ariUser, process.env.ariPassword);
await this.ari.start("externalMedia");
// Create a simple bridge that is controlled by ARI/Stasis
this.bridge = this.ari.Bridge();
try {
await this.bridge.create({ type: "mixing" });
} catch (error) {
console.error(error);
this.close();
}
this.bridge.on('BridgeDestroyed', (event) => {
console.log('BridgeDestroyed');
this.close();
});
/*
* Create the local channel. This actually creates 2
* back to back channels, one that's controlled by ARI/Stasis
* that we can put into the bridge we created above and
* another one the one that dials a phone, confbridge, etc.
* and joins _that_ bridge.
*
* localChannel below is actually the first channel.
*/
this.localChannel = this.ari.Channel();
this.localChannel.on('StasisStart', (event, chan) => {
this.bridge.addChannel({ channel: chan.id });
});
this.localChannel.on('StasisEnd', (event, chan) => {
console.log('StasisEnd');
this.close();
});
// Call the phone or confbridge specified in dialstring
try {
await this.localChannel.originate({
endpoint: process.env.dialstring, formats: process.env.format, app: "externalMedia",
});
} catch (error) {
console.error(error);
this.close();
}
// Now we create the External Media channel.
this.externalChannel = this.ari.Channel();
this.externalChannel.on('StasisStart', (event, chan) => {
this.bridge.addChannel({ channel: chan.id });
});
this.externalChannel.on('StasisEnd', (event, chan) => {
console.log('StasisEnd');
this.close();
});
/*
* We give the external channel the address of the listener
* we already set up and the format it should stream in.
*/
try {
let resp = await this.externalChannel.externalMedia({
app: "externalMedia",
external_host: process.env.listenServer,
format: process.env.format
});
this.emit('ready');
} catch (error) {
console.error(error);
this.close();
}
}
}
module.exports.AriController = AriController;