drachtio / drachtio-fsmrf

Drachtio freeswitch-based media resource function -- http://davehorton.github.io/drachtio-fsmrf
MIT License
48 stars 26 forks source link

Recording and playing audio doesn't work as expected #29

Closed telmojsneves closed 4 years ago

telmojsneves commented 5 years ago

What I am trying to build is a virtual agent that allows audio input and output. I am using drachtio server combined with freeswitch as you can see here:

version: '2'

networks:
  drachtio-fsmrf:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16

services:
  drachtio-uac:
    image: drachtio/drachtio-server:latest
    command: drachtio --contact "sip:*;transport=udp" --loglevel debug --sofia-loglevel 9
    container_name: drachtio-uac
    ports:
      - "9060:9022/tcp"
      - "5060:5060/tcp"
      - "5060:5060/udp"
    networks:
      drachtio-fsmrf:
        ipv4_address: 172.28.0.10

  freeswitch-uac:
    image: drachtio/drachtio-freeswitch-mrf:1.8.5-v0.2.1
    command: freeswitch --sip-port 5060 --rtp-range-start 20000 --rtp-range-end 20020
    container_name: freeswitch-uac
    volumes:
      - ./sounds:/usr/local/freeswitch/sounds
    ports:
      - "9070:8021/tcp"
      - "20000-20020:20000-20020/udp"
      - "20000-20020:20000-20020/tcp"
    networks:
      drachtio-fsmrf:
        ipv4_address: 172.28.0.11

And for recording audio I am using a similar example to the one founded in the examples/record folder.

const argv = require('minimist')(process.argv.slice(2));
const Srf = require('drachtio-srf');
const Mrf = require('drachtio-fsmrf')
var fs = require('fs')

const optsDrachtio = {
  host: argv['drachtio-address'] || '127.0.0.1',
  port: argv['drachtio-port'] || 9060,
  secret: argv['drachtio-secret'] || 'cymru'
} ;
const optsFreeswitch = {
  address: argv['freeswitch-address'] || '127.0.0.1',
  port: argv['freeswitch-port'] || 9070,
  secret: argv['freeswitch-secret'] || 'ClueCon'
};

const srf = new Srf() ;
srf.connect(optsDrachtio);

srf.on('connect', (err, hostport) => {
  console.log(`successfully connected to drachtio listening on ${hostport}`);
});

const mrf = new Mrf(srf) ;
mrf.connect(optsFreeswitch)
  .then((mediaserver) => {
    console.log('successfully connected to mediaserver');

    return srf.locals.ms = mediaserver;
  })
  .catch ((err) => {
    console.error(`error connecting to mediaserver: ${err}`);
  });

srf.register((req, res) => {
  console.log("Registering in the app");
  res.send(200);
})

srf.invite((req, res) => {
  const ms = req.app.locals.ms ;
  let ep;
  ms.connectCaller(req, res)
    .then(({endpoint, dialog}) => {
      console.log('successfully connected call');
      dialog.on('destroy', () => { endpoint.destroy(); });
      ep = endpoint ;
      return ep.set('RECORD_STEREO', true);
    })
    .then(() => {
      var file = fs.createWriteStream("file.mp3");

      return ep.record("file.mp3" ,{timeLimitSecs:20}) 
    })
    .then((evt) => {

      return ep.play(['silence_stream://1000', 'file.mp3']);
    })
    .then((res) => {
      console.log(`finished playing: ${JSON.stringify(res)}`);
      return ;
    })
    .catch ((err) => {
      console.log(`error connecting call to media server: ${err}`);
    });
}) ;

The only reason for register command is so that Zoiper could make a call to the service. The file is being created but nothing is stored. Also I already tried to use another examples and strategies, like mod_audio_fork module but without success. I know that this approach is not the best for what I want (literally a audio virtual agent), but it is a first step.

davehorton commented 5 years ago

The first thing to know is that the "file.mp3" you record here:

ep.record("file.mp3" ,{timeLimitSecs:20}) 

is going to be written to the filesystem on the freeswitch container.

The "file.mp3" you write here:

ar file = fs.createWriteStream("file.mp3");

is going to be written to your host. You mapped the sounds volume but you did not map the recordings volume on freeswitch.

davehorton commented 5 years ago

Is your end goal to run this system under docker? Because if not -- if your end goal is to run this on an EC2 instance or other hosted VM -- it might be faster to set up that environment. If your goal is to run on docker though, that's fine