I am using python 2 in asterisk 2 there is a section where code listen to callers audio and process the audio. During the process there is a silence of 15 sec before the audio is played. I want to add a music during the processing of audio. Is there a way to do this. the extension.config is like this
[autoattendant2]
exten => 5555,1,same=>n,Answer()
same=> n, AGI(/root/code_base/Queue/code2.py)
same=>n,hangup()
Below is the python code
#!/usr/bin/env python2
import sys
import json
from datetime import datetime
#!/usr/bin/env python2
import sys
import re
import time
import random
import subprocess
import requests
import json
from datetime import datetime
env = {}
tests = 0;
while 1:
line = sys.stdin.readline().strip()
if line == '':
break
key,data = line.split(':')
if key[:4] <> 'agi_':
#skip input that doesn't begin with agi_
sys.stderr.write("Did not work!\n");
sys.stderr.flush()
continue
key = key.strip()
data = data.strip()
if key <> '':
env[key] = data
sys.stderr.write("AGI Environment Dump:\n");
sys.stderr.flush()
for key in env.keys():
sys.stderr.write(" -- %s = %s\n" % (key, env[key]))
sys.stderr.flush()
def checkresult (params):
params = params.rstrip()
if re.search('^200',params):
result = re.search('result=(\d+)',params)
if (not result):
sys.stderr.write("FAIL ('%s')\n" % params)
sys.stderr.flush()
return -1
else:
result = result.group(1)
#debug("Result:%s Params:%s" % (result, params))
sys.stderr.write("PASS (%s)\n" % result)
sys.stderr.flush()
return result
else:
sys.stderr.write("FAIL (unexpected result '%s')\n" % params)
sys.stderr.flush()
return -2
def change_file(path, cid):
# one of the process example
filename = 'complain{0}'.format(cid)
#filename =
input_file = path + '/' + filename + '.gsm'
output_file = path + '/' + filename + '.wav'
#command = "sox {} -r 8000 -c 1 {}".format(input_file, output_file)
command = "sox {} -b 16 -r 44100 -c 1 {} trim 0 7 vol 2".format(input_file, output_file)
subprocess.call(command, shell=True)
pbcheck = requests.get("http://127.0.0.1:8000/STT_complaint/", params = {"address" : output_file, "lang" : language, "cid":cid, "phone":callerid, "start_time":now})
res = pbcheck.content
res2 = res.replace('"', "")
return res2
def run_cmd(cmd):
#This runs the general command
sys.stderr.write(cmd)
sys.stderr.flush()
sys.stdout.write(cmd)
sys.stdout.flush()
result = sys.stdin.readline().strip()
checkresult(result)
#language = "ben"
# asking problem recorded audio
cmd_streaming = "STREAM FILE /root/code_base/recorded_voices/{0}/plz_tell_problem \"\"\n".format(language, language)
run_cmd(cmd_streaming)
# listening to caller / recording caller voice
cmd_record = "RECORD FILE {0}/complain{1} gsm 1234 {2} s=3 \"\"\n".format(fixed_path, cid, 15)
run_cmd(cmd_record)
#processing audio
processed_output = change_file(path , cid) # while this is executing ad giving output i want to play wait_music and then stop to run
# while processing play this
cmd_streaming = "STREAM FILE /root/code_base/recorded_voices/wait_music \"\"\n".format(language, language)
run_cmd(cmd_streaming)
# once output received (processed_output) play next audio
cmd_streaming = "STREAM FILE /root/code_base/recorded_voices/next_instruction \"\"\n")
run_cmd(cmd_streaming)
You can create a separate thread (‘pthreads’) for the processing of your background task.
Way, way long ago, I wrote an AGI (in C) to process credit card transactions. The authorization process could take several seconds so I created a separate thread to play a ‘dead air filler’ (‘Thank you for your entry and get ready for a great time’). Usually the authorization finished before the prompt finished so the ‘caller experience’ was that the authorization was instantaneous.
Be aware that while your background thread is playing the prompt, you can’t ask Asterisk to do anything else and any I/O to STDIN/STDOUT will break the AGI protocol.
You don’t want to use GSM for music on hold. You don’t really want to send music at all if your codec is GSM.
GSM is a vocal tract model based codec, and is specifically designed for human speech. Any sounds that are not human speech are likely to be significantly compromised by using GSM. The same applies for G.729. They both achieve low bits rates at the expense of only being suitable for speech.
It is possible that there are specialist musical arrangements optimised for such codecs.
its a speech only saying we are processing pls hold. If i can implement it i will change the file . But how to add this file and in music on hold is still the issue i tried
run_cmd(“SET MUSIC on “”\n”) didnt work
when there is operation going on in I want to play a music instead of silence.
I saw the function python music on hold available but not sire how to use it in python.
[autoattendant2]
exten => 5555,1,same=>n,Answer()
same=> n, AGI(/root/code_base/Queue/code2.py)
same=>n,hangup()
#!/usr/bin/env python2
import sys
env = {}
tests = 0;
while 1:
line = sys.stdin.readline().strip()
if line == '':
break
key,data = line.split(':')
if key[:4] <> 'agi_':
#skip input that doesn't begin with agi_
sys.stderr.write("Did not work!\n");
sys.stderr.flush()
continue
key = key.strip()
data = data.strip()
if key <> '':
env[key] = data
sys.stderr.write("AGI Environment Dump:\n");
sys.stderr.flush()
for key in env.keys():
sys.stderr.write(" -- %s = %s\n" % (key, env[key]))
sys.stderr.flush()
def checkresult (params):
params = params.rstrip()
if re.search('^200',params):
result = re.search('result=(\d+)',params)
if (not result):
sys.stderr.write("FAIL ('%s')\n" % params)
sys.stderr.flush()
return -1
else:
result = result.group(1)
#debug("Result:%s Params:%s" % (result, params))
sys.stderr.write("PASS (%s)\n" % result)
sys.stderr.flush()
return result
else:
sys.stderr.write("FAIL (unexpected result '%s')\n" % params)
sys.stderr.flush()
return -2
def change_file(path, cid):
# one of the process example
filename = 'complain{0}'.format(cid)
#filename =
pbcheck = requests.get("http://127.0.0.1:8000/STT_complaint/", params = {"address" : output_file, "lang" : language, "cid":cid, "phone":callerid, "start_time":now})
res = pbcheck.content
res2 = res.replace('"', "")
return res2
def run_cmd(cmd):
#This runs the general command
sys.stderr.write(cmd)
sys.stderr.flush()
sys.stdout.write(cmd)
sys.stdout.flush()
result = sys.stdin.readline().strip()
checkresult(result)
#language = "ben"
# asking problem recorded audio
cmd_streaming = "STREAM FILE /root/code_base/recorded_voices/{0}/plz_tell_problem \"\"\n".format(language, language)
run_cmd(cmd_streaming)
# listening to caller / recording caller voice
cmd_record = "RECORD FILE {0}/complain{1} gsm 1234 {2} s=3 \"\"\n".format(fixed_path, cid, 15)
run_cmd(cmd_record)
#processing audio
processed_output = change_file(path , cid) # while this is executing ad giving output i want to play wait_music and then stop to run
# while processing play this
cmd_streaming = "STREAM FILE /root/code_base/recorded_voices/wait_music \"\"\n".format(language, language)
run_cmd(cmd_streaming)
# once output received (processed_output) play next audio
cmd_streaming = "STREAM FILE /root/code_base/recorded_voices/next_instruction \"\"\n")
run_cmd(cmd_streaming)
The auto-generated documentation is broken. I don’t know if that is because the syntax description has been done incorrectly, or because there is no way of validly describing the syntax, but in Cobol type notation, the syntax it seems to be describing is:
SET MUSIC {on|off} <class>
where <class> is mandatory, and must match a section name in musiconhold.conf. However, there is a discrepancy between the attempted formal definition and the free text description, which seems to suggest that the full syntax is:
SET MUSIC {on|off} [<class>]
Either way, the actual file is indirected via a section in musiconhold.conf.
I haven’t sought out the actual implementation to see how it is actually parsed.
The CLI command ‘agi show commands topic set music’ says the class is optional:
Enables/Disables the music on hold generator. If <class> is not specified, then
the ‘default’ music on hold class will be used. This generator will be stopped
automatically when playing a file.
Always returns ‘0’.
This is all generated from structured comments, and, as I said, there is a conflict between the part that generates the description that you have quoted and the part the should have generated the formal syntax in the wiki, which has required=true for both parameters.
Whilst I suspect that the description is correct, one would have to try it, or go to the source code, to be sure.
See:
This line appears to be trying to say that the class is mandatory:
I put a sleep here as an example, in my environment I am waiting for an answer of a query and the music on hold will play till the process is finished and I received the answer.