Apps Script: text-to-speech create an empty/corrupted (0 seconds) mp3 file

240 views
Skip to first unread message

Mario Littges

unread,
Jun 16, 2023, 4:28:52 AM6/16/23
to Google Apps Script Community
Hi,

the following script is to create an audio file in which text from a googlesheet is to be converted into speech. I use the Text-to-Speech API for this and it seems to work, at least I don't get any error messages and in the end an audio file is created and stored in my Google Drive. The problem I have now is that the audio file cannot be played and always shows 0 seconds as the duration. The file size varies depending on the length of the text, so I assume that the text is converted correctly using the Text-tp-Speech API, but the mp3 file created seems to be corrupted. Does anyone have an idea what this could be? Here is my code:

function convertToSpeech() { // MP3 file
const ss = SpreadsheetApp.getActiveSpreadsheet();
const settings = ss.getSheetByName('Settings');
const sheet = ss.getSheetByName('AI');
const apiKey = settings.getRange(7,2).getValue();

var text = sheet.getRange(2,2).getValue();
var fileName = 'audio.mp3';

var params = {
input: {
text: text
},
voice: {
languageCode: 'en-US'
, name: 'en-US-Studio-M'
},
audioConfig: {
audioEncoding: 'MP3_64_KBPS'
, effectsProfileId: ['small-bluetooth-speaker-class-device']
, pitch: 0
, speakingRate: 1
}
};

var response = UrlFetchApp.fetch('https://texttospeech.googleapis.com/v1beta1/text:synthesize?key='+apiKey, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(params)
});

var json = response.getContentText();
var data = JSON.parse(json);
var audioContent = data.audioContent;

// Convert base64-encoded audio content to binary data
var audioBytes = Utilities.base64Decode(audioContent);

// Save the MP3 file to Google Drive
var file = DriveApp.createFile(fileName, audioBytes, 'audio/mpeg');

Logger.log('Created audio file: ' + file.getName());

}

I would like to thank you in advance for any help.

Best regards,
Mario

Mario Littges

unread,
Jun 16, 2023, 4:45:52 AM6/16/23
to Google Apps Script Community

This is the generated audio file: 
  1. audio.mp3
Best regards,
Mario

Mario Littges

unread,
Jun 16, 2023, 6:27:38 AM6/16/23
to Google Apps Script Community
It's interesting, I've had this problem for a few days and haven't managed to solve it, but as soon as I write it down and ask for help, the solution suddenly comes by itself :-)

Instead of directly passing the binary audio data, I need to convert it to a Blob object before creating the file.

// Save the MP3 file to Google Drive
var blob = Utilities.newBlob(audioBytes, 'audio/mpeg');
var file = DriveApp.createFile(blob.setName(fileName));

Logger.log('Created audio file: ' + file.getName());

Thanks to myself :-)

Best regards
Mario

Jose armando Jara Osores

unread,
Jun 16, 2023, 6:46:42 AM6/16/23
to google-apps-sc...@googlegroups.com
You are right, some audio formats may not be playable on all audio players. In the code you have shared, the audio format MP3_64_KBPS is being used, which can be played on most devices and audio players. However, if you need to output a different audio format that is compatible with your players, you can change the audioEncoding value in the variable parameters. For example, you can try WAV_PCM or LINEAR16, which are more common audio formats and are supported by most audio players. It is important to note that the size of the generated file may vary depending on the chosen audio format.
‐--------‐-‐--‐‐-------------------------------------------
Here is a modified version of the script that will allow you to generate audio files in MP3_64_KBPS format and also in LINEAR16 format, which is a lossless audio format.
This version of the script creates two audio files in different formats: one in MP3_64_KBPS with the name audio_MP3.mp3 and one in LINEAR16 with the name audio_LINEAR16.wav. Now you will have at your disposal two options to select the audio format that best suits your needs.:
 
```
function convertToSpeech() { // MP3 & LINEAR16 file

  const ss = SpreadsheetApp.getActiveSpreadsheet();

  const settings = ss.getSheetByName('Settings');

  const sheet = ss.getSheetByName('AI');

  const apiKey = settings.getRange(7,2).getValue();


  var text = sheet.getRange(2,2).getValue(); 

  var fileName_MP3 = 'audio_MP3.mp3';
  var fileName_LINEAR16 = 'audio_LINEAR16.wav';


  var params_MP3 = {

    input: {

      text: text

    },

    voice: {

      languageCode: 'en-US'

      , name: 'en-US-Studio-M'

    },

    audioConfig: {

      audioEncoding: 'MP3_64_KBPS'

      , effectsProfileId: ['small-bluetooth-speaker-class-device']

      , pitch: 0

      , speakingRate: 1 

    }

  };
  
  var params_LINEAR16 = {

    input: {

      text: text

    },

    voice: {

      languageCode: 'en-US'

      , name: 'en-US-Studio-M'

    },

    audioConfig: {

      audioEncoding: 'LINEAR16'

      , sampleRateHertz: 16000

    }

  };


  // Generate MP3 file


    method: 'post',

    contentType: 'application/json',

    payload: JSON.stringify(params_MP3)

  });


  var json_MP3 = response_MP3.getContentText();

  var data_MP3 = JSON.parse(json_MP3);

  var audioContent_MP3 = data_MP3.audioContent;


  // Convert base64-encoded MP3 audio content to binary data

  var audioBytes_MP3 = Utilities.base64Decode(audioContent_MP3);


  // Save the MP3 file to Google Drive

  var file_MP3 = DriveApp.createFile(fileName_MP3, audioBytes_MP3, 'audio/mpeg');


  Logger.log('Created MP3 audio file: ' + file_MP3.getName());


  // Generate LINEAR16 file

  var response_LINEAR16 = UrlFetchApp.fetch('https://texttospeech.googleapis.com/v1/text:synthesize?key='+apiKey, {

    method: 'post',

    contentType: 'application/json',

    payload: JSON.stringify(params_LINEAR16)

  });


  var json_LINEAR16 = response_LINEAR16.getContentText();

  var data_LINEAR16 = JSON.parse(json_LINEAR16);

  var audioContent_LINEAR16 = data_LINEAR16.audioContent;


  // Convert base64-encoded LINEAR16 audio content to binary data

  var audioBytes_LINEAR16 = Utilities.base64Decode(audioContent_LINEAR16);


  // Save the LINEAR16 file to Google Drive

  var file_LINEAR16 = DriveApp.createFile(fileName_LINEAR16, audioBytes_LINEAR16, 'audio/wav');


  Logger.log('Created LINEAR16 audio file: ' + file_LINEAR16.getName());


}
```

Esta versión del script crea dos archivos de audio en distintos formatos: uno en MP3_64_KBPS con el nombre audio_MP3.mp3 y otro en LINEAR16 con el nombre audio_LINEAR16.wav. Ahora tendrás a tu disposición dos opciones para seleccionar el formato de audio que mejor se ajuste a tus necesidades.


El vie, 16 de jun de 2023, 04:28, Mario Littges <litt...@gmail.com> escribió:
Hi,
--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-apps-script-community/587ba225-31ff-4251-bd6d-3cbc7b2fec29n%40googlegroups.com.

Jose armando Jara Osores

unread,
Jun 16, 2023, 6:50:40 AM6/16/23
to google-apps-sc...@googlegroups.com
This version of the script creates two audio files in different formats: one in MP3_64_KBPS with the name audio_MP3.mp3 and one in LINEAR16 with the name audio_LINEAR16.wav. Now you will have at your disposal two options to select the audio format that best suits your needs.

Mario Littges

unread,
Jun 16, 2023, 6:52:47 AM6/16/23
to Google Apps Script Community
Thank you very much, that is a good additional idea and also a good hint.

Best regards,
Mario

Reply all
Reply to author
Forward
0 new messages