Not really a question, merely a report on an experiment.
I’ve been experimenting with feeding audio to Asterisk via FFmpeg, as an example of how to use AGI-in-AMI. The idea is that you can have an input audio file in just any format you like, and FFmpeg will convert it to something acceptable to Asterisk on-the-fly. The basic setup looks like this:
pipe_seq += 1 outpipe_base = os.path.join(tempdir, "%0.6d" % pipe_seq) # This is the name of the media file that I pass to Asterisk # (no extension allowed). outpipe_full = outpipe_base + ".gsm" # This is the actual name of the file, and hopefully Asterisk # will use this name. os.mkfifo(outpipe_full, mode = 0o600) child = subprocess.Popen \ ( args = ( "ffmpeg", "-i", audio_file, "-loglevel", "quiet", # quiet messages, unfortunately quiets error reports as well "-f", "gsm", "-acodec", "gsm", "-ar", "8000", "-af", ",".join(["lowpass=f=3000"] * 16), "-y", outpipe_full, ), stdin = subprocess.DEVNULL, stdout = subprocess.DEVNULL, )
(I tried various filter options available in my FFmpeg build, but the one above–applying a simple 3dB filter 16 times–seemed the simplest way to get decent results.)
The example dialplan context is
[audio-player] exten => _X.,1,Verbose(entering audio player) exten => _X.,n,AGI(agi:async,audio-player) exten => _X.,n,Verbose(exiting audio player) exten => _X.,n,Hangup()
And my AMI script listens for the corresponding AsyncAGIStart
events for doing its stuff. After the above setup, I tell Asterisk to stream the generated audio via an AGI-in-AMI command:
await mgr.send_request \ ( action = "AGI", parms = { "Channel" : evt["Channel"], "Command" : "STREAM FILE \"%s\" \"\"" % outpipe_base, } )
Then when the script sees the AGIExecEnd
event for the “STREAM FILE” command, it knows to shut things down and issue an ASYNCAGI BREAK command to resume dialplan execution.
What I found was, Asterisk registers a few complaints about being asked to read from a pipe, e.g.:
WARNING[682534][C-00000024]: file.c:611 filehelper: File /tmp/aster-audio-player7x653mxe/000003.gsm detected to have zero size. -- Playing '/tmp/aster-audio-player7x653mxe/000003.gsm' (escape_digits=) (sample_offset 0) (language 'en') WARNING[682534][C-00000024]: format_gsm.c:105 gsm_seek: Unable to determine current position in g719 filestream 0x7fe9e4010cb0: Illegal seek WARNING[682534][C-00000024]: format_gsm.c:167 gsm_tell: Unable to determine offset for gsm filestream 0x7fe9e4010cb0: Illegal seek WARNING[682534][C-00000024]: format_gsm.c:105 gsm_seek: Unable to determine current position in g719 filestream 0x7fe9e4010cb0: Illegal seek
but otherwise it seems to work. Naturally I avoid specifying a nonzero initial offset…
Another thing is, during testing, if my FFmpeg child process crashes before producing any output, then the Asterisk channel gets stuck and cannot be hung up. I think this is because it is blocked trying to open the FIFO for reading until somebody opens it for writing. (I can do e.g. “echo >fifo-name” from a command prompt to unblock it, assuming fifo-name is still accessible.)
Anyway, that’s what I have found so far. Feel free to offer comments, up to and including “this is a really, really bad idea”.