[asterisk-users] How to run a remote PHP script and still have access to audio stream?

David Backeberg dbackeberg at gmail.com
Fri Feb 19 19:22:14 CST 2010


On Wed, Feb 10, 2010 at 2:13 PM, Leo Burd <leob at media.mit.edu> wrote:
> Hello David,
>
> Thanks so much for your message!
>
> Please check my comments inline below...
> David Backeberg wrote:
>> On Sun, Feb 7, 2010 at 9:54 PM, Leo Burd <leob at media.mit.edu> wrote:
>>
>>> Hello there,
>>>
>>> I'm trying to figure out how to run a PHP script on a remote machine and
>>> still have access to the audio stream associated with the call.
>>>
>>> Ideally, I'd love to play/record audio files directly from/to the remote
>>> server without having to copy them back and forth to the Asterisk
>>> server.  What is the best way to do this?
>>>
>> 1) recordings, with a side order of distributing those to another machine
>> 2) remote shell scripting
>>
> What would be the "asterisk way" of recording part of the call from a
> remote server?  I'm not sure I can do that (the remote connection) with
> EAGI, can I?

The 'asterisk way' of recording part of a call needs to be done on the
asterisk system where the call is taking place. Or, if the call is
actually between two asterisk systems, the call can be recorded
directly on one or the other or both asterisk systems. The asterisk
dialplan feature is called Monitor() or MixMonitor(), and you can
refer to the documentation for the differences.

The AGI and remote connection comes in when the recording (call)
completes, and in the h (hangup) context for this dialplan context,
you would do the remote file copy so your call would now be copied off
somewhere else.

> Do you know of any examples that use ssh from inside Asterisk calls?

Sure, here's an example from one of my dialplans.

exten => s,1,Answer
exten => s,n,Set(CDR(userfield)=faxsample)
exten => s,n,Set(LOCALSTATIONID=FaxSample)
exten => s,n,Set(LOCALPATH=/var/spool/fax/recvq/${LOCALSTATIONID}/)
exten => s,n,Set(MYDATE=${STRFTIME(${EPOCH},,%C%y-%m-%d-%H%M)})
exten => s,n,Set(MYFILENAME=${LOCALSTATIONID}-${MYDATE}-${CDR(uniqueid)})
exten => s,n,Set(MYFULLPATH=${LOCALPATH}${MYFILENAME})
exten => s,n,Set(KEYFULLPATH=/var/spool/fax/ssh_key_for_remote_copy)
exten => s,n,Set(SCPUSER=filecopyuser)
exten => s,n,Set(FILESERVER=fileserver.domain.com)
exten => s,n,Set(REMOTEPATH=/path/to/where/it/should/go/${LOCALSTATIONID})
exten => s,n,Set(RECORDING=${LOCALPATH}recording/${MYFILENAME}.gsm)
exten => s,n,MixMonitor(${RECORDING})
exten => s,n,Playback(silence/1)
exten => s,n,ReceiveFax(${MYFULLPATH}.tif)

; log what happened with the fax transmission
exten => h,1,System(/bin/echo ${MYFULLPATH},${CALLERID(num)},${CALLERID(name)},$
{FAXSTATUS},${FAXERROR},${FAXMODE},${FAXPAGES},${REMOTESTATIONID} >>
${LOCALPATH}fax.log)
;
; if fax is salvageable, a tif will exist.
exten => h,n,System(test -e ${MYFULLPATH}.tif)
;exten => h,n,Verbose(System call result was ${SYSTEMSTATUS})
;
; try to turn any file that exists into a pdf
exten => h,n,ExecIf($[${SYSTEMSTATUS} =
SUCCESS]?System(/usr/bin/tiff2pdf -p"letter" ${MYFULLPATH}.tif -o
${MYFULLPATH}.pdf))
;
; check if pdf exists. If the fax was too incomplete to process, no
file will exist.
; If yes, send it off to H drive
exten => h,n,System(test -e ${MYFULLPATH}.pdf)
;exten => h,n,Verbose(System call result was ${SYSTEMSTATUS})
exten => h,n,ExecIf($[${SYSTEMSTATUS} = SUCCESS]?System(/usr/bin/scp
-i ${KEYFULLPATH} ${MYFULLPATH}.pdf
${SCPUSER}@${FILESERVER}:${REMOTEPATH}))
; if tiff file exists from good fax, name it one thing
exten => h,n,ExecIf($[${FAXSTATUS} = SUCCESS]?System(/bin/mv
${MYFULLPATH}.tif /var/spool/fax/recvq/processed))
; if fax was bad, check if we still have tif. If so, move it out
exten => h,n,System(test -e ${MYFULLPATH}.tif)
;exten => h,n,Verbose(System call result was ${SYSTEMSTATUS})
exten => h,n,ExecIf($[${SYSTEMSTATUS} = SUCCESS]?System(/bin/mv
${MYFULLPATH}.tif
/var/spool/fax/recvq/processed/${MYFILENAME}-FAILED.tif))
exten => h,n,Hangup

> How much control do the ssh processes have over the call, if any?

As you can see in that particular example, I was using scp to do a
remote file copy of the received fax. I also setup MixMonitor()
against the channel with a filename that would match the cdr of the
call in case I ever needed to go back and troubleshoot a particular
fax.

>  Is that comparable to Fast_AGI?  Or EAGI?

Ummm, kindof. My example shows doing everything directly in asterisk
dialplan. AGI let's you use the language you prefer to do arbitrary
things with calls, using the AGI library for that language. Some
people prefer AGI, some people prefer dialplan. They both have their
strengths, and drawbacks.

Strength of dialplan is it's extremely debuggable. Strength of AGI is
that you get to leverage the syntax and libraries in a language you
already use, but when you want to debug, you have (in my opinion) less
introspection into what's going on unless you use the innate debugging
native to your language of choice. ('agi set debug on' helps).

My personal experience has been that I really prefer AGI when I need
to make lots of database calls, as that's where I much prefer Perl,
and much dislike the asterisk syntax. So I have a set of AGIs that use
the Perl AGI library and do arbitrary things to query the user for
digits, compare those to a database, authenticate, do web services
calls, speak back information, etc.

> I'm intrigued about the remote shell idea...  please let me know if you
> have additional information about it, ok?

As you can see from my dialplan sample, you can define a gazillion
variables, and then use them where you need them. You can also tell
from my sample that the semicolon is the comment character, and that
Verbose() command helps you generate extra output as you need it.

Feel free to ask further questions and I apologize for the late reply.



More information about the asterisk-users mailing list