iOS (4.3) safari issue with Audio (multiple files) - javascript

I'm having an issue with the AUDIO tag. I have an HTML page (with javascript) where 4 sound files play in succession. In iOS 5, and latest safari, things play wonderfully, but in 4.3(.2) things aren't working.
Below are the MANY solutions I have tried. It should be noted that playing ONE sound file on a page is not a problem. I have Voice Over audio playing on page-load for most of my pages and that works fine.
All of the below methods work perfectly in 5.0 and latest desktop safari, just not in iOS 4.3 simulator/device:
1) Have a hidden div, set innerHTML = an tag with the appropriate src file
1a) onended - clear div innerHTML, load next audio file
1b) setTimeout, delay 2 seconds between each file (which is 1 second long) then load next sound
2) Hidden div, set innerHTML = 4 audio tags
2a) onended - .play() next audio file
2b) setTimeout - .play() next audio file
3) replaced with EMBED
4) replaced with OBJECT
5) Used javascript only:
a = new Audio(src); a.play();
The behavior is best described as "wonky". Sometimes only 1 sound will play, others two will play, rarely 3. Sometimes the first will repeat 4 times (while the debug displays that 4 different sounds should have played)
My ultimate goal is to have a random sequence of 4 sounds played in succession.

It seems like if I do everything with 1 javascript audio control, things work better...
I created a global audio control:
var a=new Audio();
Whenever I wanted to play a sound I did:
a.pause();
a.src='newfile.m4a';
a.play();

Related

Two videos on one page carousel - Chromium

I have 2 vides hosted on a server.
In Chromium browser (Version 65.0.3325.181) https://server/index.html is loaded.
Using Javascript, 2 video elements are inserted after window.onload and the 1st one is started.
Both inserted like:
let video = document.createElement('video');
video.setAttribute('width', '100%');
video.setAttribute('height', '100%');
video.setAttribute('preload', 'auto');
let source = document.createElement('source');
source.setAttribute('src', <http://server/video/path>);
source.setAttribute('type', 'video/mp4');
video.appendChild(source);
After finish video.on('ended') video element becomes hidden. And next video element becomes visible and started.
Everything works fine:
2 video elements created and hidden.
Immediately 1st video element started and playing ..
On 1st video ended - it becomes hidden
Second video becomes visible and started ... successfully reach its end and becomes hidden again...
then start again from 1st video...
I have following observation.
First video is always playing smootly after initially cached.
Second video is always playing with glitches and freezes of few milliseconds.
I am using Chromium on Raspberry Pi 3.
When first video starts: CPU is like 40-50-60%
Everytime the second video starts: CPU is like 120-220% and with glitches and freezes.
The issue is not video or encoding related, because when i switch places: the new 2th video (which was 1st before) becomes the problematic one. Always the second video!
Why this can be?
Can you give me some clue or direction what it might be?
One possible reason is that the first video is using the Raspberry PI's built in Broadcom HW video decoding, but the second one is having to fall back to SW decoding.
The same affect can be seen on many computers if you play multiple videos and exceed what decoding the platform can handle in HW - a typical approach is to fall back on some form of SW decoding, or perhaps to simply give priority to the first video(s) playing.
There are also restrictions to the codec and frame rates supported on most video cards, although this does not sound like the issue you are seeing as the video sounds like it plays fine when it is the only or the first video.

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.

Somehow pause or sleep javascript on iOS Safari

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)

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)

Why can't I play sounds more than once using HTML5 audio tag?

This is how the sound is "stored":
<audio id = "hammer" src="res/sounds/Building/hammer.wav"></audio>
In the actual game (which I use sounds for), I use this to play the sound:
function playSound(soundid)
{
document.getElementById(soundid).currentTime = 0;
document.getElementById(soundid).play();
}
But the sound plays only the first time, and never again!
I tried resetting the "currentTime" in the console to 0, but I literally get this:
>document.getElementById("hammer").currentTime = 0
0
>document.getElementById("hammer").currentTime
0.340...
Why is this happening, how do I fix it?
See this slide and the preceding three slides of Evan Wallace and Justin Ardini's presentation on html5 game dev.
For all the resources to make some awesome games, part of their talk: http://madebyevan.com/gamedevclass/
Audio still doesn't work consistently across all browsers, as of right now:
An element must be reloaded in Chrome or it will only play once
An element must not be reloaded in Firefox or there will be a delay
function playSoundEvent() {
if (window.chrome) elems[index].load()
elems[index].play()
index = (index + 1) % elems.length
}
I had this issue recently with an html5. Worked everywhere except safari.
Using load() before calling play() solved this problem. It also helps to make sure that sound effects do not overlap with heavy clickers when event-handlers trigger sounds.
Here what I used
<audio id="sound-one" preload="auto">
<source src="http://myurl/foo.mp3"></source>
<source src="http://myurl/foo.ogg"></source>
</audio>
click here
Jquery
$("#navigation-id") //this attached is to an element on the page
.mouseover(function() {
sound-one.load();
sound-one.play();
});
A few months before I faced the same issue while developing a Piano in HTML5. When a key was pressed again and again I had to stop, rewind and play the audio on each key press. I used the same code written in this question which worked in Firefox and Safari, but not in Chrome. In Chrome it didn't play again. Finally I had to modify the code to make it work. Added one listener for the event onseeked, then set currentTime = 0 and in the event handler invoked play. This worked for me. Similarly I had to wait for the event of one action before giving next action in many places. It was an old version of Chrome. Later I found out that even some versions of Browsers support Audio, the way each one supports is slightly different. This difference won't be visible if we simply put an audio tag and play the audio, but will experience when we try to control the audio using Javascript. Anyways its all about older versions of Browsers, its much much better in all latest versions. So please check in the latest version of Chrome ( Even my piano worked in Chrome 10 without the code modification ) and regarding the audio format, I would suggest you to keep mp3 and ogg files of your audio instead of single wav file.
For anyone stumbling across this post in the future, the audio tag is really not a great way to do game audio.
I'd highly recommend taking the time to learn the WebAudio API instead.

Categories

Resources