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...
Related
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.
I was trying to share a Youtube link and wanted the person to just see that clip without any of the irrelevant suggestions that pop up next to it. I knew that adding ?rel=0 (or &rel=0) at the end of the URL used to achieve this, but this doesn't seem to be working anymore. After googling a bit, I found suggestions to use the youtu.be domain instead of youtube.com, but suggestions were shown nonetheless, or the URL gave an error. How else can I share this link and have no 'related' clips shown on the side? Thanks!
rel=0 is used to disable related videos shown at the end of a video, not to remove the suggested videos in the sidebars.
You can use the embed URL to access the video on it's own - http://youtube.com/embed/dQw4w9WgXcQ. Add ?rel=0 to disable the related videos at the end too.
Note, that rel=0 no longer works if you are signed into your Google account (YouTube, Gmail, etc).
&rel=0 only works when not signed in. However, you can get around this by using the enhanced privacy mode:
https://www.youtube-nocookie.com/embed/[id]?rel=0
As of August 23, 2018,
The behavior for the rel parameter is changing on or after September
25, 2018. The effect of the change is that you will not be able to
disable related videos. However, you will have the option of
specifying that the related videos shown in the player should be from
the same channel as the video that was just played.
To be more specific:
Prior to the change, if the parameter's value is set to 0, then the player does not show related videos.
After the change, if the rel parameter is set to 0, the player will show related videos that are from the same channel as the video that was just played.
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?
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.
I have a Windows phone app with a page that uses the XNA Microphone and has a record button and play back button, very similar to any number of tutorials online. When I first navigate to the page the record and play functionality works fine. However, if I click the back button, then navigate to the page again, the sound recorded sounds like a part of the spoken word repeated a couple of times. For example, I'll record "testing" and the playback sounds like "sss...sss". Any ideas?
I figured it out. The following line is in the page's constructor:
this.MicroPhone.BufferReady += new EventHandler(this.Microphone_BufferReady);
A new page gets constructed on every navigation to the page, therefore the Microphone_BufferReady function in multiple instances of the same page object was getting called and the data from the microphone was occasionally being stored in other instances. The key is to remove the handler in the OnNavigatedFrom page event:
this.MicroPhone.BufferReady -= new EventHandler(this.Microphone_BufferReady);