I have developed game is html5,Jquery, Javascript where I need to preload several audios. These audios are playing one by one but, when I minimize iPad then audio is still paying.
Can any body help to pause an audio while browser is going to minimize. And audio should play when browser comes to foreground.
I'm about halfway there to getting you a full solution. Here's what I have so far:
var audio = document.getElementsByTagName('audio')[0];
window.onpageshow = function() {
audio.play();
}
window.onpagehide = function() {
audio.pause();
}
So, as long as your on the app tab when you close Safari, it will pause the audio. And play it when you start back up. It doesn't stop when you change tabs.
If your app is apple-mobile-web-app-capable, this will trigger onpageshow when you open the app using the homescreen button, and will pause it when you close it. It doesn't pause exactly, since opening it back up forces it to start from the beginning. You'd have to capture where you were in the track using localStorage or something and then set the currentTime to that when you open it back up.
Looks like you'll be able to use the Visibility API in iOS 7 according to caniuse.com
Just for history's sake, I'm going to at least state some other things I tried.
window.onblur
using requestAnimationFrame with a setTimeout (this worked on desktops, but not iOS)
var t;
requestAnimationFrame(function checkWindow() {
if ( audio.paused ) {
audio.play();
}
clearTimeout(t);
t = setTimeout(function() {
audio.pause();
}, 32);
});
I recommend you use the page visibility API, which gives you an event that tells you when a page's visibility changes.
function handleVisibilityChange() {
if (document.hidden){
stopAllSounds();
}else{
playAllSounds();
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
stopAllSounds and playAllSounds will be defined as you see fit, but this event will fire when Safari is minimized and maximized. It works on Android devices and all modern platforms
Hopefully I am not late to answer it. I found the following solution which works in desktop and ios devices (haven't checked in android yet)
$(window).on("blur focus", function(e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case "blur":
// do work
your_audio.pause();
break;
case "focus":
// do work
your_audio.play();
break;
}
}
$(this).data("prevType", e.type);
})
PS: your_audio is a variable, you have to define it.
I found this solution here
Related
I'm having an issue on Mobile Safari where my HTML5 video won't return to the start once it has finished, so that when it is played again it tries to play the last second before closing once again.
I've attached a handler to the "ended" event so that it closes to the full screen once the video has finished:
$(videoID).bind("ended", function() {
$(videoID).get(0).webkitExitFullScreen();
});
Any ideas?
I should add that I've tried resetting the currentTime to 0, but this doesn't seem to work.
Ended up that I had stupidly put currentTime=0 after exiting full screen when it needed to be before. i.e.
$(videoID).bind("ended", function() {
$(videoID).get(0).currentTime = 0;
$(videoID).get(0).webkitExitFullScreen();
});
I'm using Mediaelement.js to play some video and using javascript to get autoplay working. It works perfectly in Chrome, and IE10, but when it comes to Firefox and IE8 I have a problem with the flash fallback. The following works in Chrome:
jQuery('video,audio').mediaelementplayer();
if(autoPlay == "true") {
player = new MediaElementPlayer("#"+currentPage+" video,audio");
player.play();
}
IE8 returns the following:
And firefox returns no errors, but if I add an alert(alert("hallo");) in front of player.play(), it plays when I dismiss the alert-box.
I can't add fiddle, because of heavy use of XML.
The player isn't loaded up and ready to play when the script presses the play button.
The script needs to press the play button inside the success function in the mediaelement instance creation.
See here: How do I get mediaelement.js player state (paused, volume, etc.)?
Some browsers (webkit specifically) may trigger the play() method before the video is completely ready and the video may just hang while loading.
I would advice to add an event listener to detect when the video can actually play before triggering the play() method like :
success : function (media, domObject) {
media.addEventListener('canplay', function () {
media.play();
}, false);
} // success
Yeah sorry, solved it a half year later:
As mentioned, the play event must be invoked in the success function
jQuery("video,audio").mediaelementplayer();
if(autoPlay == "1") {
media = jQuery("#"+currentPage+" video,audio")[0];
new MediaElement(media, {success: function(media) {
media.play();
}});
}
Today I get started in appmobi. I was developing a small example to deal with sounds.
I just needed to create a handler to play and stop many sounds.
var audioOn = new Audio('sounds/11.mp3');
audioOn.play();
This code is working in the xdk simulator, also on android devices, but not in my Iphone 5.
The thing is, if I use tag it works on iphone, but I want to use javascript native api to deal with sounds and more.
I have been trying to deal with it with appmobi player library but it comes without controls to stop, resume etc, thats way I want to use native.
Here is part of javascript code :
<script type="text/javascript">
/* This function runs once the page is loaded, but appMobi is not yet active */
var init = function(){
var alarmButton = document.getElementById("alarmButton");
var on = false;
//var audioOn = new Audio('http://rpg.hamsterrepublic.com/wiki-images/3/3e/Heal8-Bit.ogg');
var audioOn = new Audio('sounds/11.mp3');
audioOn.addEventListener('ended', function() {
this.play();
}, false);
var but = function(){
alert("but");
alert(on);
alert(audioOn);
if(!on){
on = true;
audioOn.currentTime = 0;
audioOn.play();
}
else{
on = false;
audioOn.pause();
}
}
//alarmButton.addEventListener("click",but,false);
alarmButton.addEventListener("touchstart",but,false);
alarmButton.addEventListener("tap",but,false);
};
window.addEventListener("load",init,false);
/* This code prevents users from dragging the page */
var preventDefaultScroll = function(event) {
event.preventDefault();
window.scroll(0,0);
return false;
};
document.addEventListener('touchmove', preventDefaultScroll, false);
/* This code is used to run as soon as appMobi activates */
var onDeviceReady=function(){
//Size the display to 768px by 1024px
AppMobi.display.useViewport(768,1024);
//hide splash screen
AppMobi.device.hideSplashScreen();
};
document.addEventListener("appMobi.device.ready",onDeviceReady,false);
function echo(){
alert("clicked");
}
</script>
Thanks a lot
It seems like its not appmobi issue.
I think appmobi lab app for iphone uses safari mobile to run the html5 tests.
So its a safari mobile affair.
It seems play() work when launched by an onclick event. See http://groups.google.com/group/iphonewebdev/browse_thread/thread/91e31ba7ae25e6d4?hl=en
Need to perform some tests...
I have to try this:
http://www.schillmania.com/projects/soundmanager2/
Supporting HTML5 audio can be tedious in modern browsers, let alone
legacy ones. With real-world visitors using browsers ranging from
mobile Safari to IE 6 across a wide range of devices, there can be
many support cases to consider.
SoundManager 2 gives you a single, powerful API that supports both new
and old, using HTML5 audio where supported and optional Flash-based
fallback where needed. Ideally when using SoundManager 2, audio "just
works."
I'm trying to add music to a virtual tour application I'm writing in JS and jQuery and so far my code, shown below, works great in Chrome, FF, IE9, and Opera. But in Safari 5.1.7, which is the newest you can get for a Windows machine, it just doesn't work... Through my research of the problem, I know that Safari doesn't autoplay music and it has to be started manually, but when I click the play button, nothing happens. And, btw, the code inspector in Safari shows that my audio tag is there with the music sources so I don't think it has anything to do with the DOM. Any ideas on my problem?
HTML:
<div id="musicBtns">
<p>Music:</p>
<p id="musicPlayBtn">Play</p>
<p>/</p>
<p id="musicPauseBtn">Pause</p>
</div>
My music object in JS:
var Music =
{
musicBtns: $('#musicBtns'),
playBtn: $('#musicPlayBtn'),
pauseBtn: $('#musicPauseBtn'),
isPlaying: false,
init: function()
{
if(!music.includeMusic) // If the client didn't want any music in the tour app, remove the music btns from the DOM
{
this.musicBtns.remove();
}
else // Else, setup the audio element
{
var parent = this;
var audio = $('<audio loop="true">');
if(music.autoplay)
{
audio.attr('autoplay', 'autoplay');
this.isPlaying = true;
this.togglePlayPause();
}
// Add a source elements and appends them to the audio element
this.addSource(audio, music.ogg); // 'music.ogg' is a reference to the path in a JSON file
this.addSource(audio, music.mp3);
this.musicBtns.append(audio);
// Add event listeners for the play/pause btns
this.playBtn.click(function()
{
audio.trigger('play');
parent.isPlaying = true;
parent.togglePlayPause();
});
this.pauseBtn.click(function()
{
audio.trigger('pause');
parent.isPlaying = false;
parent.togglePlayPause();
});
}
},
addSource: function(el, path)
{
el.append($('<source>').attr('src', path));
},
// Add or remove classes depending on the state of play/pause
togglePlayPause: function()
{
if(this.isPlaying)
{
this.playBtn.addClass('underline');
this.pauseBtn.removeClass('underline');
}
else
{
this.playBtn.removeClass('underline');
this.pauseBtn.addClass('underline');
}
}
}
Edit: Could this be a bug in Safari?
So the problem turned out to be with QuickTime. I guess I must of deleted it off of my machine awhile back because I didn't think I needed it. After I re-installed QuickTime, Safari plays music using the audio tag with no problem. Autoplay even works too.
Kinda funny how the champion of native HTML5 audio/video support, doesn't support HTML5 audio/video without a plugin...
In HTML5 video on Safari I had an issue with this where I had to "load" (which, I think, either starts the buffer or loads the whole thing) before I set it to play. This seemed to actually make things work in a few webkit browsers. So something like:
var a = new Audio("file.mp3");
a.load();
a.play();
Worth a try
I need to play a sound when a new message appears on a website. It works fine on Chrome and Safari but I can't make it work on Safari mobile.
I saw that the sound has to be initialised with a user action so I tried that:
var sound = new Audio('./path/to/my/sound.mp3');
var hasPlayed = false;
$('body').bind('click touchstart', function() {
sound.load();
});
sound.addEventListener('play', function() {
hasPlayed = true;
});
var playSound = function() {
if(hasPlayed) {
sound.currentTime = 0;
}
sound.play();
}
Unfortunately, the sound still don't play. I also tried with the Buzz library, and the issue is the same.
So, the question is : how can I play a sound programmatically on mobile browsers ?
First of all: HTML5 audio support in Mobile Safari on iOS (5.01, 5.1) is rather limited. But I have managed to get some small 'event type' sounds working in my iPad 2 web apps. Since you are talking about only one sound file for your app, you don't have to fall back on audio sprites tricks (i.e. merging multiple MP3's into one MP3 file and changing the play position within the merged file depending on the sound you want to be played).
As you have noticed, you cannot play audio automatically in Mobile Safari, i.e. without the user clicking on some element. Technically speaking, the audio must be played (not loaded) in the same call stack as a click event. But you will probably experience a 0,5 second delay then, when Mobile Safari creates the audio object. Here is a solution to this 'problem':
At the start of your app (while loading/initializing), add a click handler to the HTML document that starts playing your audio file as soon as the user clicks/taps anywhere in the app. This will force Safari to start loading the audio.
Listen for the 'play' event that is triggered when the audio is ready to be played, and immediately pause.
Now start playing the audio (without delay) again when you need it.
Here is some quick JavaScript code:
function initAudio() {
var audio = new Audio('./path/to/my/sound.mp3');
audio.addEventListener('play', function () {
// When the audio is ready to play, immediately pause.
audio.pause();
audio.removeEventListener('play', arguments.callee, false);
}, false);
document.addEventListener('click', function () {
// Start playing audio when the user clicks anywhere on the page,
// to force Mobile Safari to load the audio.
document.removeEventListener('click', arguments.callee, false);
audio.play();
}, false);
}
For those that are coming across this problem and the solution by Jeroen is not working here is a solution that works and ensures the proper scoping is correctly enforced.
Make sure initAudio is called on page load. I.e. in your Init function or for jquery inside the document.ready ($(function(){});)
function initAudio(){
var audio = new Audio('./path/to/my/sound.mp3');
var self = this;
//not sure if you need this, but it's better to be safe
self.audio = audio;
var startAudio = function(){
self.audio.play();
document.removeEventListener("touchstart", self.startAudio, false);
}
self.startAudio = startAudio;
var pauseAudio = function(){
self.audio.pause();
self.audio.removeEventListener("play", self.pauseAudio, false);
}
self.pauseAudio = pauseAudio;
document.addEventListener("touchstart", self.startAudio, false);
self.audio.addEventListener("play", self.pauseAudio, false);
}