Somehow pause or sleep javascript on iOS Safari - javascript

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?

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.

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)

Related

Applying effects to MediaStream in audio tag streaming Shoutcast

I've got a project I've been working on that broke due to an update in Chrome and I've tried everything I can think of to fix it, but I think my underlying implementation is the problem.
In my project, I'm setting the src of an HTML5 audio tag to a Shoutcast link. I then capture the media stream, call createMediaStreamSource with it, then apply filter that I want to the audio (low pass filter, etc.). In Firefox, I can then call play directly on the new stream source and it plays with the given effects. In Chrome, however, since the audio element is not playing, calling play on the stream source does nothing. But if I play the audio element, Chrome plays both the audio element and the stream source. In older versions of chrome, I could just mute the audio element and the stream would continue playing, but in newer versions, this doesn't work.
Is there some better way to be doing this? I just want to play the stream source with new effects. Maybe some way of modifying the stream source with the effects, then setting that back to the audio tag? A different way of playing the streaming audio?
For additional context, I'm using a library called Pizzicato to do this. Code looks roughly like this:
audioElement.oncanplaythrough = () => {
audioElement.oncanplaythrough = null;
let capturedStream;
if (options.audioElement.mozCaptureStream) {
capturedStream = context.createMediaStreamSource(options.audioElement.mozCaptureStream());
} else {
capturedStream = context.createMediaStreamSource(options.audioElement.captureStream());
}
applyEffects(capturedStream , soundEffects); // connects effect AudioNodes together
audioStream.play();
};

HTML5 Audio tag refuses to stop playing, even after being removed?

So I have this audio tag:
<audio src=".....mp3" autoplay id="aud"></audio>
And 20 seconds later I fire this code:
var obj=$('#aud')
obj[0].volume=0;
obj[0].pause();
obj.prop('volume',0);
obj.trigger('pause');
obj.attr('src','');
obj.remove();
console.log('REMOVED!!');
But after all of this, the audio is still playing??
The audio tag has been successfully removed by obj.remove(), but the audio goes on.
The console.log() logs correctly. I get no errors. But despite using several methods to mute, pause and remove the audio tag, the audio goes on.
Can anyone explain why?
I need to purge this audio with salt and flame. Any help will be most appreciated, this is slowly sending me insane...
So I fiddled with this when writing this as an answer and I conclude the following:
Manually creating the audio tag with autoplay property causes it to play even before being added to the DOM tree 2 times(on older jquery implementations). Even after adding that element to the DOM tree, it will be usually impossible to stop both audio streams - prolly one of the streams gets disconnected from the element when second stream is played. Did not dig into that too deeply. I reproduced the issue here:
http://jsfiddle.net/2gaBs/3/
When you click Create w/o autoplay button you can pause it properly, but when you click Create autoplay it will start immedietally (even before adding to the DOM tree) 2 times! You probably didn't notice the 2nd playback(neither did I) because when mp3 is on the same machine 2 audio streams are almost perfectly in sync. Pressing Try stop will stop one of the audio streams (you need to wait 5 seconds, note the setTimeout).
Also note that if you switch to jQuery ver to 1.8.3 or above this issue no longer occurs, so it seems that both of us were working on old jQuery libs that day^^
So 2 solutions are: update jquery version to 1.8.3 or above, or create the element without autoplay property and start it later.

javascript Audio object vs. HTML5 Audio tag

In a project recently when I loaded a sound with
var myAudio = new Audio("myAudio.mp3");
myAudio.play();
It played fine unless a dialogue was opened (ie alert, confirm). However when I instead tried adding an audio tag in my html
<audio id="audio1">
<source src="alarm.mp3" type="audio/mpeg" />
</audio>
and using
var myAudio1 = document.getElementById("audio1");
myAudio1.play()
it continued to play after a dialogue was opened. Does anyone know why this is? Also more generally what are the differences between the two ways to play sounds?
According to this wiki entry at Mozilla <audio> and new Audio() should be the same but it doesn't look like that is the case in practice. Whenever I need to create an audio object in JavaScript I actually just create an <audio> element like this:
var audio = document.createElement('audio');
That actually creates an audio element that you can use exactly like an <audio> element that was declared in the page's HTML.
To recreate your example with this technique you'd do this:
var audio = document.createElement('audio');
audio.src = 'alarm.mp3'
audio.play();
JavaScript halts during an Alert or Confirm box.
You cannot concurrently run code and display an alert(), confirm(), or prompt(), it literally waits for user input on this, this is a core feature of JavaScript.
I am assuming it is that very reason why an audio file played entirely within JavaScript scope does this. Comparatively Flash video clips or HTML5 audio/video will continue to play on even when a JavaScript alert/confirm/prompt is open.
As for what method is better, well that is up to you. It is pretty archaic to do anything with the JavaScript built in alert/confirm/prompt anymore, there are way better looking prompts you can make with jQuery UI and so on.
If you have a lot of dynamic content on the page or are you looking into background buffering audio before they need to be triggered and so on, then JavaScript is probably the saner way to go about things.
If you have literally just one player on the screen then there is no excuse for not putting in onto the HTML code. Although unlikely to affect anyone these days, it is still bad practice to rely heavily on JavaScript when there is no reason to.
I came up with the function below from several answers across the web.
function playAudio(url){
var audio = document.createElement('audio');
audio.src = url;
audio.style.display = "none"; //added to fix ios issue
audio.autoplay = false; //avoid the user has not interacted with your page issue
audio.onended = function(){
audio.remove(); //remove after playing to clean the Dom
};
document.body.appendChild(audio);
}
If you will create - then you will have problems on ios, because it showing even you will set width:0px
var myAudio = new Audio("myAudio.mp3"); is faster because it does not interact with the DOM.
If you are using multiple audios and/or won't need the user to interact with the player controls you should definetly chose new Audio() where the DOM is not involved.
First let me answer the difference that lies between them.
audio tag in html and the new audio object in js, if have a difference is a subtle one and insignificant. They actually do the same thing.
If you just want to include an audio inside your webpage, then using the html tag is seem fit and recommended. And
If you would like the audio to play whilst there has been an interaction from the user, then the javascript Audio object is seem fit and recommended. For instance;
document.querySelector("button).onclick=()=>{let audio=new Audio(audio url); audio.play;
Besides that's the primary purpose of javascript.
Now the reason why the audio still plays when the dialogue opens when you use the html audio tag is because of the fact that the browser first loads your html file, execute the content of the file until it encounters the script tag in the html file and loads the javascript file too. All I'm trying to say is, the audio tag was already read by the browser even before the script loaded.
Javascript pauses when an alert(), prompt() or confirm is encountered. Thus "playing fine after an alert was opened". (•‿•).

jQuery .load() function doesn't work on iPad

I have a problem with the .load(); function on my ipad.
$(this).bind('ended',function() {
$('video').load();
});
It's a simply function for loading the same content after the Video ends.
Any idea why this function does not work on an iPad?
The .load() method loads the video into the tag. The .play() method starts the currently loaded video. One more thing to keep in mind is this, is the video the right format? The tag can load quite a few formats but not every browser can handle every format. iOS browser like iPad/iPhone and even Safari on OSX/Windows can play m3u8 playlists encoded with h264/AAC and mp4 encoded with h264/AAC files but will not play webm, vp8 or avi. So you need to keep all of this in mind when building this type of tag. You might want to look into just building the the player with straight Javascript and supplying multiple tags and then let the browser determine the video it can play. (I did this at a past job and it is a lot easier than you might think) And I believe that with certain browsers you need to reset the 'play pointer' and tell it to start at position 0
jsfiddle [dot] net/nexxuz/XuLCC/15/
(will not let be post link without code)
And I was able to get this working playing multiple videos too (once one ended played another) (Ad video plus content video) also I was able to get a mid roll video working too. (at x seconds into video play another video and then once that video is done resume the first video)

HTML5 Audio Plays Randomly

I am implementing sound effects in HTML5 audio but after a while, it just stops playing any audio. The file type is correct because it starts fine but then seems to give up.
var sound = new Audio(url);
function play() {
sound.play();
}
Is there a better way to do this so it consistently plays sound?
Here is a link to my implementation. Easy to reproduce by pressing spacebar a lot until it eventually gives up (also shoot the lights for added sounds). http://craftyjs.com/elevatoraction/
This occurs for me in the latest version of Chrome (8.0)
Edit: I did as Gaurav suggested and only played the same instance of each sound file, but the same sort of problems are present. It will arbitrarily stop playing.
Edit 2: I just noticed that whenever I try to play the sound, the networkState is always 1 which according to this means it hasn't fully loaded. That is odd seeing as it still plays sometimes and even when it plays the networkState is always 1
Don't create a new audio object each time you want to play a sound, reuse the same resource.
var sound1 = new Audio(url);
function playSound1() {
sound1.play();
}
I think this is related to the bug http://code.google.com/p/chromium/issues/detail?id=57070

Categories

Resources