0

I have a piece of javascript where I'm playing a sound like so...

var audio = document.createElement('audio');
audio.src = 'folder/test.wav';
audio.play();

I need to play more than one file spaced apart so you know what it's saying. iOS doesn't allow you to use setTimeout. I tried that in separate functions and it fails to sound off the second audio clip when using setTimeout. Any other ideas?

EDIT

I have this function:

function playaudio(file) {
    var audio = document.createElement('audio');
    audio.src = 'folder/'+file+'.wav';
    audio.play();
}

Calling it like so:

playaudio("test1");
playaudio("test2");

All I need it to pause inbetween test1 and test1 so they don't play together. Any ideas?

Geek Grid
  • 207
  • 6
  • 17
  • setTimeout works 100% in mobile Safari. – mikekavouras Sep 11 '13 at 21:03
  • Maybe it is working and it's failing to play an additional audio clip? It works fine in a browser, fails in iOS. – Geek Grid Sep 11 '13 at 21:04
  • Post the code that fails, maybe someone will show you how to fix it. – Barmar Sep 11 '13 at 21:14
  • This probably falls into the same category as autoplay. Check out [this answer](http://stackoverflow.com/questions/4259928/how-can-i-autoplay-media-in-ios-4-2-1-mobile-safari). Here's a [fiddle](http://jsfiddle.net/mikekavouras/raUzk/1/) of this working, but it's initialized by a click event. – mikekavouras Sep 11 '13 at 21:17

2 Answers2

1

You can use iOS Native code to trigger Javascript method calls:

[webViewObject stringByEvaluatingJavaScriptFromString:@"playNextSound();"];

Where playNextSound is a JS method defined in the page loaded by the UIWebView. And instead of setTimeout, you can have native timers using NSTimer to space out your audio plays.

Vinod Vishwanath
  • 5,821
  • 2
  • 26
  • 40
0

setTimeout() works on iOS. The issue likely has to do with how the browser handles <audio> and <video> content.

iOS will only play <audio> and <video> content if it is triggered by user input. You mention your initial audio.play() call for the first clip works fine, so I'm guessing it's user-triggered. The problem is that functions inside setTimeout() clear the call stack, so they may no longer be considered user-driven by the browser, even if they are preceded by a click event.

The simplest solution is to combine your multiple audio clips into one. You could also pad the clips you want to delay with silence at the start, and play them all right after the click event (assuming the OS version you're targeting supports multiple audio objects at once)

Community
  • 1
  • 1
Max Hartshorn
  • 709
  • 7
  • 19
  • 1
    I considered that... but I could go from having 30 clips on the server to thousands given all the variations I need to account for. – Geek Grid Sep 12 '13 at 11:41
  • Are you developing an app btw? You can override this restriction in that case: http://stackoverflow.com/questions/15731667/uiwebview-mediaplaybackrequiresuseraction – Max Hartshorn Sep 12 '13 at 22:05