рд╕реБрдкреНрд░рднрд╛рдд
рдХрд▓ рд░рд╛рдд рдореИрдВрдиреЗ рд╣реЗрдмреНрд░рд╛ рдХреЛ рджреЗрдЦрд╛, рдПрдХ
Google рд▓реЗрдЦ
+ рдПрд╕реНрдЯрд░рд┐рд╕реНрдХ
рдЖрдИрд╡реАрдЖрд░ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рджреЗрдЦрд╛ рдФрд░ рдореЗрд░реЗ рдмрд╛рд▓ рдореЗрд░реЗ рдХрд╛рдВрдЦ рдореЗрдВ рдЪрд▓реЗ рдЧрдПред
рднрд╛рд╖рдг рд╕рдВрд╢реНрд▓реЗрд╖рдг, рдпрд╣ рдХрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИ!
рдорд╣реЛрддреНрд╕рд╡ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдирдореВрдиреЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реИ, рд╕рд░рд▓ рдФрд░ Google рд╕реЗред
рдореИрдВрдиреЗ рддреБрд░рдВрдд рдЕрдкрдиреЗ рдкрд╕рдВрджреАрджрд╛ php рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╡рд┐рдХрд▓реНрдк рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдИ рдФрд░ рдЗрд╕реЗ Asterisk рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
AGI рдХреЗ рд░реВрдк рдореЗрдВ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ред рдореИрдВ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рд╕рдВрд╢реНрд▓реЗрд╖рдг рдХреЛ рдбрд╛рдпрд▓рдкреНрд▓реИрдиреЗрдЯ рдореЗрдВ рдПрдХрд▓ рдкрдВрдХреНрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдП, рдорд╛рдирдХ
SayDigits () рдХрдорд╛рдВрдб рдХреЗ рд░реВрдк рдореЗрдВ:
Extension.ael рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдЙрдкрдпреЛрдЧ:
s => { Answer(); Wait(1); AGI(say.php,""); AGI(say.php," "); AGI(say.php,"Habrahabr!",en); AGI(say.php," !"); AGI(say.php,"!"); AGI(say.php," "); AGI(say.php," !"); };
рдФрд░ рд╕реНрд╡рдпрдВ php рдХреЛрдб (/var/lib/asterisk/agi-bin/say.php рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП):
#!/usr/bin/php -q <?php $agivars = array(); while (!feof(STDIN)) { $agivar = trim(fgets(STDIN)); if ($agivar === '') break; $agivar = explode(':', $agivar); $agivars[$agivar[0]] = trim($agivar[1]); } extract($agivars); $text = $_SERVER["argv"][1]; if (isset($_SERVER["argv"][2])) $lang = $_SERVER["argv"][2]; else $lang = 'ru'; $md5 = md5($text); $prefix = '/var/lib/asterisk/festivalcache/'; $filename = $prefix.$md5; if (!file_exists($filename.'.alaw')) { $wget = 'wget -U "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5" '; $wget.= '"http://translate.google.com/translate_tts?q='.$text.'&tl='.$lang.'" -O '.$filename.'.mp3'; $ffmpeg = 'ffmpeg -i '.$filename.'.mp3 -ar 8000 -ac 1 -ab 64 '.$filename.'.wav -ar 8000 -ac 1 -ab 64 -f alaw '.$filename.'.alaw -map 0:0 -map 0:0'; $exec = $wget.' && '.$ffmpeg.' && rm '.$filename.'.mp3 '.$filename.'.wav'; exec($exec); } echo 'STREAM FILE "'.$filename.'" ""'."\n"; fgets(STDIN); exit(0); ?>
рдореЗрд░реЗ рддрд╛рд░рд╛рдВрдХрди рдореЗрдВ, рдореБрдЦреНрдп рдХреЛрдбреЗрдХ рдЕрд▓рд╛рд╡ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдПрдордкреА 3 рдХреЛ рддреБрд░рдВрдд рдмрджрд▓ рджреЗрддрд╛ рд╣реВрдВред
10 рдорд┐рдирдЯ рдХреА рдЦреБрд╢реА рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ рдпрд╛рдж рдЖрдпрд╛ рдХрд┐ Google рдореЗрдВ рднрд╛рд╖рдг рдкрд╣рдЪрд╛рдирдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ (рдЬреИрд╕реЗ рдХрд┐ рдореЛрдмрд╛рдЗрд▓ рдлреЛрди рд╕реЗ рдЦреЛрдЬ рдореЗрдВ)ред рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЪрдврд╝рд╛ рдФрд░ рд▓реЗрдЦ
рд╡реЙрдпрд╕ рдирд┐рдпрдВрддреНрд░рдг рдкрд╛рдпрд╛
ред рд░реВрд╕реА рднрд╛рд╖рдг рдХреА рдорд╛рдиреНрдпрддрд╛ , рдЬрд╣рд╛рдВ Google рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рднрд╛рд╖рдг рдорд╛рдиреНрдпрддрд╛ рдХреЗ рд▓рд┐рдП php рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдирд┐рд╣рд┐рдд рд╣реИред
рдореИрдВрдиреЗ AGI рдлреЙрд░реНрдо рдореЗрдВ рдХреЛрдб рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдФрд░ (/var/lib/asterisk/agi-bin/voice.pp):
#!/usr/bin/php -q <? $agivars = array(); while (!feof(STDIN)) { $agivar = trim(fgets(STDIN)); if ($agivar === '') break; $agivar = explode(':', $agivar); $agivars[$agivar[0]] = trim($agivar[1]); } extract($agivars); $filename = $_SERVER["argv"][1]; exec('flac -f -s '.$filename.'.wav -o '.$filename.'.flac'); $file_to_upload = array('myfile'=>'@'.$filename.'.flac'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU"); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: audio/x-flac; rate=8000")); curl_setopt($ch, CURLOPT_POSTFIELDS, $file_to_upload); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); $result=curl_exec ($ch); curl_close ($ch); $json_array = json_decode($result, true); $voice_cmd = $json_array["hypotheses"][0]["utterance"]; unlink($filename.'.flac'); unlink($filename.'.wav'); echo 'SET VARIABLE VOICE "'.$voice_cmd.'"'."\n"; fgets(STDIN); echo 'VERBOSE ("'.$voice_cmd.'")'."\n"; fgets(STDIN); exit(0); ?>
Google рд╡рд╛рдХреН API, flac рдФрд░ speex рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдзреНрд╡рдирд┐ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП flacред
рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рдкрд╛рда рдЪрд░ $ {VOICE} рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
Extension.ael рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
s => { Answer(); Wait(1); AGI(say.php,""); AGI(say.php,""); AGI(say.php," "); Record(/tmp/${UNIQUEID}.wav,3,20); AGI(say.php," "); Playback(/tmp/${UNIQUEID}); AGI(voice.php,/tmp/${UNIQUEID}); AGI(say.php," "); AGI(say.php,"${VOICE}"); Hangup(); };
рд░рд┐рдХреЙрд░реНрдб 20 рд╕реЗрдХрдВрдб рдХреА рдЕрдзрд┐рдХрддрдо рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рдПрдХ wav рдлрд╝рд╛рдЗрд▓ рд░рд┐рдХреЙрд░реНрдб рдХрд░рддрд╛ рд╣реИ рдФрд░ 3 рд╕реЗрдХрдВрдб рдХреЗ рдореМрди рдХреЗ рдмрд╛рдж рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред
рдЪреВрдВрдХрд┐ рдпрд╣ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИ, рд╣рдо рдЬреЛ рдХрд╣рддреЗ рд╣реИрдВ рдЙрд╕реЗ рд╕реБрдирддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рдкрд╛рда рдХреЛ рд╕рдВрд╢реНрд▓реЗрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рдореИрдВ рдХреНрдпрд╛ рдХрд╣ рд╕рдХрддрд╛ рд╣реВрдБ, Google - рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд┐рдпрд╛!
рдЕрдм рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рддреНрдпреМрд╣рд╛рд░ рдФрд░ рд╕реНрдлрд┐рдВрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рд╢реБрджреНрдз рддрд╛рд░рд╛рдВрдХрди рдХреИрд╕реЗ рд╕рдВрд╢реНрд▓реЗрд╖рдг рдФрд░ рднрд╛рд╖рдг рдорд╛рдиреНрдпрддрд╛ рд╕рд┐рдЦрд╛ рд╕рдХрддрд╛ рд╣реИред
рдФрд░ рдЕрдЧрд░ рдЕрдзрд┐рдХрд╛рд░реА рдЖрдкрд╕реЗ рддреБрд░рдВрдд рдЖрдИрд╡реАрдЖрд░ рдореЗрдиреВ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣реЗрдВ, рддреЛ рд╣рдо рдЖрдкрдХреЛ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!
рджреНрд╡рд╛рд░рд╛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛рдореИрдВрдиреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА
рдЯрд┐рдкреНрдкрдгреА int80h рдкрдврд╝реА,
Google рдЕрдиреБрд╡рд╛рдж рдПрдкреАрдЖрдИ рд╕реЗ рдмрд┐рдВрдЧ рдЯреНрд░рд╛рдВрд╕рд▓реЗрдЯ рдПрдкреАрдЖрдИ рдореЗрдВ
рдкреНрд░рд╡рд╛рд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝рд╛ рдФрд░ рд╕реЛрдЪрд╛ рдХрд┐ рд╕рдм рдХреБрдЫ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рдВрд╕реНрдХрд░рдг 2.0
Microsoft рдЕрдиреБрд╡рд╛рджрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднрд╛рд╖рдг рдХреЛ рд╕рдВрд╢реНрд▓реЗрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рдХрд╣реЛ:
#!/usr/bin/php -q <?php $agivars = array(); while (!feof(STDIN)) { $agivar = trim(fgets(STDIN)); if ($agivar === '') break; $agivar = explode(':', $agivar); $agivars[$agivar[0]] = trim($agivar[1]); } extract($agivars); $text = $_SERVER["argv"][1]; if (isset($_SERVER["argv"][2]) && in_array($_SERVER["argv"][2], array('g','m'))) $voice = $_SERVER["argv"][2]; else $voice = 'g'; if (isset($_SERVER["argv"][3])) $lang = $_SERVER["argv"][3]; else $lang = 'ru'; $md5 = md5($text.$voice.$lang); $prefix = '/var/lib/asterisk/festivalcache/'; $appid = 'T0CQJrrwQ1NcJFlJshEfWTzaI18B4TzVvBKx9CDoLvf8*'; $filename = $prefix.$md5; if (!file_exists($filename.'.alaw')) { if ($voice == 'm') { $ext = '.wav'; exec('wget "http://api.microsofttranslator.com/V2/Http.svc/Speak?language='.$lang.'&format=audio/wav&options=MaxQuality&appid='.$appid.'&text='.$text.'" -O '.$filename.$ext); } else { $ext = '.mp3'; exec('wget -U "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5" "http://translate.google.com/translate_tts?q='.$text.'&tl='.$lang.'" -O '.$filename.$ext); } if (@filesize($filename.$ext) > 0) { exec('ffmpeg -i '.$filename.$ext.' -ar 8000 -ac 1 -ab 64 -f alaw '.$filename.'.alaw -map 0:0'); } unlink($filename.$ext); } if (file_exists($filename.'.alaw')) { echo 'STREAM FILE "'.$filename.'" ""'."\n"; fgets(STDIN); } else { echo 'VERBOSE ("Speech Error!")'."\n"; fgets(STDIN); } exit(0); ?>
Microsoft wav рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдзреНрд╡рдирд┐ рджреЗрддрд╛ рд╣реИ (mp3 рдЧреБрдгрд╡рддреНрддрд╛ рд╢реВрдиреНрдп рд╣реИ) рдФрд░ рдХреБрдЫ Bing AppId рдХреЗ рд▓рд┐рдП рдкреВрдЫрддрд╛ рд╣реИ (рдореИрдВрдиреЗ рдЗрд╕реЗ microsofttranslator.com рд╕реЗ рд▓рд┐рдпрд╛, рдЖрдЗрдП рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХрдм рддрдХ рдЬреАрд╡рд┐рдд рд░рд╣реЗрдЧрд╛)ред
рд╕рдВрд╢реНрд▓реЗрд╖рдг рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдореБрдЭреЗ Google рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЦрд░рд╛рдм рд▓рдЧ рд░рд╣реА рдереА, рд▓реЗрдХрд┐рди рдирд╛рдореЛрдВ рдореЗрдВ рдЬреЛрд░ рдЕрдзрд┐рдХ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдбрд╛рд▓рд╛ рдЧрдпрд╛ рд╣реИред
AGI(say.php,"",m); AGI(say.php,"",${},${}); ${} - m g ( = g) ${} - ru, en ( = ru)
рд░реВрд╕реА рдкрд╛рда рдХреЗрд╡рд▓ рдЖрд░рдпреВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдЕрдВрдЧреНрд░реЗрдЬреА рд╣рдореЗрд╢рд╛ рд░рд╣реЗрдЧреА, рд▓реЗрдХрд┐рди рдЖрд░рдпреВ рдХреЗ рд╕рд╛рде рдпрд╣ "рдЯреВрдЯ" рдЬрд╛рдПрдЧрд╛ред
рдкрд╛рда рдореЗрдВ рдЙрдЪреНрдЪрд╛рд░рдг рдХрд╛рд░реНрдп ('рд╕реНрд╡рд░ рдХреЗ рд╕рд╛рдордиреЗ) рдФрд░ рд╡рд┐рд░рд╛рдо рдЪрд┐рд╣реНрдиреЛрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП!) рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдмрджрд▓реЗрдВред
рдкреБрдирд╢реНрдЪ: рдмрджрд▓рд╛ рдЧрдпрд╛ рдХрд┐ рд╡рд╛рдХреН рдкрд╣рдЪрд╛рди рдЦрд╛рд▓реА рдкрд╛рда рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдЖрдк рдПрдХ рд╣реА рдлрд╛рдЗрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рднреЗрдЬрддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдЖрд╕рд╛рдиреА рд╕реЗ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рдЕрдЬреАрдм рд╣реИ :-)