title: POST base64 encoded file to google speech api using perl
body: <p>I am having difficulty encoding a FLAC audio file to base64 when posting a json string to the google speech api. I noticed a few \n's in the reply from google, not sure if the base64 isn't good enough going in or perhaps I don't fully grasp how to build such strings and make them json-y enough to satisfy google. I'm leaning towards utf-8 encoding but my last attempt at further processing the information to be sent left me with mountains of other error messages from perl. Any pointers at all would be a great help! (even if the pointer is to give up on doing this on my own and pay the support fee to google)</p>
  
  <pre><code>Error message:
      {
        "error": {
          "code": 400,
          "message": "Invalid value at 'audio.content' (TYPE_BYTES), Base64 decoding failed for "ZkxhQwAAACIQABAAAAlJABQpAfQA8AABS+DDBqlWu7Ba27gz/koR4+04AwAAJAAAAAAAAAAAAAAA\nAAAAAAAQAAAAAAAAATAAAAAAAAABQ5kQAAQAACggAAAAcmVmZXJlbmNlIGxpYkZMQUMgMS4zLjAg\nMjAxMzA1MjYAAAAAgQA...
  </code></pre>
  
  <p>My code is:</p>
  
  <pre><code>#!/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 
  # &lt;zaf.000@gmail.com&gt;
  #
  #
  # 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, "&lt;", "$file") or die "Cant read file: $!";
      my $audio = do { local $/; &lt;$fh&gt; };
      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-&gt;new( 'POST', $url );
  $req-&gt;header( 'Content-Type' =&gt; 'application/json' );
  $req-&gt;content( $json );
  
  my $lwp = LWP::UserAgent-&gt;new;
  my $response = $lwp-&gt;request($req);
  
  print $response-&gt;as_string; #debug output google's reply headers and message
  last if (!$response-&gt;is_success);
  
  print $response-&gt;content; #debug output the full transcript
      my $doodle = $response-&gt;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;
  </code></pre>