Verify User Watched YouTube Video in Backbone App - jquery-ui

I have a Backbone Marionette app with a Rails back-end. I need to be able to display a youtube video in a mobile browser on the Backbone side. Easy enough.
The place I'm running into trouble is figuring out how to validate that a user completely watched a video. Does anyone know how I can do this?
So far I'm letting the user view the video via jquery_youtube which more or less just wraps the youtube video in a modal window.
I'm not too familiar with the Youtube API but it seems like player.getPlayerState() = 0 might be what I'm looking for.
I was thinking that perhaps I could do
events:
"beforeClose .ui-dialog-title": "checkVideoStatus"
checkVideoStatus: (e) ->
console.log e
console.log "log"
and then in the check video status I could verify that player.getPlayerState() = 0 but I can't seem to get the log statements to fire which of course is because the dialog modal is outside of this view.
Any ideas for how I can verify that the user watched the video?

Related

The embedded player shows "Please click here to watch this video on YouTube" to some users under unclearly circumstances

We use the YouTube embedded player on a hybrid app based on Cordova. The app has a lot of traffic worldwide.
The player displays the message "Please click here to watch this video on YouTube" to some users when they try to play any video under unclearly circumstances.
We do not see a clear pattern, it doesn't seem to depend on the user's country nor the restrictions of the video.
We have seen in the player code (https://www.youtube.com/yts/jsbin/player_ias-vflrnurMS/en_US/base.js) that the message is assigned to a constant called "TOO_MANY_REQUESTS_WITH_LINK" but there is no high volume of requests per user and the quota cannot be configured as in other Google APIs.
We follow the iFrame API reference:
https://developers.google.com/youtube/iframe_api_reference?hl=en
<iframe id="player" src="https://www.youtube.com/embed/M7lc1UVf-VE?autoplay=1&cc_load_policy=0&controls=0&disablekb=1&enablejsapi=1&fs=0&iv_load_policy=3&loop=0&modestbranding=1&playsinline=1&rel=0&showinfo=0&wmode=transparent&origin=XXX" frameborder="0"></iframe>
<script type="text/javascript">
var player,
scriptTag = document.createElement('script'),
firstScriptTag = document.getElementsByTagName('script')[0];
scriptTag.src = "https://www.youtube.com/iframe_api";
firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag);
function onYouTubeIframeAPIReady() {
var options = JSON.parse('{"autoplay":1,"cc_load_policy":0,"controls":0,"disablekb":1,"enablejsapi":1,"fs":0,"iv_load_policy":3,"loop":0,"modestbranding":1,"playsinline":1,"rel":0,"showinfo":0,"wmode":"transparent","origin":"XXX"}');
if (!options.origin) {
options.origin = location.origin ||
location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');
}
player = new YTRemoteVPlayer('player', '<%-videoId%>', options);
}
</script>
Does anyone know what may be happening and how to fix it?
Me and my teammates managed to reproduce that behaviour locally.
To reproduce that behaviour, all you need to do is, under the same IP Address, to load the youtube JS multiple times and for different videos. Although I cannot clarify the exact amount of times it must be done (we left some devices aside doing it), the behavior certainly happened.
As an attempt of a workaround for that problem, we accessed the https://web.archive.org/web website and fetched an old YouTube JS script (https://www.youtube.com/iframe_api). We tried to use that old script, but with no success. The message continued to appear =/.
I really do not know if there is much we, developers, can do about it, but wait for an YouTube statement and/or revision of recent changes on their end.
Update
There is an issue opened on Google's issue tracker website:
https://issuetracker.google.com/issues/143091693
Update
It looks like that YouTube have resolved that problem on their end. We'll keep monitoring :)
Update (November 5th 2019)
The problem is happening again.
Update (November 7th 2019)
I have opened a new issue on issuetracker:
- https://issuetracker.google.com/issues/144057800
I don't have a fix for it, but I can add more information about the problem, this way maybe someone can help us with this issue.
I am getting the same error with some users, and like you said there is no a clear pattern. My devices are working properly, but I did some tests with the help of a user of my app that is getting this error. Following the results:
Demo used in my tests: https://developers.google.com/youtube/youtube_player_demo
Test 1 - Open the iframe player api demo on device's browser - WORKED
Test 2 - Open the iframe player api demo into a webview on my app - FAIL
Test 3 - Open the iframe player api demo into a webview on my app using a VPN connection - WORKED
So, it appears to be a combination of APP + IP is blocked. I don't know the reason, and it will be very helpful if someone repeat these tests. I am trying to confirm it with another user, but it's a little hard to find someone willing to help.
UPDATE: a second user tried to use a VPN and it worked to him too.
UPDATE 2: a user with this problem told me that the videos are working properly again now. It appears to be a temporary block by Youtube on server side.

YouTube iFrame API: events fired for TrueView InStream Ads (video ads)

Which events are fired when a TrueView InStreams ad starts and ends?
The YouTube iFrame API reference does not give any hint about it.
I need to know when the real video starts.
As these ads are shown "randomly", I cannot make any test.
One possible answer could be a way to systematically show these ads (and thus allow testing).
Seems already answered by What is the YouTube's PlayerState during pre-roll ad?.
Basically, when ads starts state changes from -1 (undefined) to 5 (cued) then 2 (paused).
I guess it's possible to know if ads on by looping (setInterval and such) and checking if state strictly goes from -1, 5 and finally 2.
Starting check with -1 secures from confusing ad's start/end from other event likes "cueing next video", etc.
However, this isn't a perfect solution as ads can start at the end of the video...

Youtube-API: How to determine if I liked a video before?

I am developing a client of Youtube for iOS devices. I want to check if logged user did Like or dislike a specified video or not. But I can't find any support API (here)
When I load the feed of videos, I just found rating information below , No thing shows that logged user liked or disliked this video.
{
"gd$rating":{
"average":4.8963733,
"max":5,
"min":1,
"numRaters":193,
"rel":"http://schemas.google.com/g/2005#overall"
},
"yt$statistics":{
"favoriteCount":"0",
"viewCount":"111626"
},
"yt$rating":{
"numDislikes":"5",
"numLikes":"188"
}
}
Did I make any mistake?
It can be done using YouTube Data API v3.
https://developers.google.com/youtube/v3/docs/videos/getRating
This is API v3, checkout this page :
https://developers.google.com/youtube/v3/docs/playlists
Currently, The official client youtube on android and iOS devices does not support this. User can't see that he/she liked or disliked a video. And, when I press "like" or "dislike" on iPad youtube app, the number of like on the youtube web does not change.
Unbelievable!

SoundCloud Widget External Control iOS issue

I have found a bug using the external controls for the html5 widget on iOS, i have tested with iphone and ipad. The controls inside the widget work ok. However on my clients site http://www.bushytunes.net and the widget api playground http://w.soundcloud.com/player/api_playground.html the external controls run an error.
Here is what the console from the widget playground prints:
SC.Widget.Events.PLAY {"loadedProgress":null,"currentPosition":0,"relativePosition":0}
SC.Widget.Events.PAUSE {"loadedProgress":null,"currentPosition":0,"relativePosition":0}
SC.Widget.Events.PLAY {"loadedProgress":null,"currentPosition":0,"relativePosition":0}
SC.Widget.Events.PLAY {"loadedProgress":null,"currentPosition":0,"relativePosition":0}
SC.Widget.Events.PLAY {"loadedProgress":null,"currentPosition":0,"relativePosition":0}
SC.Widget.Events.READY {}
Loading...
Thanks, James
TL;DR: iOS 6 should work with a limitation of a call to play to be init by user action, iOS5 and below probably won't get a fix.
We'll try to resolve this with some kind of a hack, but most probably this won't get a proper solution any time soon.
SoundCloud Widget is using HTML5 Audio to play sounds on iOS. There are two limitations on starting playback in iOS:
Playback must be started by user action (so within event handler)
The call to audio.play method has to be within synchronous call stack of that event handler.
This means, that this works:
document.querySelector('.play-button').addEventListener('click', function () {
audioController.play();
}, false);
But this doesn't:
document.querySelector('.play-button').addEventListener('click', function () {
setTimeout(function () {
audioController.play();
}, 500);
}, false);
Cross-domain communication between iframes is only possible in asynchronous manner. Our implementation is using postMessage DOM API, but even older techniques such as Fragment Identifier Messaging (FIM) that is using location.hash are asynchronous. This means we don't currently see a way of enabling playback through API for iOS5 and below (as there is also no Flash fallback).
However, there are also good news: iOS6 has dropped the limitation No2. This means that as long as the API call to play is called by user action, you'll be able to play sounds. Even though the communication between your parent window and widgets' iframe is still async. Unfortunately iOS hasn't dropped this limitation.
I hope this helps and I'll update this answer in case we find a proper workaround.
My suggestion would be to build your own custom player with a library like Audio5JS or SoundManager2 in case controlling playback on iOS is crucial for your app.
You can see vague description of what I am talking about on developer.apple.com resource.
I can't completely tell if #gryzzly is trying to say this, but the Widget API's external controls are completely broken on mobile. The answer does explain why -- you can't synchronously tell the iFrame to play the sound, but it is my understanding that proper iframe.contentWindow calls would be synchronous? I may be wrong.
Try directing your mobile phone to the widget API playground: https://w.soundcloud.com/player/api_playground.html
Even there it doesn't actually play unless you press the orange button.
Pretty irritating since there's no application to get around the streaming API limit either. There seems to be literally no way to get a site that may experience more than 15,000 requests/plays per day to work with SoundCloud on mobile. I just want continuous music playback.

Embedding Youtube Videos on user's wall with the Javascript API

I'm attempting to embed a Youtube video on a user's wall using the Javascript API. I've poured over a bunch of different tutorials and came up with this:
var data = {
method: 'feed',
link: current_video_url, // Link to the vide on our site
source: current_video_src, // Link to the Youtube video, http://youtube.com/v/[hash]
picture: current_picture_url, // Thumbnail from youtube
title: current_video_title, // Title from our page
caption: current_video_description // Text from our page
}
FB.ui(data);
Running the Facebook Debugger shows that the current_video_url link is being properly parsed for OG tags and is available as an embedded video. I ran a debugger and all the variables are being properly set in the data variable.
This worked fine for about 2 days, and then we pushed the site live. We set up a new AppID in Facebook but now all the videos are just thumbnails instead of being embedded in the user's wall. I thought maybe this is a problem with the live site but now the dev site is broken too.
What's the best way to get this to work consistently?

Resources