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”. ![]()