I have an audio element inside my page that starts playing at a button click.
Is there a way to pause the audio when the user presses the iPhone HOME button and Safari goes into background?
Thank you!
Make use of a loop, to check if the user is on the webpage. Store the time.
var lastSeen;
var loop = function (){
lastSeen = Date.now();
setTimeout(loop, 50);
};
loop();
var music = document.getElementById('music');
music.addEventListener('timeupdate', function (){
if(Date.now() - lastSeen > 100){
this.pause();
}
}, false);
source: Stop HTML5 audio from looping when iOS Safari is closed
Related
How to handle next audio button pressed event and previous audio button event on flutter just audio with audio services , my audio files is encrypted , i must decrypt audio file before playing
mediaItem.add(MediaItem(id: "1", title: item.title!,artUri: Uri.file(PathHelper().pathAudio!+"name.mp3")));
_player.setFilePath(PathHelper().pathAudio!+"name.mp3");
I will just answer the main question about handling button events (I can't answer about encryption).
To handle button events, override these methods in your audio handler:
skipToNext
skipToPrevious
click
The first two handle next and previous buttons in various places including the notification, while click handles button presses on a headset. Since some headsets also also have next/previous buttons, and some headset emulate next/previous by long pressing on the volume buttons, etc., click can handle multiple types of events. For this reason, click takes a parameter indicating which of the 3 types of events occurred (next, previous or play/pause).
The default implementation of click is as follows:
Future<void> click([MediaButton button = MediaButton.media]) async {
switch (button) {
case MediaButton.media:
if (playbackState.valueOrNull?.playing == true) {
await pause();
} else {
await play();
}
break;
case MediaButton.next:
await skipToNext();
break;
case MediaButton.previous:
await skipToPrevious();
break;
}
}
(Reference: API documentation)
In short, I have embedded a youtube video in my app using iframe and set it to auto play when the player’s ready after a user has entered that specific page.
-Problem I’m facing: the video player behaves as I expected on Android devices. The user enters the page, the video is played automatically without pressing the ‘play’ button, when he/she wants to go fullscreen, just hit ‘fullscreen’. Sames go for when that user wants to pause the video.
However, on iOS: the user enters the page --> the video plays automatically in full screen mode which definitely not what I want --> the video is paused when the user exits full screen and if he/she hits ‘play’, it goes fullscreen again. Basically, it’s only playable in full screen.
-The question is: is there any way I can achieve the same behaviors of the video player as on Android for iOS? Thank you so much, any help would be really appreciated.
-This is the html:
<iframe id="iframeTube" width="100%" height="250" src="https://www.youtube.com/embed/b5cv7ihxBeY?enablejsapi=1&fs=1" frameborder="0"
style="border: solid 4px #37474F" allowfullscreen></iframe>
-this is the video being processed in .ts file:
ionViewWillEnter() {
this.onYouTubeIframeAPIReady();
}
ionViewDidEnter() {
this.fullscreenProcess(this);
}
onYouTubeIframeAPIReady() {
this.player = new YT.Player('iframeTube', {
events: {
'onReady': this.onPlayerReady,
'onStateChange': this.onPlayerStateChange
}
});
}
onPlayerReady(event) {
console.log('ready')
var embedCode = event.target.getVideoEmbedCode();
event.target.playVideo();
var self = this;
}
fullscreenProcess(self)
{
document.addEventListener("webkitfullscreenchange", function (event) {
if (document.webkitIsFullScreen) {
console.log("full")
self.screenOrientation.lock(self.screenOrientation.ORIENTATIONS.LANDSCAPE);
}
else {
self.screenOrientation.unlock();
console.log("not full")
}
});
}
I'm trying to show a youtube video that is started using javascript. This is how the video-object is instatiated:
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '720',
width: '1280',
html5: 0,
videoId: 'i8IXMGHpGBk',
playerVars: {'modestbranding': 1, 'controls': 1,'showinfo': 0, 'rel': 0 },
events: {
'onStateChange': function(e) {
if (e.data === 0) {
$('html, body').animate({
scrollTop: $(".quizwrapper").offset().top
}, 1000);
document.getElementById('first').focus();
}
}
}
});
}
I'm later playing the video like this:
if(player){
player.playVideo();
console.log(player);
}
This works in all four mayor broswers and chrome for android. But in safari on iphone, it looks as though the video starts to load (the youtube spinning balls) and after that just a black rectangle.
I get no errors in inspector.
Taken from the YouTube iFrame API Reference which takes you to the Apple Safari HTML5 Audio and Video Guide:
Warning: To prevent unsolicited downloads over cellular networks at the user’s expense, embedded media cannot be played automatically
in Safari on iOS—the user always initiates playback. A controller is
automatically supplied on iPhone or iPod touch once playback is
initiated, but for iPad you must either set the controls attribute
or provide a controller using JavaScript.
I am using the HTML5 Soundcloud widget API to skip to another song on the sound finish event.
http://jsbin.com/axuzoj/4/edit
Unfortunately there appears to be a race condition bug in the finish event. The Soundcloud player ends up playing two songs simultaneously: the next song in the list and the song that was skipped to in the finish event handler.
var widget = null;
$(function() {
var iframe = document.querySelector('#soundcloud_player iframe');
widget = SC.Widget(iframe);
widget.bind(SC.Widget.Events.READY, function() {
widget.bind(SC.Widget.Events.FINISH, function() {
widget.skip(3);
});
});
});
Is this a known bug?
Is there a better way to skip to a different track after a sound finishes?
Is there a way to turn off continuous play?
Adding a short wait before skipping in the finish event handler, gets around the problem. But doesn't seem like a good method.
window.setTimeout(function() { widget.skip(3); }, 300);
Another work around is to skip to a song just before the previous song finishes, using PLAY_PROGRESS event instead of on FINISH event.
widget.bind(SC.Widget.Events.READY, function() {
widget.bind(SC.Widget.Events.PLAY_PROGRESS, function(obj) {
if (obj.relativePosition > 0.999) {
widget.pause();
widget.skip(3);
}
});
});
Yes, there was a race-condition bug which is fixed now.
The following code works in my desktop browser but not in Safari on my iPhone, it does display the alert() but doensn't play the audio. What am I doing wrong?
soundManager.url = '/assets/backend/swf/';
soundManager.preferFlash = false;
soundManager.useHTML5Audio = true;
soundManager.onready(function(){
function playSong(){
soundManager.createSound({
id: 'song_<?=$song->ID?>',
url: '/backend/song/play/<?=$song->ID?>',
type: 'audio/mp3'
}).play();
}
$('#play').click(function(){
alert('playSong()');
playSong();
});
});
From what I've seen, iPhone doesn't like "auto-played" sounds, and they require the sound to be played from user interaction.
In your case, the iOS browser must not like the fact that you're creating the sound AND THEN playing it back immediately.
Give this variant a try and see if it works for you:
soundManager.url = '/assets/backend/swf/';
soundManager.preferFlash = false;
soundManager.useHTML5Audio = true;
soundManager.onready(function(){
// Create the sounds here (don't call play)
soundManager.createSound({
id: 'song_<?=$song->ID?>', // It is not cool to put PHP here, read below!
url: '/backend/song/play/<?=$song->ID?>',
type: 'audio/mp3'
});
$('#play').click(function(){
var soundId = 'song_<?= $song->ID ?>';
soundManager.play(soundId);
});
});
As a side note: I'd advise you AGAINST mixing JS and PHP in that way. Check this SoundManager2 example on how to "augment" a regular MP3 link like this:
Click here to play blabla
into something that plays an MP3 onclick:
SoundManager2 documentation
Regards and good luck!