title: HTML5 Audio - Why not working on iOS? (NO autoplay involved)
body: <p>I built a simple demo app to test HTML5-Audio. When you touch or click the robot's head the webapp <em>says</em> "eins", which is german for "one" (I had this soundfile on my computer for testing). </p>
  
  <p><strong>You can test the demo app here: <a href="http://jstesproject.cwsurf.de/" rel="nofollow">http://jstesproject.cwsurf.de/</a></strong></p>
  
  <p><em>(Remarks: The robot is the phonegap icon, but there is NO phonegap or cordova technology involved. It is plain HTML5, Javascript (+jQuery) and CSS. Also, you have manually click the robot's head, so there is NO autostart involved.)</em></p>
  
  <p>The webapp works fine on desktop browsers (I tested Chrome and Firefox) and on Android native browser (I tested with Android 4.0). However, I cannot get it to work under iOS (iPhone, neither Chrome nor Safari). The Audio-Object throws an error (code 4).</p>
  
  <p><strong>Why is this? How can I get it to work under iOS?</strong> There is no autostart involved. Please see my code below:</p>
  
  <p><strong>Code</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>$(document).ready(function() {
    clearLog();
  
    log('Document ready!');
  
    $('.clickable').click(function() {
      var value = $(this).html();
  
      playAudio('res/audio/', '1.wav');
    });
  });
  
  //==============
  // AUDIO
  function playAudio(path, src) {
    log('playAudio called! Arguments: ' + path + ', ' + src);
  
    $('#path').html('path -&gt; ' + path);
    $('#file').html('file -&gt; ' + path + src);
  
    if (typeof Audio != "undefined") {
      log('Playing Audio using HTML5...');
  
      var audioUrl = path + src;
      log('audioUrl: ' + audioUrl);
  
      var audio = new Audio();
      audio.src = audioUrl;
      audio.type = 'audio/x-wav';
  
      audio.addEventListener('error', function() {
        log('Audio error: ' + audioUrl + '; ' + JSON.stringify(audio.error));
        $('#audioStatus').html('Audio error: ' + audioUrl + '; ' + JSON.stringify(audio.error));
      });
  
      audio.addEventListener('play', function() {
        log('Starting audio: ' + audioUrl + '; MIME-type: ' + audio.type);
        $('#audioStatus').html('Playing audio: ' + audioUrl);
      });
  
      audio.addEventListener('ended', function() {
        log('Playback ended: ' + audioUrl);
        $('#audioStatus').html('Stopped...');
      });
  
      audio.addEventListener('canplay', function() {
        audio.play();
      });
    } else {
      log('Cannot play audio via HTML5 -&gt; !(typeof Audio != "undefined")');
    }
  }
  
  //==============
  // UTILS
  function log(s, showAlert) {
    var now = new Date();
    var text = makeTwoDigits(now.getHours()) + ':' + makeTwoDigits(now.getMinutes()) + ':' + makeTwoDigits(now.getSeconds()) + ' &gt;&gt; ' + s;
  
    $('#console').append('&lt;p&gt;' + text + '&lt;/p&gt;');
    console.log(text);
  
    if (showAlert) {
      alert(text);
    }
  }
  
  function clearLog() {
    $('#console').html('&lt;p&gt;&lt;strong&gt;Console&lt;/strong&gt; &lt;span&gt;[clear]&lt;/span&gt;&lt;/p&gt;');
  
    $('#console span').click(function() {
      clearLog();
    });
  }
  
  function makeTwoDigits(x) {
    if (x &lt; 10) {
      return '0' + x;
    } else {
      return '' + x;
    }
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code> {
     margin: 0;
     padding: 0;
     box-sizing: border-box;
   }
   body {
     overflow-y: scroll;
     background-color: #EEE;
   }
   .clickable {
     cursor: pointer;
   }
   .icon {
     text-align: center;
   }
   .app {
     width: 256px;
     height: auto;
     margin: 50px auto;
     padding: 20px;
     background: linear-gradient(#9dd2ea, #8bceec);
     border-radius: 10px;
   }
   .numbers,
   .display {
     overflow: hidden;
   }
   .app .numbers span {
     float: left;
     width: 50px;
     height: 50px;
     background: white;
     border-radius: 10px;
     padding: 10px;
     margin: 10px;
     line-height: 32px;
     text-align: center;
     cursor: pointer;
   }
   .app .display span {
     float: left;
     width: 190px;
     height: 50px;
     background: grey;
     color: white;
     border-radius: 10px;
     padding: 10px;
     margin: 10px;
     line-height: 32px;
     text-align: center;
     cursor: pointer;
   }
   .app .debug {
     text-align: center;
     margin-top: 10px;
   }
   #console {
     width: 80%;
     margin: 20px auto;
     padding: 20px;
     background: linear-gradient(#9dd2ea, #00d3ec);
     border-radius: 10px;
   }
   #console p {
     margin: 10px 0px;
   }
   #console span {
     float: right;
     cursor: pointer;
   }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
  
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="stylesheet" type="text/css" href="css/index.css" /&gt;
    &lt;title&gt;I can say one!&lt;/title&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
    &lt;div class="app"&gt;
      &lt;div class="clickable icon"&gt;CLICK MY ROBOT-HEAD!&lt;/div&gt;
      &lt;div class="clickable icon"&gt;
        &lt;img src="icon.png" /&gt;
      &lt;/div&gt;
  
      &lt;div class="debug"&gt;Info:&lt;/div&gt;
      &lt;div id="path" class="debug"&gt;N/A&lt;/div&gt;
      &lt;div id="file" class="debug"&gt;N/A&lt;/div&gt;
      &lt;div id="audioStatus" class="debug"&gt;N/A&lt;/div&gt;
    &lt;/div&gt;
  
    &lt;div id="console"&gt;
      &lt;p&gt;&lt;strong&gt;Console&lt;/strong&gt;  &lt;span&gt;[clear]&lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  
    &lt;script src="js/jquery-2.1.1.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="js/prefixfree-1.0.7.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="js/index.js" type="text/javascript"&gt;&lt;/script&gt;
  &lt;/body&gt;
  
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>