I am using IBM Watson TTS for Text-to-Speech functionality. I am able to get the audio file using Postman's Send and Download functionality. But, how I am supposed to do that in Perl. I am completely new to Perl. The reason I am using Perl to do it, is that I need to implement TTS in Asterisk AGI.
Edit: I am able to save the file. But, unable to play it in Asterisk.
I am using following code snippet for the POST request and playing audio:
....
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 :(得分:0)
I assume you are using LWP::UserAgent for your $ua
and File::Temp for the tempfile
function.
tempfile
returns a filehandle and a filename. $uaresponse
is an HTTP::Response object, and its method content
returns the undecoded, raw body of the HTTP response.
You are assigning that body (which is probably the full wave file) to the variable that holds the filename of the temporary file. You never write the content to the file. You are trying to do that in your commented out code, but since you had already overwritten the filename it would not have worked.
You can use the $fh
that tempfile
gives you directly. Since wave is binary data, it makes sense to set binmode
on $fh
. You can then directly write into it.
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
}
That should be it. There is no :wav
encoding in Perl, so that part of the code you tried would not have worked anyway.
Note that in your call to tempfile
you set the UNLINK => 1
option, which means that the temporary file will be automatically deleted once your program ends. It seems like that's not what you want. It looks like you want to keep that file. Maybe File::Temp is not the right approach in that case.
答案 1 :(得分:0)
以下是最受欢迎的问题。
1)文件必须具有 EXACT 格式: wav,pcm 8khz,16 bit,mono 。任何其他格式都将被忽略。如果您有其他格式,则首先使用sox或其他工具进行更改格式。如果你不确定关于格式,你应该使用sox或其他工具来确保支持格式。
2)您发送到星号的文件名应该在末尾没有.wav扩展名。用户Asterisk :: AGI模块,无需从头开始重写agi交互。
3)文件必须具有星号用户读取的权限
4)文件所在的目录必须具有星号用户打开/读取的权限
答案 2 :(得分:0)
@ arheops和@simbabque提供的答案肯定有帮助。
阻碍我的程序正常运行的恶作剧错误是打印声明:
print "Successful with IBM \n";
我学会了在Asterisk CLI上执行打印语句的困难方式,因此,上面一个是错误的(510无效或未知命令)我忽略了。一旦我评论了打印响应,它就运行良好。
但是,如果你想使用打印,正确的方法应该是:
print "VERBOSE \" Successful with IBM \" \n";