【问题标题】:POST base64 encoded file to google speech api using perl使用 perl 将 base64 编码文件发布到谷歌语音 api
【发布时间】:2016-09-21 22:55:46
【问题描述】:

在将 json 字符串发布到 google 语音 api 时,我无法将 FLAC 音频文件编码为 base64。我注意到谷歌的回复中有一些 \n,不确定 base64 是否不够好,或者我可能没有完全掌握如何构建这样的字符串并使它们 json-y 足以满足谷歌。我倾向于 utf-8 编码,但我最后一次尝试进一步处理要发送的信息给我留下了来自 perl 的大量其他错误消息。任何指针都会有很大的帮助! (即使指针是放弃我自己这样做并向谷歌支付支持费)

Error message:
    {
      "error": {
        "code": 400,
        "message": "Invalid value at 'audio.content' (TYPE_BYTES), Base64 decoding failed for "ZkxhQwAAACIQABAAAAlJABQpAfQA8AABS+DDBqlWu7Ba27gz/koR4+04AwAAJAAAAAAAAAAAAAAA\nAAAAAAAQAAAAAAAAATAAAAAAAAABQ5kQAAQAACggAAAAcmVmZXJlbmNlIGxpYkZMQUMgMS4zLjAg\nMjAxMzA1MjYAAAAAgQA...

我的代码是:

#!/usr/bin/env perl
# Render speech to text using the google cloud speech engine.
#
# Kruft Industries Sept. 2016
#
#
# Intended to replace work by the following(not sure where this is hosted): GNU General Public License Version 2 Copyright (C) 2011 - 2012, Lefteris Zafiris 
# <zaf.000@gmail.com>
#
#
# The script takes as input flac files at 8kHz and returns the following values: status : Return status. 0 means success, non zero values indicating different 
# errors.
#
# Outputs a voice transcription that satisfies the input of sendmailmp3 for freepbx authored by the above Zafiris I am by no means an expert with the perl 
# language, Please forgive any blaring ugliness :)

use utf8;
use MIME::Base64;
use strict;
use warnings; 
use LWP::UserAgent; 

if (!@ARGV || $ARGV[0] eq '-h' || $ARGV[0] eq '--help') {
    print "Speech recognition using google cloud speech api.\n\n";
    print "Usage: $0 [FILES]\n\n";
    exit;
}
my $url = "https://speech.googleapis.com/v1beta1/speech:syncrecognize?key=API KEY HERE"; 

my @file_list = @ARGV; foreach my $file 
(@file_list) {
    print "Opening $file\n";
    open(my $fh, "<", "$file") or die "Cant read file: $!";
    my $audio = do { local $/; <$fh> };
    close($fh);

my $flac = encode_base64url($audio);

my $json = '{"config":{"encoding":"FLAC","sample_rate":8000,"language_code":"en-US"},"audio":{"content":"' . $flac . '"}}';

my $req = HTTP::Request->new( 'POST', $url );
$req->header( 'Content-Type' => 'application/json' );
$req->content( $json );

my $lwp = LWP::UserAgent->new;
my $response = $lwp->request($req);

print $response->as_string; #debug output google's reply headers and message
last if (!$response->is_success);

print $response->content; #debug output the full transcript
    my $doodle = $response->content;
    $doodle =~ s/.*\"transcript\"://g;
$doodle =~ s/}\],.*//g;
$doodle =~ s/^{\"result\":\[\]}/{\"result\":/g;
$doodle =~ s/\R//g;
$doodle =~ s/\*/_/g;
    print $doodle;


}
      sub encode_base64url{
         my($data) = @_;
         return 0 unless $data;
         $data = encode_base64($data);
         $data =~ tr#\-_#+/#;
         return($data);
      }
exit;

【问题讨论】:

  • Google 是否需要 Base64 的 URL 版本?您的encode_base64url 版本与MIME::Base64::encode_base64url 的工作方式不同,已在Google 的回显代码中验证,其中包含'/''+' 和换行符。事实上,您的版本只产生与encode_base64 相同的输出。 URL 版本也应该删除'='

标签: json perl base64 google-speech-api


【解决方案1】:

这是更正后的脚本。这应该对很多人有帮助,我可能会更新标题和描述以防止重复问题!感谢您为我指明正确的方向,Christopher Oicles!

#!/usr/bin/env perl
# Render speech to text using the google cloud speech engine.
#
# Kruft Industries Sept. 2016
#
#
# Intended to replace work by the following(not sure where this is hosted): GNU General Public License Version 2 Copyright (C) 2011 - 2012, Lefteris Zafiris 
# <zaf.000@gmail.com>
#
#
# The script takes as input flac files at 8kHz and returns the following values: status : Return status. 0 means success, non zero values indicating different 
# errors.
#
# Outputs a voice transcription that satisfies the input of sendmailmp3 for freepbx authored by the above Zafiris I am by no means an expert with the perl 
# language, Please forgive any blaring ugliness :)

use utf8;
use MIME::Base64;
use strict;
use warnings; 
use LWP::UserAgent; 

if (!@ARGV || $ARGV[0] eq '-h' || $ARGV[0] eq '--help') {
print "Speech recognition using google cloud speech api.\n\n";
print "Usage: $0 [FILES]\n\n";
exit;
}
my $url = "https://speech.googleapis.com/v1beta1/speech:syncrecognize?key=API KEY GOES HERE"; 

my @file_list = @ARGV; foreach my $file 
(@file_list) {
print "Opening $file\n";
open(my $fh, "<", "$file") or die "Cant read file: $!";
my $audio = do { local $/; <$fh> };
close($fh);

my $flac = encode_base64url($audio);

my $json = '{"config":{"encoding":"FLAC","sample_rate":8000,"language_code":"en-US"},"audio":{"content":"' . $flac . '"}}';

my $req = HTTP::Request->new( 'POST', $url );
$req->header( 'Content-Type' => 'application/json' );
$req->content( $json );

my $lwp = LWP::UserAgent->new;
my $response = $lwp->request($req);

#print $response->as_string; #debug output google's reply headers and message
last if (!$response->is_success);

#print $response->content; #debug output the full transcript
    my $doodle = $response->content;
    $doodle =~ s/.*\"transcript\"://g;
$doodle =~ s/}\],.*//g;
$doodle =~ s/^{\"result\":\[\]}/{\"result\":/g;
$doodle =~ s/\R//g;
$doodle =~ s/\*/_/g;
    print $doodle;


}
      sub encode_base64url{
         my($data) = @_;
         return 0 unless $data;
         $data = encode_base64($data);
         $data =~ s/\+/-/g;
         $data =~ s/\//_/g;
         $data =~ s/\=//g;
         $data =~ s/\n//g;
         return($data);
      }
exit;

【讨论】:

  • 我遇到了同样的问题。我们是否应该删除 +/=\n 以便能够被 Google 解码?我已经把它删除了,但我仍然无法解码。
  • 是的,这就是 $doodle 正在做的事情。如果您仍然遇到问题,则可能是其他问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-26
  • 1970-01-01
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多