📄 phpagi.php
字号:
$buffer .= chr($res['result']); return $res; } return array('code'=>AGIRES_OK, 'result'=>ord($buffer{strlen($buffer)-1})); } /** * Plays the given file and receives DTMF data. * Return early if $buffer is adequate for request. * * This is similar to STREAM FILE, but this command can accept and return many DTMF digits, * while STREAM FILE returns immediately after the first DTMF digit is detected. * * Asterisk looks for the file to play in /var/lib/asterisk/sounds by default. * * If the user doesn't press any keys when the message plays, there is $timeout milliseconds * of silence then the command ends. * * The user has the opportunity to press a key at any time during the message or the * post-message silence. If the user presses a key while the message is playing, the * message stops playing. When the first key is pressed a timer starts counting for * $timeout milliseconds. Every time the user presses another key the timer is restarted. * The command ends when the counter goes to zero or the maximum number of digits is entered, * whichever happens first. * * If you don't specify a time out then a default timeout of 2000 is used following a pressed * digit. If no digits are pressed then 6 seconds of silence follow the message. * * If you don't specify $max_digits then the user can enter as many digits as they want. * * Pressing the # key has the same effect as the timer running out: the command ends and * any previously keyed digits are returned. A side effect of this is that there is no * way to read a # key using this command. * * @link http://www.voip-info.org/wiki-get+data * @param string $buffer * @param string $filename file to play. Do not include file extension. * @param integer $timeout milliseconds * @param integer $max_digits * @return array, see evaluate for return information. ['result'] holds the digits and ['data'] holds the timeout if present. * * This differs from other commands with return DTMF as numbers representing ASCII characters. */ function fastpass_get_data(&$buffer, $filename, $timeout=NULL, $max_digits=NULL) { if(is_null($max_digits) || strlen($buffer) < $max_digits) { if($buffer == '') { $res = $this->get_data($filename, $timeout, $max_digits); if($res['code'] == AGIRES_OK) $buffer .= $res['result']; return $res; } else { while(is_null($max_digits) || strlen($buffer) < $max_digits) { $res = $this->wait_for_digit(); if($res['code'] != AGIRES_OK) return $res; if($res['result'] == ord('#')) break; $buffer .= chr($res['result']); } } } return array('code'=>AGIRES_OK, 'result'=>$buffer); } // ********************************************************************************************************* // ** DERIVED ** // ********************************************************************************************************* /** * Menu. * * This function presents the user with a menu and reads the response * * @param array $choices has the following structure: * array('1'=>'*Press 1 for this', // festival reads if prompt starts with * * '2'=>'some-gsm-without-extension', * '*'=>'*Press star for help'); * @return mixed key pressed on sucess, -1 on failure */ function menu($choices, $timeout=2000) { $keys = join('', array_keys($choices)); $choice = NULL; while(is_null($choice)) { foreach($choices as $prompt) { if($prompt{0} == '*') $ret = $this->text2wav(substr($prompt, 1), $keys); else $ret = $this->stream_file($prompt, $keys); if($ret['code'] != AGIRES_OK || $ret['result'] == -1) { $choice = -1; break; } if($ret['result'] != 0) { $choice = chr($ret['result']); break; } } if(is_null($choice)) { $ret = $this->get_data('beep', $timeout, 1); if($ret['code'] != AGIRES_OK || $ret['result'] == -1) $choice = -1; elseif($ret['result'] != '' && strpos(' '.$keys, $ret['result'])) $choice = $ret['result']; } } return $choice; } /** * Goto - Set context, extension and priority. * * @param string $context * @param string $extension * @param string $priority */ function goto($context, $extension='s', $priority=1) { $this->set_context($context); $this->set_extension($extension); $this->set_priority($priority); } /** * Parse caller id. * * @example examples/dtmf.php Get DTMF tones from the user and say the digits * @example examples/input.php Get text input from the user and say it back * * "name" <proto:user@server:port> * * @param string $callerid * @return array('Name'=>$name, 'Number'=>$number) */ function parse_callerid($callerid=NULL) { if(is_null($callerid)) $callerid = $this->request['agi_callerid']; $ret = array('name'=>'', 'protocol'=>'', 'username'=>'', 'host'=>'', 'port'=>''); $callerid = trim($callerid); if($callerid{0} == '"' || $callerid{0} == "'") { $d = $callerid{0}; $callerid = explode($d, substr($callerid, 1)); $ret['name'] = array_shift($callerid); $callerid = join($d, $callerid); } $callerid = explode('@', trim($callerid, '<> ')); $username = explode(':', array_shift($callerid)); if(count($username) == 1) $ret['username'] = $username[0]; else { $ret['protocol'] = array_shift($username); $ret['username'] = join(':', $username); } $callerid = join('@', $callerid); $host = explode(':', $callerid); if(count($host) == 1) $ret['host'] = $host[0]; else { $ret['host'] = array_shift($host); $ret['port'] = join(':', $host); } return $ret; } /** * Use festival to read text. * * @example examples/dtmf.php Get DTMF tones from the user and say the digits * @example examples/input.php Get text input from the user and say it back * @example examples/ping.php Ping an IP address * * @link http://www.cstr.ed.ac.uk/projects/festival/ * @param string $text * @param string $escape_digits * @param integer $frequency * @return array, see evaluate for return information. */ function text2wav($text, $escape_digits='', $frequency=8000) { $text = trim($text); if($text == '') return true; $hash = md5($text); $fname = $this->config['phpagi']['tempdir'] . DIRECTORY_SEPARATOR; $fname .= 'text2wav_' . $hash; // create wave file if(!file_exists("$fname.wav")) { // write text file if(!file_exists("$fname.txt")) { $fp = fopen("$fname.txt", 'w'); fputs($fp, $text); fclose($fp); } shell_exec("{$this->config['festival']['text2wave']} -F $frequency -o $fname.wav $fname.txt"); } else { touch("$fname.txt"); touch("$fname.wav"); } // stream it $ret = $this->stream_file($fname, $escape_digits); // clean up old files $delete = time() - 2592000; // 1 month foreach(glob($this->config['phpagi']['tempdir'] . DIRECTORY_SEPARATOR . 'text2wav_*') as $file) if(filemtime($file) < $delete) unlink($file); return $ret; } /** * Use Cepstral Swift to read text. * * @link http://www.cepstral.com/ * @param string $text * @param string $escape_digits * @param integer $frequency * @return array, see evaluate for return information. */ function swift($text, $escape_digits='', $frequency=8000, $voice=NULL) { if(!is_null($voice)) $voice = "-n $voice"; elseif(isset($this->config['cepstral']['voice'])) $voice = "-n {$this->config['cepstral']['voice']}"; $text = trim($text); if($text == '') return true; $hash = md5($text); $fname = $this->config['phpagi']['tempdir'] . DIRECTORY_SEPARATOR; $fname .= 'swift_' . $hash; // create wave file if(!file_exists("$fname.wav")) { // write text file if(!file_exists("$fname.txt")) { $fp = fopen("$fname.txt", 'w'); fputs($fp, $text); fclose($fp); } shell_exec("{$this->config['cepstral']['swift']} -p audio/channels=1,audio/sampling-rate=$frequency $voice -o $fname.wav -f $fname.txt"); } // stream it $ret = $this->stream_file($fname, $escape_digits); // clean up old files $delete = time() - 2592000; // 1 month foreach(glob($this->config['phpagi']['tempdir'] . DIRECTORY_SEPARATOR . 'swift_*') as $file) if(filemtime($file) < $delete) unlink($file); return $ret; } /** * Text Input. * * Based on ideas found at http://www.voip-info.org/wiki-Asterisk+cmd+DTMFToText * * Example: * UC H LC i , SP h o w SP a r e SP y o u ? * $string = '*8'.'44*'.'*5'.'444*'.'00*'.'0*'.'44*'.'666*'.'9*'.'0*'.'2*'.'777*'.'33*'.'0*'.'999*'.'666*'.'88*'.'0000*'; * * @link http://www.voip-info.org/wiki-Asterisk+cmd+DTMFToText * @example examples/input.php Get text input from the user and say it back * * @return string */ function text_input($mode='NUMERIC') { $alpha = array( 'k0'=>' ', 'k00'=>',', 'k000'=>'.', 'k0000'=>'?', 'k00000'=>'0', 'k1'=>'!', 'k11'=>':', 'k111'=>';', 'k1111'=>'#', 'k11111'=>'1', 'k2'=>'A', 'k22'=>'B', 'k222'=>'C', 'k2222'=>'2', 'k3'=>'D', 'k33'=>'E', 'k333'=>'F', 'k3333'=>'3', 'k4'=>'G', 'k44'=>'H', 'k444'=>'I', 'k4444'=>'4', 'k5'=>'J', 'k55'=>'K', 'k555'=>'L', 'k5555'=>'5', 'k6'=>'M', 'k66'=>'N', 'k666'=>'O', 'k6666'=>'6', 'k7'=>'P', 'k77'=>'Q', 'k777'=>'R', 'k7777'=>'S', 'k77777'=>'7', 'k8'=>'T', 'k88'=>'U', 'k888'=>'V', 'k8888'=>'8', 'k9'=>'W', 'k99'=>'X', 'k999'=>'Y', 'k9999'=>'Z', 'k99999'=>'9'); $symbol = array('k0'=>'=', 'k1'=>'<', 'k11'=>'(', 'k111'=>'[', 'k1111'=>'{', 'k11111'=>'1', 'k2'=>'@', 'k22'=>'$', 'k222'=>'&', 'k2222'=>'%', 'k22222'=>'2', 'k3'=>'>', 'k33'=>')', 'k333'=>']', 'k3333'=>'}', 'k33333'=>'3', 'k4'=>'+', 'k44'=>'-', 'k444'=>'*', 'k4444'=>'/', 'k44444'=>'4', 'k5'=>"'", 'k55'=>'`', 'k555'=>'5', 'k6'=>'"', 'k66'=>'6', 'k7'=>'^', 'k77'=>'7', 'k8'=>"\\",'k88'=>'|', 'k888'=>'8', 'k9'=>'_', 'k99'=>'~', 'k999'=>'9'); $text = ''; do { $command = false; $result = $this->get_data('beep'); foreach(explode('*', $result['result']) as $code) { if($command) { switch($code{0}) { case '2': $text = substr($text, 0, strlen($text) - 1); break; // backspace case '5': $mode = 'LOWERCASE'; break; case '6': $mode = 'NUMERIC'; break; case '7': $mode = 'SYMBOL'; break; case '8': $mode = 'UPPERCASE'; break; case '9': $text = explode(' ', $text); unset($text[count($text)-1]); $text = join(' ', $text); break; // backspace a word } $code = substr($code, 1); $command = false; } if($code == '') $command = true; elseif($mode == 'NUMERIC') $text .= $code; elseif($mode == 'UPPERCASE' && isset($alpha['k'.$code])) $text .= $alpha['k'.$code]; elseif($mode == 'LOWERCASE' && isset($alpha['k'.$code])) $text .= strtolower($alpha['k'.$code]); elseif($mode == 'SYMBOL' && isset($symbol['k'.$code])) $text .= $symbol['k'.$code]; } $this->say_punctuation($text); } while(substr($result['result'], -2) == '**'); return $text; } /** * Say Puncutation in a string. * * @param string $text * @param string $escape_digits * @param integer $frequency
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -