0

i was wondering if i can download all audio files from google word pronunciation

i came up with a solution that actually works

i created an html page with the following code

<a id="mylink" href='//ssl.gstatic.com/dictionary/static/sounds/de/0/word.mp3' download='word.mp3'>download audio "word"</a>

now if you click the above link , the browser will start downloading the audio file and if you change word.mp3 to something else and click it again , it will start downloading the new word;

the problem is I tried to download the whole dictionary in mp3 format.

so i came up with the following javascript

var words=['cat','fish','police','office','ball'];//the whole dictioany.....
for(var z in words )
setTimeout(function(){
var lin=document.querySelector("a");//gets the above link
lin.href="//ssl.gstatic.com/dictionary/static/sounds/de/0/"+a[z]+".mp3";//changes link href to each of the array "words"
lin.download=a[z]+".mp3";//changes the file name to current word
lin.click();//after clicking this link , all downloads start at the same time 
},1000)//even it setup to fire after 1 second
//all the downloads start at same time 

the biggest problem is that only audio file downloaded is the last one "ball"

and it's downloaded multiple times any solution is appreciated and thanks in advance

here is the example on jsfiddle click

Ucef Mir
  • 3
  • 2
  • You could alternatively download all files within a `.zip` file [Multiple download links to one zip file before download javascript](http://stackoverflow.com/questions/37176397/multiple-download-links-to-one-zip-file-before-download-javascript/) – guest271314 Feb 02 '17 at 00:53

2 Answers2

0

You can't use a setTimeout() in a loop, as the loop will execute faster than the timeout. Thus, the final result will be ran for each event in the loop (a[z] will call a[4] five times). To get around this, you'll need to slightly modify your for loop, and not use a timeout:

var a = ['cat', 'fish', 'police', 'office', 'ball'];
for (var z = 0; z < a.length; z++) {
  var l = document.querySelector("a");
  l.href = "//ssl.gstatic.com/dictionary/static/sounds/de/0/" + a[z] + ".mp3";
  l.download = a[z] + ".mp3";
  l.click();
}

I've created an updated fiddle showcasing this here.

Hope this helps!

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
0

The problems with your code are:

  1. The setTimeout is executed within the loop at nearly the same time. So that is why the function is also executed at the same time. Think of having ten egg timers that you all activate at the same time. They will also all ring at the same time.
  2. The function triggered by setTmeout uses the variable z declared outside the function. It does not use the value of z at the time when setTimeout is executed, but at the time the function is executed. All instances of the function access the same variable, so they all use the value of z during the last loop.

Instead of having a loop, use setInterval to execute a function at a given interval and use a counter variable so that a different variable is used at each time the function is executed.

function run()
{
  var words=['cat','fish','police','office','ball'];
  var counter = 0;

  // Setup IntervalFunction to run every 2 seconds
  var interval = setInterval(IntervalFunction, 2000);

  function IntervalFunction()
  {
    // Download word
    downloadWord(words[counter]);

    // Increase counter
    counter++;

    // When counter is beyond array, stop IntervalFunction from running
    if(counter >= words.length)
    {
        clearInterval(interval);
    }
  }
}

function downloadWord(word)
{
    var lin = document.querySelector("a");
    lin.href = "https://ssl.gstatic.com/dictionary/static/sounds/de/0/" + word + ".mp3";
    lin.download = word + ".mp3";
    lin.click();
}
NineBerry
  • 26,306
  • 3
  • 62
  • 93
  • thanx man , i accepted the above answer cuz it was shorter and more clear , yours is also effective and more detailed , I appreciate your effort , thanks again – Ucef Mir Feb 08 '17 at 00:13