We help IT Professionals succeed at work.

MixMonitor - Convert to mp3

Silas2
Silas2 used Ask the Experts™
on
I'm running the MixMonitor command, but it makes a wav, I was thinking of converting to mp3 at a low bitrate. I have been doing that with lame.exe on windows, is it best to run lame on linux or how about this SOX?
How would I invoke it? (I see a MONITOR_EXEC but it looks like that param is only available on Monitor())?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Ron MalmsteadInformation Services Manager

Commented:
ffmpeg can do it easily...

www.ffmpeg.org

You can invoke it from the dialplan, using the System()  app.



Ron MalmsteadInformation Services Manager

Commented:
Something like this maybe...


[macro-record]

exten => s,1,Playback(call)
exten => s,n,Playback(is-now-being-recorded)
exten => s,n,Playback(beep)
;Record to wav
exten => s,n,NoOp(Reording ${DIALEDNUM})
exten => s,n,MixMonitor(/var/spool/Asterisk/monitor/wavrecordings/${DIALEDNUM}.wav,bW(3))
;Convert to mp3
exten => s,n,System(ffmpeg -i /var/spool/Asterisk/monitor/recordings/${DIALEDNUM}.wav /var/spool/Asterisk/monitor/mp3recordings/${DIALEDNUM}.mp3)
Ron MalmsteadInformation Services Manager

Commented:
ooops...syntax

[macro-record]

exten => s,1,Playback(call)
exten => s,n,Playback(is-now-being-recorded)
exten => s,n,Playback(beep)
exten => s,n,NoOp(Reording ${DIALEDNUM})

;Record to wav
exten => s,n,MixMonitor(/var/spool/Asterisk/monitor/wavrecordings/${DIALEDNUM}.wav,bW(3))

;Convert to mp3
exten => s,n,System(ffmpeg -i /var/spool/Asterisk/monitor/wavrecordings/${DIALEDNUM}.wav /var/spool/Asterisk/monitor/mp3recordings/${DIALEDNUM}.mp3)

Author

Commented:
Can you specify a bitrate in that command line? I can get away with a very low one (16) I've discovered, and I need to ftp the files so the smaller the better.
Ron MalmsteadInformation Services Manager

Commented:
Yes, you can specify bitrate, and about a million other options with ffmpeg.
The help file is long.  (ffmpeg -help)

Example..

exten => s,n,System(ffmpeg -i /var/spool/Asterisk/monitor/wavrecordings/${DIALEDNUM}.wav -ar 44100 /var/spool/Asterisk/monitor/mp3recordings/${DIALEDNUM}.mp3)
   
Ron MalmsteadInformation Services Manager

Commented:
I think this would result in a small enough file...

ffmpeg audio.wav -ar 22050 -ab 64k audio.mp3

Author

Commented:
I just ran the dialplan, but it didn't make the mp3, (i just ran an app-get on ffmpeg, it seemed to be happy with the install, but I am a linux newbie), is there any way to diag what went wrong - the asterisk cli said nothing.
Ron MalmsteadInformation Services Manager

Commented:
Can you post the CLI output ?
It must have shown something...??no??

Also, please post the dialplan code you are working with.
Ron MalmsteadInformation Services Manager

Commented:
I would suggest runnig ffmpeg by itself from a terminal window, to get the command line working first before putting it into the dialplan.

Also, everytime you change the dialplan, you need to issue an "EXTENSIONS RELOAD" from the CLI.

Author

Commented:
I've been running 'dialplan reload' is that any good?
Ron MalmsteadInformation Services Manager

Commented:
...Yes, it's the same thing.
Ron MalmsteadInformation Services Manager

Commented:
Try this.

Record a file to wav.

Then from a terminal window, attempt to convert it with ffmpeg.

Post the results of your efforts...

NOTE: The "system()" app will not return any error messages from ffmpeg on your cli... so if your syntax is off or the command parameters are wrong, you won't know it unless you are testing in a terminal window first.

Author

Commented:
silas@silas-Asterisk:/var/spool/asterisk/monitor/mp3Recordings$ ffmpeg -i /var/spool/asterisk/monitor/02074353410_201108051626_104.wav /var/spool/asterisk/monitor/mp3Recordings/02074353410_201108051626_104.mp3
FFmpeg version 0.6.2-4:0.6.2-1ubuntu1, Copyright (c) 2000-2010 the Libav developers
  built on Mar 22 2011 15:35:22 with gcc 4.5.2
  configuration: --extra-version=4:0.6.2-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static
  WARNING: library configuration mismatch
  libavutil   configuration: --extra-version=4:0.6.2-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libavcodec  configuration: --extra-version=4:0.6.2-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libavformat configuration: --extra-version=4:0.6.2-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libavdevice configuration: --extra-version=4:0.6.2-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libavfilter configuration: --extra-version=4:0.6.2-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libswscale  configuration: --extra-version=4:0.6.2-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libpostproc configuration: --extra-version=4:0.6.2-1ubuntu1 --prefix=/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libavutil     50.15. 1 / 50.15. 1
  libavcodec    52.72. 2 / 52.72. 2
  libavformat   52.64. 2 / 52.64. 2
  libavdevice   52. 2. 0 / 52. 2. 0
  libavfilter    1.19. 0 /  1.19. 0
  libswscale     0.11. 0 /  0.11. 0
  libpostproc   51. 2. 0 / 51. 2. 0
[wav @ 0x99b4420]max_analyze_duration reached
[wav @ 0x99b4420]Estimating duration from bitrate, this may be inaccurate
Input #0, wav, from '/var/spool/asterisk/monitor/02074353410_201108051626_104.wav':
  Duration: 00:03:11.84, bitrate: 128 kb/s
    Stream #0.0: Audio: pcm_s16le, 8000 Hz, 1 channels, s16, 128 kb/s
File '/var/spool/asterisk/monitor/mp3Recordings/02074353410_201108051626_104.mp3' already exists. Overwrite ? [y/N]

Author

Commented:
That's when I type the cmd straight into a console, when I run it from asterisk, nothing seems to happen.
Here's my extensions.conf:
[BaseUser]
exten => _XXXXXXXXXXX,1,Set(CallTime=${STRFTIME(${EPOCH},,%C%y%m%d%H%M)})
exten => _XXXXXXXXXXX,n,Set(CALLFILENAME=${EXTEN}_${CallTime}_${CALLERID(num)})
exten => _XXXXXXXXXXX,n,MixMonitor(${CALLFILENAME}.wav,b)
exten => _XXXXXXXXXXX,n,Dial(SIP/VoIPProvider/${EXTEN})
exten => _XXXXXXXXXXX,n,System(ffmpeg -i /var/spool/asterisk/monitor/${CALLFILENAME}.wav /var/spool/asterisk/monitor/mp3Recordings/${CALLFILENAME}.mp3)
Ron MalmsteadInformation Services Manager

Commented:
File '/var/spool/asterisk/monitor/mp3Recordings/02074353410_201108051626_104.mp3' already exists. Overwrite ? [y/N]    

It shows the file is already there...
There is an option in ffmpeg to overwrite without prompt ( I forget what it is though ).   You may want to use it because otherwise ffmpeg will "hang" in the background if the file already exists..waiting for you to press "y" to overwrite..
Ron MalmsteadInformation Services Manager

Commented:
...also, you may want to provide asterisk with the full path to ffmpeg, though I didn't think it would be necessary.
Ron MalmsteadInformation Services Manager

Commented:
I think you are really close to having it working, at face value everything looks correct.
Ron MalmsteadInformation Services Manager

Commented:
Oh wait ...this is Ubuntu right??

....maybe SUDO would help?!!

Author

Commented:
The overwite is because I had made it before with a previous console cmd.
When I ran this in the console I didn't need sudo, do the asterisk 'System' process need to be granted special permissions?

Author

Commented:
Here's a CLI output of the dialplan show + the CLI from a phone call which goes ok up to the MixMonitor, then no System/ffmpeg, shed any light for you?
dialplan show 02074353410@TeamMember
[ Included context 'BaseUser' created by 'pbx_config' ]
  '_XXXXXXXXXXX' => 1. Set(CallTime=${STRFTIME(${EPOCH},,%C%y%m%d%H%M)}) [pbx_config]
                    2. Set(CALLFILENAME=${EXTEN}_${CallTime}_${CALLERID(num)}) [pbx_config]
                    3. MixMonitor(${CALLFILENAME}.wav,b)          [pbx_config]
                    4. Dial(SIP/VoIPProvider/${EXTEN})            [pbx_config]
                    5. System(ffmpeg -i /var/spool/asterisk/monitor/${CALLFILENAME}.wav /var/spool/asterisk/monitor/mp3Recordings/${CALLFILENAME}.mp3) [pbx_config]

-= 1 extension (5 priorities) in 1 context. =-
  == Using SIP RTP CoS mark 5
    -- Executing [02074353410@TeamMember:1] Set("SIP/104-0000001d", "CallTime=201108052128") in new stack
    -- Executing [02074353410@TeamMember:2] Set("SIP/104-0000001d", "CALLFILENAME=02074353410_201108052128_104") in new stack
    -- Executing [02074353410@TeamMember:3] MixMonitor("SIP/104-0000001d", "02074353410_201108052128_104.wav,b") in new stack
    -- Executing [02074353410@TeamMember:4] Dial("SIP/104-0000001d", "SIP/VoIPProvider/02074353410") in new stack
  == Using SIP RTP CoS mark 5
  == Begin MixMonitor Recording SIP/104-0000001d
    -- Called VoIPProvider/02074353410
    -- SIP/VoIPProvider-0000001e is making progress passing it to SIP/104-0000001d
    -- SIP/VoIPProvider-0000001e answered SIP/104-0000001d
  == Spawn extension (TeamMember, 02074353410, 4) exited non-zero on 'SIP/104-0000001d'
  == MixMonitor close filestream
  == End MixMonitor Recording SIP/104-0000001d

Author

Commented:
Is there a System(runSomethingSimple) I can run to check the System call is working ok? (as I know the line ffmpeg is working)

Commented:
If this is just to get smaller files you can change the format that Mixmonitor records in to gsm or gsm encoded wav.  Probably be about 1/10 the size of of the linear encoded wav.

All you have to do is change the file extension and it will automatically do the format.  So .wav for normal 16 bit linear wave,  .WAV for gsm encoded wave and .gsm for gsm encoding.

MixMonitor does has the option to include a system command that will be executed when the recording is completed - without any dialplan tinkering.  More or less the same as using a System call in the dialplan but may be a bit cleaner.

The gsm/gsm encoded wave encoding is likely going to be less cpu overhead than mp3 encoding.

Author

Commented:
That's a great suggestion and one I would readily take up but...it needs to be mp3 when it gets ftp'd off the linux box (its going to a public ISP running Medium Trust,  and then gets played by a mp3 web pluggin which only takes mp3, the Medium Trust prevents me running lame.exe (or any unmanaged process) ), so I think I'm stuck with the mp3 workaround.
Ron MalmsteadInformation Services Manager

Commented:
To test the system command ...you can do a simple echo to a file, or delete a test file.

""do the asterisk 'System' process need to be granted special permissions? ""

I wasn't sure if you would need to use sudo when invoking other apps from the dialplan, I just know it's sometimes needed in Ubuntu though i'm not that familiar with Ubuntu myself.  I use CentOS on my box.

..it can't hurt to try anyway.
It certainly could be permissions related if ffmpeg is not launching from the dialplan and we know it works otherwise..
Ron MalmsteadInformation Services Manager

Commented:
Kode makes a good suggestion there...

"MixMonitor does has the option to include a system command that will be executed when the recording is completed "

You might try putting the command line into the mixmonitor line.

From your CLI output it doesn't show the dialplan ever gets to the System() cmd line.  Including it with Mixmon may solve that.

Author

Commented:
Sorry, away long weekend.
I just ran this exten => _XXXXXXXXXXX,n,System(rm /filePath/aFile.wav), which didn't run (i did chmod 777 on the file first, and the command did run ok in an ordinary linux conole)
As far as I know, I've done nothing to alter the user asterisk is running under, so I guess that's 'root'?
Any idea why System() wouldn't run?

Author

Commented:
Sorry, my ignorance, when I piped an echo into a file it did echo to the file so System() is running. It must be a some other problem with the command.
Information Services Manager
Commented:
I don't think the System() line is being executed by the dialplan at all.
I would try to put it into the Mixmonitor cmd as Kode suggested.

Another option would be to put both mixmon and system() lines into a macro and call that with the Dial() app...

Doing either of those should ensure that the dialplan code gets executed.
Ron MalmsteadInformation Services Manager

Commented:
Also...there's option  "g" in the dial() app...

http://www.voip-info.org/wiki/view/Asterisk+cmd+Dial
g: When the called party hangs up, continue to execute commands in the current context at the next priority.

Author

Commented:
I think you might have it there with the 'g', as I've just discovered that I can at least get System to run a delete, but not after the Dial() nothing,including the echo is being executed after the Dial(),
Ron MalmsteadInformation Services Manager
Commented:
Are you using the 'h' extension at all?

That could be another option.

h would be executed on hangup as well.

Author

Commented:
Thanks for putting me in the direction of this stuff, I don't know how I would have found it otherwise. When I tried with the g option, for some reason - no execute after hangup, as advertised, but the h extension is firing, why would that be?
Ron MalmsteadInformation Services Manager

Commented:
I'm not sure on that one.
The wiki on Asterisk is a bit out of date, it may be deprecated in later releases.

If you use the h extension, that will fire everytime, so I would stick with that.

Author

Commented:
Phew!!!!! At last. I can't thank you enough. I got it running right, I did switch to lame as opposed to ffmpeg, only because I was getting everything else working but the mp3 was empty, and thought it would be easier to switch to something I had working before than (probably) friggin with the codecs.
Here is the dialplan i ended up with:
exten => _XXXXXXXXXXX,1,Set(CallTime=${STRFTIME(${EPOCH},,%C%y%m%d%H%M)})
exten => _XXXXXXXXXXX,n,Set(CALLFILENAME=${EXTEN}_${CallTime}_${CALLERID(num)})
exten => _XXXXXXXXXXX,n,MixMonitor(${CALLFILENAME}.wav,b)
exten => _XXXXXXXXXXX,n,Dial(SIP/VoIPProvider/${EXTEN},15,g)
exten => h,1,System(chmod 777 /var/spool/asterisk/monitor/${CALLFILENAME}.wav)
exten => h,n,System(/usr/bin/lame -B 16 /var/spool/asterisk/monitor/${CALLFILENAME}.wav /var/spool/asterisk/monitor/${CALLFILENAME}.mp3)
exten => h,n,System(chmod 777 /var/spool/asterisk/monitor/${CALLFILENAME}.mp3)
exten => h,n,System(rm /var/spool/asterisk/monitor/${CALLFILENAME}.wav)
Ron MalmsteadInformation Services Manager

Commented:
Cool, glad to help.