Code viewer for World: Audiobook Generator

// Cloned by Aleena Joseph on 21 Nov 2023 from World "New World (clone by Aleena Joseph)" by Aleena Joseph 
// Please leave this clone trail here.

const openaiURL = "https://api.openai.com/v1/audio/speech";           // can POST to this 3rd party URL
  
const themodel = "tts-1";       // the OpenAI text to speech model

// default API key and prompt:

var apikey = "";
var theprompt = "hello";

  $('body').css( "margin", "20px" );
  $('body').css( "padding", "20px" );
  
 
 document.write ( `
 <style>
body {
  background-image: url('/uploads/aj1799/audiobook.jpg');
  background-position: center;
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-size: cover;
}

</style>
 <h1 align="center"> Convert text/story to Audiobooks</h1>

<pre>

</pre>
Set up your API Key to use text to speech service. <br>
Enter text and get different voice modulations. <br>
Choose different voices from the dropdown <br>
<pre>

</pre>
<h3> Enter API key </h3>
The crucial thing is you need an    "API key" to talk to OpenAI. <br>
Register for free and get your API key  
<a href='https://platform.openai.com/account/api-keys'>here</a>.
<br>
You enter your API key below and then give text.
<p>
<div id=enterkey>
Enter API key: 
	<input    style='width:25vw;'    maxlength='2000'   NAME="apikey"    id="apikey"       VALUE='' >  
	<button onclick='setkey();'  class=ab-normbutton >Set API key</button>
</div>
<pre>

</pre>
<button id="showLanguagesButton">Show Supported Languages</button>
<ul id="languagesList" style="display: none;"></ul>
<pre>

</pre>
<h3> Enter a text that you want to convert </h3>
<textarea id="textInput" rows="3" cols="50" placeholder="Enter text here..." VALUE=''></textarea><br>

<h3> Select voice </h3>
<select id="voiceSelection">
  <option value="alloy">Alloy</option>
  <option value="echo">Echo</option>
  <option value="fable">fable</option>
  <option value="onyx">Onyx</option>
  <option value="nova">Nova</option>
  <option value="shimmer">Shimmer</option>
  
</select>
<br>
<h3> Select output format </h3>
<select id="output">
  <option value="mp3">MP3</option>
  <option value="opus">Opus</option>
  <option value="aac">AAC</option>
  <option value="flac">FLAC</option>
</select>
<pre>

</pre>
<button id="Send" class=ab-normbutton>Submit</button>
<br>
<h3> Playback your Audio Data </h3>
<div id=them > </div> 

<audio id="audioPlayer" controls>
  Your browser does not support the audio element.
</audio>
<pre>

</pre>
<button id="downloadButton" style="display: none;">Download Audiobook</button>

</div>

` );

function setkey()          
{
	apikey =  jQuery("input#apikey").val();
	apikey = apikey.trim();
	$("#enterkey").html ( "<b> API key has been set. </b>" );
	console.log('API has been set');
}

// List of supported languages
const supportedLanguages = [
'Afrikaans', 
'Arabic',
'Armenian',
'Azerbaijani',
'Belarusian',
'Bosnian',
'Bulgarian',
'Catalan',
'Chinese',
'Croatian',
'Czech',
'Danish',
'Dutch',
'English',
'Estonian',
'Finnish',
'French',
'Galician',
'German',
'Greek',
'Hebrew',
'Hindi',
'Hungarian',
'Icelandic',
'Indonesian',
'Italian',
'Japanese',
'Kannada',
'Kazakh',
'Korean',
'Latvian',
'Lithuanian',
'Macedonian',
'Malay',
'Marathi',
'Maori',
'Nepali',
'Norwegian',
'Persian',
'Polish', 
'Portuguese',
'Romanian',
'Russian',
'Serbian',
'Slovak',
'Slovenian',
'Spanish',
'Swahili',
'Swedish',
'Tagalog',
'Tamil',
'Thai',
'Turkish',
'Ukrainian',
'Urdu',
'Vietnamese',
'Welsh',
];

const toggleLanguagesList = () => {
  const languagesList = document.getElementById('languagesList');

  // Toggle the visibility of the list
  languagesList.style.display = languagesList.style.display === 'none' ? 'block' : 'none';

  // If the list is visible, populate it with supported languages
  if (languagesList.style.display === 'block') {
    languagesList.innerHTML = ''; // Clear previous content
    supportedLanguages.forEach((language) => {
      const listItem = document.createElement('li');
      listItem.textContent = language;
      languagesList.appendChild(listItem);
    });
  } else {
    languagesList.innerHTML = ''; // Clear the list if hiding
  }
};

document.getElementById('showLanguagesButton').addEventListener('click', toggleLanguagesList);

//document.getElementById('showLanguagesButton').addEventListener('click', showLanguages);

document.getElementById('Send').addEventListener('click', () => {
const selectedVoice = document.getElementById('voiceSelection').value;
const text_to_convert = document.getElementById('textInput').value;
const output_format = document.getElementById('output').value;
const requestData = {
  model: 'tts-1',
  voice: selectedVoice,                      
  input: text_to_convert, 
  response_format: output_format,  //passing output format from user
};

function handleError(error) {
  console.error('Error:', error);
}

function handleSuccess(data) {
  const audioBlob = new Blob([data], { type: 'audio/mp3' });
  const audioUrl = URL.createObjectURL(audioBlob);

  // Get the audio element by ID
  const audioPlayer = document.getElementById('audioPlayer');

  // Set the source of the audio element to the generated audio URL
  audioPlayer.src = audioUrl;
  
  //for downloading audiobook
  const downloadButton = document.getElementById('downloadButton');

  downloadButton.style.display = 'block';   

const downloadAudio = () => {
  const downloadLink = document.createElement('a');
  downloadLink.href = URL.createObjectURL(audioBlob);
  downloadLink.download = 'audio_book.'+output_format;//'generated_audio.mp3';
  downloadLink.style.display = 'none';
  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
};

document.getElementById('downloadButton').addEventListener('click', downloadAudio);
} 

fetch(openaiURL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: "Bearer " + apikey,
  },
  body: JSON.stringify(requestData),
})
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.blob();
  })
  .then(handleSuccess)
  .catch(handleError);

});