How to handle YouTube video events (started, finished, etc) in uiwebview iOS - ios

Currently I'm using the new iframe API to embed a YouTube video inside the uiwebview on the iPad and I've been able to make it auto play without user interactions.
In the iframe API it is described how to use the onstatechange event but in my application it doesn't seem to work and unfortunately I can't see any debug in uiwebview.
I just want to able able to detect when the video ends, have you got any advice on it?
Has anyone got it to work?

Have you tried (from the documentation) to assign an integer to the event of a movie ending?:
onStateChange This event fires whenever the player's state changes.
The data property of the event object that the API passes to your
event listener function will specify an integer that corresponds to
the new player state. Possible data values are:
-1 (unstarted)
0 (ended)
1 (playing)
2 (paused)
3 (buffering)
5 (video cued).
When the player first loads a video, it will broadcast an unstarted
(-1) event. When a video is cued and ready to play, the player will
broadcast a video cued (5) event. In your code, you can specify the
integer values or you can use one of the following namespaced
variables:
YT.PlayerState.ENDED
YT.PlayerState.PLAYING
YT.PlayerState.PAUSED
YT.PlayerState.BUFFERING
YT.PlayerState.CUED
So, something like:
if(event.data==YT.PlayerState.ENDED){
//do stuff here
}

To detect when the video ends then the video has the state of 0 or YT.PlayerState.ENDED
Here's a link to jsfiddle a link!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Page 1</title>
</head>
<body>
<h1>Video page</h1>
<br>
<!-- 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 = "https://www.youtube.com/iframe_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 onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'ussCHoQttyQ',
playerVars: {
'autoplay': 0,
'controls': 0,
'showinfo': 0,
'rel': 0
},
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),
// -1 unstarted
// 0 ended
// 1 playing
// 2 paused
// 3 buffering
// 5 video cued
var done = false;
function onPlayerStateChange(event) {
console.log(event);
if (event.data == YT.PlayerState.ENDED) {
alert(1);
}
}
</script>
</body>
</html>

May this http://code.google.com/apis/youtube/js_api_reference.html#SubscribingEvents can help you

It may be connected with autoplay-policy in your browser (it's disabled by default in mobile browsers).
If your browser is chrome you can start it with additional commandline flag --autoplay-policy=no-user-gesture-required - it worked for me.

you need to make use of JavaScript for that.
Refer this link : https://developers.google.com/youtube/js_api_reference

Related

(YouTube API): YT.Player doesnt work playVideo

I need to develop autoplay when user visit the page, actually apply code snippet as provided in google doc:
https://developers.google.com/youtube/iframe_api_reference
<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 = "https://www.youtube.com/iframe_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 onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '360',
width: '640',
videoId: 'M7lc1UVf-VE',
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;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
and it doesn't work properly, video doesn't play/
I've tried to put event.target.playVideo(); in setTimeout with delay 1000, 2000, 3000, but this experiment is failed as well - video didn't play
Could you help, please?
I assume your problem is the autoplay policy most browsers implement.
It prevents autoplay in most cases.
One exception is that autoplay works when the video sound is muted. Maybe that is something that works for your use case.
For further reference visit:
https://developer.chrome.com/blog/autoplay/
https://support.mozilla.org/en-US/kb/block-autoplay
https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/

Inconsistent behavior with loop=1 on iframe

I am having a very frustrating experience trying to get videos to loop consistently using a basic iframe. I am not interacting with the API via code. I simply have an iframe with autoplay=1,mute=1,loop=1. I've tried using stand-alone videos and I've tried playlists (with list=[ID],listType=playlist) and I keep running into the same problem. Sometimes the player will loop the video and sometimes it will not. Every time I think I have it figured out and I'm ready to deploy the app, I test it again and the video fails to loop.
Windows 10
Chrome 71.0.3578.98
Angular 6.0.3
You can choose any of these options:
Check my answer where I described how you can set your URL for create a playlist (using a single videoId) and simulate a loop.
Use the YouTube iframe Player API for set your video and (once the video ended), call the playVideo() function for play the current video = hence, creating a loop.
This is the code: - unfortunately, you can't see it working here, but, you can see the working jsfiddle1
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// Variables of the divs (where the YouTube iframe will load):
var player;
function onYouTubeIframeAPIReady() {
// Div player:
player = new YT.Player('player', {
height: '360',
width: '640',
videoId: 'xPCZEoGJi_4',
playerVars: {
'autoplay': 1,
'loop': 1,
'mute': 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 5. The API calls this function when the player's state changes.
function onPlayerStateChange(event) {
// When the video ends, it will play again.
// See: https://developers.google.com/youtube/iframe_api_reference?hl=en#Events
if (event.data == YT.PlayerState.ENDED) {
player.playVideo();
}
}
// Div "player" - The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<div id="player"></div>
1 If the video (once has loaded) hasn't play, you have to play manually the video - this is due some kind of restrictions that jsfiddle has.

YouTube iframe api behavior on Chromecast

Trying to get a YouTube video playing on Chromecast, not using the YouTube receiver but simply the iframe YouTube api. When the receiver url is loaded in a desktop chrome browser it plays ok but when the same url is loaded onto Chromecast I get the message 'This video is currently unavailable - Learn More'. If I keep trying to get the widget, once created, to play different videos it sometimes also says 'The Adobe Flash Player is required for video playback'.
The widget is created in the onYouTubeIframeAPIReady() callback using new YT.Player as shown in the docs. Maybe I'm confused but I thought the iframe api was html5 based, not flash based. Has anyone successfully achieved this or is this unsupported on Chromecast, hence the weird behaviour? I also stumbled across this http://www.youtube.com/html5
Here's the code I'm currently using on my receiver. The message handling (both directions) is hit and miss, and I'm currently working through that ... but the loading of the iFrame library, the embedding of the video, etc. all works. If it doesn't work on your end, we can start to investigate how your setup might be different. I've tried to add comments where it might be helpful.
<html>
<head>
<script src="https://www.gstatic.com/cast/js/receiver/1.0/cast_receiver.js">
</script>
<script type="text/javascript">
// first create our receiver object and our channel handler
var receiver = new cast.receiver.Receiver('{YOUR_APP_ID}', ['ChromecastYoutube'],"",5);
var ytChannelHandler = new cast.receiver.ChannelHandler('ChromecastYoutube'); // 'using 'ChromecastYoutube' as my dev namespace. Wouldn't really be that in production.
ytChannelHandler.addChannelFactory(receiver.createChannelFactory('ChromecastYoutube'));
ytChannelHandler.addEventListener(
cast.receiver.Channel.EventType.MESSAGE,
onMessage.bind(this)
);
receiver.start();
window.addEventListener('load', function() { // we won't try to load the iframe libraries until the chromecast window is fully loaded.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '562',
width: '1000',
videoId: 'jLlSqucqXB0',
playerVars: { 'autoplay': 0, 'controls': 0 },
events: {
'onReady': onPlayerReady,
'onPlayerStateChange': onStateChange
}
});
}
function onPlayerReady(event) {
document.getElementById('annotation').innerHTML="We're ready to go";
}
function onStateChange(event) {
switch (event.data) {
case YT.PlayerState.ENDED:
// TODO let sender know we're done, then close casting
break;
case YT.PlayerState.PLAYING:
// TODO let sender know we're playing
break;
case YT.PlayerState.PAUSED:
// TODO let sender know we're paused
break;
}
}
function onMessage(event) { // currently, any one of these will work, but subsequent ones seem to falter. Investigating...
ytBindings={"playVideo":player.playVideo(),"pauseVideo":player.pauseVideo(),"stopVideo":player.stopVideo(),"getStatus":player.getPlayerState()}
ytBindings[event.message];
}
</script>
<style>
#wrapper {
width: 1000px;
margin: 10px auto;
text-align: center;
}
#annotation {
color: #ffffcc;
font-size: 200%;
margin-top:25px;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="player"></div>
<div id="annotation"></div>
</div>
</body>
</html>
Current behavior: it now seems to be fixed with Chromecast firmware 16041 and if the country code is set correctly during Chromecast setup. See the latest comment here https://code.google.com/p/gdata-issues/issues/detail?id=5923
Old answer:
Here is the root cause of the issue: https://support.google.com/chromecast/answer/2995235?hl=en
Some videos may not play using Chromecast. Private videos, live content, and videos not approved for mobile playback will not work with Chromecast.
Hopefully this will change, kills a primary Chromecast use case.
I also ran into this issue and found the cause to be the fact that I was using html5 audio to play some sound effects just before the video began. Removing the sound effects made the youtube player work again.

Are YouTube view counts incremented when using the iframe Player?

We are embedding a youtube player into our page. Easy implementation of code and html5 support driven us to use the youtube iframe player.
Problem is that view count does not work with the api. No video does not autoplay and we are playing the video with youtube's default play button.
When I revert back to a AS3 player view count seems to work.
Is it a bug in the iframe api?
Anyone come across a solve?
Thanks!!!
Views that originate as a result of clicking on one of the native player UI elements (either the play button in the control bar or on the static player image) will normally count towards incrementing the views for a video. There are obviously other signals that could come into play, but all things being equal, there's no reason why using an <iframe> embed vs. an ActionScript 3 embed should prevent views from being counted.
If you have a specific example of your implementation that you want to pass along, I can take a look and see if you're doing anything unorthodox.
we have created a simple test html file with a video using the YouTube iFrame API, as the idea is to have the videoplayer fall back to the HTML5 videoplayer on mobile devices. However views are not being counted on click to play video:
http://www.youtube.com/watch?v=-LHUt9FGgys
In the body of the html we have the following:
<div id="player"></div>
<script>
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: '-LHUt9FGgys',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
//event.target.playVideo();
}
var done = false;
function onPlayerStateChange(event) {
// if (event.data == YT.PlayerState.PLAYING && !done) {
// setTimeout(stopVideo, 6000);
// done = true;
// }
}
function stopVideo() {
player.stopVideo();
}
</script>
It would be interesting to see if you or someone else has a solution for this. Thanks!

Youtube IFrame API onError fires with error code 150 for videos from Vevo

Let me explain my scenario. I want to use Youtube IFrame API to embed some videos on my website.
I tested the video with id wdGZBRAwW74 (https://www.youtube.com/watch?v=wdGZBRAwW74) on this page: Youtube IFrame Player Demo. And it works OK.
I try this example code:
<!DOCTYPE html>
<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 = "//www.youtube.com/iframe_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 onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'wdGZBRAwW74',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
'onError': onPlayerError
}
});
}
// 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;
}
}
function onPlayerError(event){
console.log(event.data);
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
with some virtual host domains on my localhost and i got result:
with domain app.centaur.com/youtube/index.htm: IFrame API work OK, the video play without problems.
with domain app.music.com/youtube/index.html: IFrame API work OK, but the video can not play, API fires onError with error 150 and the embedded player show message "This video contains content from VEVO, who has blocked it from display on this website. Watch on Youtube"
with domain app.musiccentaur.com/youtube/index.htm: like first case, everything work ok
with domain app.centaurmusic.com/youtube/: like first case, everything work ok
As i know error 150 stand for "The owner of the requested video does not allow it to be played in embedded players". But i see it still work in case 1, 3, 4, so what is it mean ?
Seem all of videos by Vevo related to this problems. I'm not sure if Vevo defined some policy for embedding their videos.
Maybe the problem come from my domain music.com, but i'm not sure there is some rules of domain to embed Vevo's video on websites.
What if i buy a domain for my website then i got error 150, this is so bad. :(
Is there anyone deal with this before? Please give me some solutions. Thanks in advance.
Note: this error only occurs on Vevo's videos.
Content owners are allowed to set up a white/black list of domain names on which embedding is allowed/denied. There is no way to work around these restriction.
This blog post has a bit more info about content restrictions in general: http://apiblog.youtube.com/2011/12/understanding-playback-restrictions.html

Resources