2016-12-09 6 views
0

Я использую IBM Watson TTS для функциональности Text-to-Speech. Я могу получить аудиофайл с помощью функции Postman's Send and Download. Но, как я должен это делать в Perl. Я совершенно не знаком с Perl. Причина, по которой я использую Perl для этого, заключается в том, что мне нужно реализовать TTS в Asterisk AGI.Как получить аудиофайл WAV с использованием HTTP POST в Perl и воспроизвести его в Asterisk AGI

Редактировать: Я могу сохранить файл. Но играть в Asterisk не удалось.

Я использую следующий фрагмент кода для запроса POST и воспроизведения аудио:

.... 
my $uaresponse = $ua->post(
    "$url", 
    Content_Type => "application/json", 
    Accept => "audio/wav", 
    Authorization => "Basic OWFmMjhhYmItMWFmMi00ZjU0LWE1YTAtNTJhNGUxNjRjNGQ1OnlkYWgwN3BRdEJMVA==", 
    Content => $json_text, 
); 

if(!$uaresponse->is_success){ 
    print "Failed request to IBM \n"; 
} else{ 
    print "Successful with IBM \n"; 

    ($fh, $tmpname) = tempfile("ggl_XXXXXXXX", DIR => $tmpdir, UNLINK => 1); 

    $tmpname = $uaresponse->content; 

# my approach is wrong somewhere here...?? 

    #print "$tmpname\n"; 


#   open(my $out, '>:wav', "$tmpname.wav") or die "unable to open $!"; 
#   print $out pack('a*', $ua_response2->content); 

    # Playback and save file in cache # 
    $res = playback($tmpname, $intkey); 
    die if ($res < 0); 
    last if ($res > 0); 

} 

sub checkresponse { 
my $input = <STDIN>; 
my @values; 

chomp $input; 
if ($input =~ /^200 result=(-?\d+)\s?(.*)$/) { 
    @values = ("$1", "$2"); 
} else { 
    $input .= <STDIN> if ($input =~ /^520-Invalid/); 
    warn "$name Unexpected result: $input\n"; 
    @values = (-1, -1); 
} 
return @values; 
} 

sub playback { 
my ($file, $keys) = @_; 
my @response; 

print "STREAM FILE $file \"$keys\"\n"; 
@response = checkresponse(); 
if ($response[0] >= 32 && chr($response[0]) =~ /[\w*#]/) { 
    console_log("Got digit chr($response[0])") if ($debug); 
    print "SET EXTENSION ", chr($response[0]), "\n"; 
    checkresponse(); 
    print "SET PRIORITY 1\n"; 
    checkresponse(); 
} elsif ($response[0] == -1) { 
    console_log("Failed to play $file."); 
} 
return $response[0]; 
} 
+0

Рассматривали вы используете EAGI потоковое аудио непосредственно из сценария? https://wiki.asterisk.org/wiki/display/AST/Application_EAGI – QuickDanger

ответ

0

Я предполагаю, что вы используете LWP::UserAgent для $ua и File::Temp для функции tempfile.

tempfile возвращает дескриптор файла и filename. $uaresponse - это объект HTTP::Response, а его method content возвращает неуказанное, необработанное тело ответа HTTP.

Вы назначаете это тело (вероятно, полный волновой файл) переменной, которая содержит имя файла временного файла. Вы никогда не записываете содержимое в файл. Вы пытаетесь сделать это в своем прокомментированном коде, но поскольку вы уже перезаписали имя файла, это не сработало бы.

Вы можете использовать $fh, который дает tempfile. Поскольку волна представляет собой двоичные данные, имеет смысл установить binmode на $fh. Затем вы можете напрямую писать в нее.

if(!$uaresponse->is_success){ 
    print "Failed request to IBM \n"; 
} else{ 
    print "Successful with IBM \n"; 

    my ($fh, $tmpname) = tempfile("ggl_XXXXXXXX.wav", DIR => $tmpdir, UNLINK => 1); 
    binmode $fh; 
    print $fh $uaresponse->content; # or with pack if you want 
} 

Это должно быть так. В Perl нет кодировки :wav, так что часть кода, который вы пытались, никак не сработала.

Обратите внимание, что в вашем телефоне tempfile вы устанавливаете опцию UNLINK => 1, что означает, что временный файл будет автоматически удален после завершения вашей программы. Похоже, это не то, что вы хотите. Похоже, вы хотите сохранить этот файл. Возможно, файл :: Temp не подходит для этого.

+0

Спасибо, я попробую. –

+0

Другой проблемой, с которой я столкнулся, является сохранение файла как «ggl_XXXX» без расширения .wav, поэтому, когда я пытаюсь воспроизвести файл, используя , напечатайте «STREAM FILE $ file \» $ keys \ "\ n" ; Я получаю ошибку «не удалось воспроизвести». –

+0

@DhawanGupta хорошо, вы не сказали ему использовать правильное расширение. Но я не понимаю, почему это имеет значение, если это не Windows. – simbabque

0

В первую очередь это номера в порядке.

1) Файл должен иметь EXACT Формат: WAV, PCM 8 кГц, 16 бит, моно. Любой другой формат будет проигнорирован. Если у вас другой формат, вы сначала используете sox или другой инструмент для изменения формата. Если вы НЕУДАЧУ о формате, вы должны использовать sox или другой инструмент, чтобы быть уверенным в том, что поддерживается формат.

2) Имя файла, которое вы отправляете на звездочку, должно быть без расширения .wav в конце. Пользователь Asterisk :: Модуль AGI, не нужно переписывать взаимодействие с нуля.

3 файла) должны иметь разрешения для чтения пользователя Звездочки

4) Dir где файл находится, должны иметь разрешения на открытие/чтение пользователя Звездочки

+0

Я думаю, что причиной могут быть 3-я и 4-я. Я использовал «chmod 777» для разрешения файла. Правильно ли это сделать? Каким должен быть правильный путь? –

0

Ответы, предоставленные @arheops и @simbabque, безусловно, помогли ,

mischievious ошибка, которая была препятствует нормальному функционированию моей программы был оператор печати:

print "Successful with IBM \n"; 

Я узнал это на своей шкуре, что печать инструкции выполняются на Asterisk CLI так, выше один давал error (510 Invalid или Unknown Command), которую я пропускал. Как только я прокомментировал ответ на печать, он работал нормально.

Однако, если вы чувствуете, как с помощью печати, правильный путь должен быть:

print "VERBOSE \" Successful with IBM \" \n";