IonicFramework - Stop video auto play in fullscreen mode on iOS - ionic-framework

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")
}
});
}

Related

Web Audio Session API to trigger method calls in app rather than playing media

I'm having a hard time getting the Web Audio API to do what I want. My goal is to eventually trigger voice recognition in a PWA on mobile, but first I decided to do a test case of incrementing a counter whenever play or pause was pressed. I am using the Vue framework.
Here is an abbreviated version of my code along with the GUI is creates on the screen.
<template>
<v-app>
<v-btn #click="activateMediaButton">Start</v-btn>
<div>{{counter}}</div>
<v-btn #click="increment">Increment</v-btn>
</v-app>
</template>
<script>
export default {
name: 'App',
data(){
return {
counter: 0
};
},
methods: {
increment(){
console.log('ssedfr');
this.counter++;
},
activateMediaButton(){
navigator.mediaSession.metadata = new window.MediaMetadata({})
navigator.mediaSession.playbackState = 'playing';
try{
navigator.mediaSession.setActionHandler('play', this.increment)
navigator.mediaSession.setActionHandler('pause',this.increment)
}
catch(error){console.log(error);}
}
}
}
</script>
As you can see, the action handlers are registered when I click the start button on the GUI, and the counter value is supposed to go up whenever I press the media buttons. I have tested this counter using the Increment button element on the GUI and it works fine, but the calls to increment aren't even being fired when the media keys are pressed as confirmed by console.log statements. No errors are thrown when the try block is executed to register the actions.
I am testing this functionality by using the Media keys on my laptop, which otherwise do play and pause media available in any open tabs. I have closed all other media tabs so that nothing is intercepting the keystrokes. I do notice that whenever I press the media button after the actions are registered, the focus goes to the Start button element that triggered the registration in such a way that it looks like a click is being held on it.
I have also tested this on my phone through a Netlify hosted PWA and bluetooth earphones and it doesn't work there either.
To work with Web Media Session API, the page must have to be playing a media file (video or audio).
Here is a working example:
<template>
<div>
<button #click="activateMediaButton">Start</button>
<div>{{ counter }}</div>
<button #click="increment">Increment</button>
<audio
src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
controls
></audio>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
counter: 0,
};
},
mounted() {
navigator.mediaSession.metadata = new window.MediaMetadata({
title: "Unforgettable",
artist: "Nat King Cole",
album: "The Ultimate Collection (Remastered)",
artwork: [
{
src: "https://dummyimage.com/512x512",
sizes: "512x512",
type: "image/png",
},
],
});
navigator.mediaSession.setActionHandler("play", this.increment);
navigator.mediaSession.setActionHandler("pause", this.increment);
},
methods: {
increment() {
this.counter++;
// handle action from here
},
activateMediaButton() {
if (navigator.mediaSession.playbackState === "playing") {
navigator.mediaSession.playbackState = "pause";
document.querySelector("audio").pause();
} else {
navigator.mediaSession.playbackState = "playing";
document.querySelector("audio").play();
}
},
},
};
</script>
To understand how it works try pausing the audio manually from the page and then try using the media keys.

Youtube iframe on ionic app generate play icon background

I'm developing an app, using Ionic 3, thats reproduce a youtube video. As I want an embedded video I use an iframe where the src is the video's url.
When I test on an Android device, i get this before the video starts playing.
Is there a way to avoid that background? or make it personalized?
Testing it using "ionic serve" makes the background completely black, so it only happens running on an android device.
Why not use a temporary <img>, as soon as the user clicks on the img, the <iframe> tag is toggled on, with Autoplay = true.
I recommend using angular youtube-player. You can detect when the video is ready to play. If the video is not ready yet, just display an image or a spinner.
Here is an example:
HTML:
<img class="video-loading-cover" src="assets/images/home/ytcover.png" height="550" width="1400" [hidden]="isVideoLoaded" alt="">
<youtube-player #youTubePlayer (ready)="playVideo($event)" (stateChange)="onPlayerStateChange($event)" (error)="hideVideo()"
width="100%" height="540px" [playerVars]="playerVars" [videoId]="videoId"></youtube-player>
TS:
#ViewChild('youTubePlayer') youTubePlayer: YT.Player;
isVideoLoaded: boolean;
videoId = 'your video id';
// optional
playerVars: YT.PlayerVars = {
autoplay: AutoPlay.AutoPlay,
loop: Loop.Loop,
playlist: 'yourPlaylist',
controls: Controls.Hide,
enablejsapi: JsApi.Enable,
origin: window.location.origin,
rel: RelatedVideos.Hide,
iv_load_policy: IvLoadPolicy.Hide,
autohide: AutoHide.HideAllControls,
showinfo: ShowInfo.Hide
};
ngOnInit() {
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
document.body.appendChild(tag);
}
onPlayerStateChange(el) {
this.youTubePlayer.mute();
switch (el.data) {
case -1:
case 2:
this.youTubePlayer.playVideo();
break;
case 1:
this.isVideoLoaded = true;
break;
}
}
hideVideo(): void {
this.isVideoLoaded = false;
}
playVideo(event): void {
this.youTubePlayer.mute();
setTimeout(() => {
this.youTubePlayer.playVideo();
}, 10);
}
Note that in my example when the youtube video is loading it will call the (error)="hideVideo()" function and an image will be displayed. When it is available it will automatically hide the image and play the video.

Why does mobile safari only show a loader and then just a black rectangle when playing a youtube embed via javascript on an iphone?

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.

iPhone Safari - Pause html audio when pressing home button

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

Playing youtube using <iframe> fails on iPhone, but still works for iPad under iOS 6 (both work fine on iOS 5)

I use the following HTML template with an to hand to a UIWebView. I understand that this is the supported way to play youtube videos.
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
playerVars: {'autoplay' : 1},
height: 'VIDEO_HEIGHT',
width: 'VIDEO_WIDTH',
videoId: 'VIDEO_ID',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
if (event.data == YT.PlayerState.ENDED) {
event.target.clearVideo();
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
Obviously, I substitute in the dynamic values for the HEIGHT, WIDTH and VIDEOID params. This has always worked fine under iOS 5 on iPhone and iPad. Now under iOS 6, when the user taps the triangle the video appears to download and try to start, then gives up. Here is what appears in the logfile:
> 2012-09-30 23:27:48.759 xxxxx[6219:c07] [MPAVController] Autoplay: Enabling autoplay
> 2012-09-30 23:27:48.759 xxxxx[6219:c07] [MPAVController] Autoplay: Skipping autoplay, disabled (for current item: 0, on player: 1)
> 2012-09-30 23:27:48.761 xxxxx[6219:c07] setting movie path: http://o-o---preferred---sn-ab5e6nll---v24---lscache1.c.youtube.com/videoplayback?upn=ag6FiVPe_XY&sparams=cp%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&fexp=907064%2C908457%2C908310%2C914072%2C922401%2C920704%2C912806%2C913419%2C913546%2C913556%2C919349%2C919351%2C925109%2C919003%2C912706&key=yt1&expire=1349086864&itag=18&ipbits=8&sver=3&ratebypass=yes&mt=1349062032&ip=96.232.106.90&mv=m&source=youtube&ms=au&cp=U0hTTlBTVF9LTkNOM19ITVhJOnRob1gwVHFmQWUw&id=04d71fcbfe79a176&signature=33A43FD457B9FC5DD70284826E7D9BF113F9C0BB.9BC87BDCF97DFCB64F967D2CAD1051D2FC80DAC0
Same results in Simulator (all supported models) and hardware device (iPhone 4s).
Oddly, it still works just fine on iPad 2 (simulator and hardware), here is the logging:
> 2012-09-30 23:32:01.586 xxxxx[6390:c07] [MPAVController] Autoplay: Enabling autoplay
> 2012-09-30 23:32:01.586 xxxxx[6390:c07] [MPAVController] Autoplay: Skipping autoplay, disabled (for current item: 0, on player: 1)
> 2012-09-30 23:32:01.588 xxxxx[6390:c07] setting movie path: http://o-o---preferred---sn-ab5e6nll---v24---lscache1.c.youtube.com/videoplayback?upn=x7-Ydawtba4&sparams=cp%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&fexp=920921%2C926600%2C915704%2C914071%2C922401%2C920704%2C912806%2C913419%2C913546%2C913556%2C919349%2C919351%2C925109%2C919003%2C912706&key=yt1&expire=1349086864&itag=18&ipbits=8&sver=3&ratebypass=yes&mt=1349062271&ip=96.232.106.90&mv=m&source=youtube&ms=au&cp=U0hTTlBTVF9LTkNOM19ITVhJOmVQbjRzVUhBbFpF&id=04d71fcbfe79a176&signature=CD05405B78D1CD7987FE5B9F41DD2C15943BBC2E.863966BDB04003866C6740046C0C2499A0CC4DDD
I've seen some similar questions here recently, but so far no one has suggested what might be be happening. Can anybody suggest what might be going on?
Regards,
-MpK-
Your html worked fine for me (with HEIGHT, WIDTH and VIDEOID substitutions) as-is, loaded in a UIWebView on iOS 6, in both Simulator and device (iPhone 5).
Could the problem have been an intermittent YouTube or network problem? Have you tried again since or tried a different video ID?
Cheers,
Chris
I got the same issue. For me that was happening because i loaded video in viewWillAppear. viewWillAppear is called again after the you-tube video loaded. I fixed it by changing my code (viewWillAppear is called only in ios 6 after video loading)