I'm currently loading the YouTube API like so:
$(function () {
// This code will trigger onYouTubePlayerAPIReady
$('<script>', {
src: 'https://s.ytimg.com/yts/jsbin/www-widgetapi-vflwt8QCF.js',
async: true
}).insertBefore($('script:first'));
});
I was looking at the YouTube demo page, https://developers.google.com/youtube/youtube_player_demo, and I noticed in their source that they were using a different URL to load their widget API:
<script src="https://s.ytimg.com/yts/jsbin/www-widgetapi-vfl4qCmf3.js" async></script>
I thought that this might be a more up-to-date version of their API. So, I swapped it out, but I receive an error message:
Uncaught ReferenceError: YTConfig is not defined
I'm left wondering which of these is the correct location, if either, to be loading the most up to date widgetapi data from. Is there a location for this info?
to get the latest API version I suggest to use example from YT reference:
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
this'll make sure the latest version is being loaded
if you really need to grab latest version for some reason just check this url:
https://www.youtube.com/iframe_api
and get it from the source code
Related
With the YouTube JS API, I can do the following:
<script src="//www.youtube.com/player_api"></script>
<script language="javascript">
function onYouTubeIframeAPIReady() {
ytPlayer = new YT.Player('ytplayer');
}
</script>
This will load the API, and when its ready, assign ytPlayer.
However, the Dailymotion API is included as follows:
<script src="//api.dmcdn.net/all.js"></script>
<script>
DM.init();
</script>
This doesn't wait for the API to be ready. So I'll often get Uncaught ReferenceError: DM is not defined errors. Does Dailymotion have a way to wait for the API to be ready before it executes code?
The most efficient way to load the SDK in your site is to load it asynchronously: example loading asynchronously
You can then subscribe to the event 'apiready'
event subscribe documentation
list of events
Has YouTube started locking down cross origin requests?
I am using a fullscreen autoplay hero video on my website and it has been functioning correctly for a long time. Within the last couple weeks it stopped working and I have the following error in the logs.
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('https://tbrogames.github.io').
Per the answer on this question
I tried changing the host between http and https to see if that would fix it and it didn't.
My website that throws the error: https://tbrogames.github.io/
I was able to find a bigger games website that also has this exact issue.
https://playbattlegrounds.com/main.pu
They are also using a youtube video as the hero/splash video; and it no longer functions, throwing the same error.
The relevant javascript can be found here
https://github.com/tbrogames/tbrogames.github.io/blob/master/js/defer.js
However, this was working for a long time and I didn't change any of the code. Which is why I'm thinking that it is a change that YouTube has made.
I think that error is actually misleading. I had the same issue, but I believe that it is actually chrome that is no longer autoplaying the hero. I get this error: Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first. https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
The fix for me was calling mute on the video in Javascript Before playing the video. The iframe version of the embed with the same properties would not autoplay
<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('ythero', {
videoId: '3FjTef9gn3Q',
height: '100%',
width: '100%',
playerVars: {
rel: 0,
controls: 0,
showinfo: 0,
autoplay: 1,
loop: 1,
playlist: '3FjTef9gn3Q',
modestbranding: 1
},
events: {
'onReady': onPlayerReady,
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.mute();
event.target.playVideo();
}
</script>
YouTube does allow it. Make sure you are loading from a URL such as:
https://www.youtube.com/embed/HIbAz29L-FA?modestbranding=1&playsinline=0&showinfo=0&enablejsapi=1&origin=https%3A%2F%2Fintercoin.org&widgetid=1
Note the "origin" component, as well as "enablejsapi=1". The origin must match what your domain is, and then it will be whitelisted and work.
My google-map is only loading asynchronously after a page reload or an HTTP redirect. For the first onload, it won't appear-- none of the javascript is called.
In Rails development mode, it works without any problem. Likewise, the map loads asynchronously in production mode if I serve assets locally. But when I configure Amazon Web Services' Cloudfront CDN, it fails on the first page load.
Here's the javascript from the view that calls the map:
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.1.min.js"></script>
<script type="text/javascript">
function initialize() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
streetViewControl: false,
overviewMapControl: false,
mapTypeControl: false,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.DEFAULT,
},
center: new google.maps.LatLng(39.82, -98.58),
});
// Info Window Content
var infoWindowContent = <%= raw #content %>;
var locations = <%= raw #location %>;
// Display multiple markers on a map
var infowindow = new google.maps.InfoWindow(), marker, i;
var marker, i;
var markers = new Array();
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(infoWindowContent[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
function loadScript() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' +
'callback=initialize';
document.body.appendChild(script);
}
window.onload =loadScript;
</script>
Any idea what may be going wrong with the code on AWS Cloudfront?
Wow. Finally solved this.
A few things went wrong.
First, AWS S3 and Cloudfront do not allow CORS, or Cross Origin Resource Sharing, by default. This means that you cannot call an AJAX resource served by either-- it won't work. That said, you can configure both to allow CORS. To do so, you need to edit your S3 bucket permissions and add a CORS Configuration (AWS offers good examples on help pages). Next, you need to whitelist the 'Origin' header on your Cloudfront distribution. This will allow cloudfront to forward the Origin header from the request to the response, and allow CORS. (I didn't fully get this to work. Check AWS help resources on CORS for more information)
Second, I noticed that even though my AJAX script was served locally and not by Cloudfront, a different javascript file was: my Turbolinks js file. It turns out the Turbolinks gem that the Rails Asset Pipeline requires creates a js file ended up being uploaded to my distribution (it's required by default in the application.js file). If you read the Turbolinks documentation, you'll see that Turbolinks ensures only reloads the html body and title of the head. Here's this from the README:
"Instead of letting the browser recompile the JavaScript and CSS between each page
change, it keeps the current page instance alive and replaces only the body and
the title in the head"
As it turns out, the Turbolinks interfered with the local AJAX and prevented the Google Map from loading asynchronously. Since the AWS CORS configuration evaded me, I simply added the option to turn turbolinks off for the link leading to the Google Map page:
data: { no_turbolink: true }
to make the full link:
<%=link_to "/map", data: { no_turbolink: true } %>
With no turbolinks, the page was never called using the Cloudfront Turbolinks.js file, and thus the local AJax could load the Google Map.
I hope this helps ye weary travelers!
I've got an odd issue that I cannot figure out. When using Twitter and Google+ share buttons, it shares the correct page title, but also gives a completely wrong URL.
What's even more weird is that it is using a URL from another website of mine, completely unrelated!
These are the buttons:
<li>Tweet</li>
<li><div class="g-plusone" data-size="medium" data-annotation="inline"></div></li>
Here is the javascript that powers them:
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
I've made sure to be logged into the right account when grabbing the code for the buttons.
I don't get it!
ps. It is being done within my own Wordpress Template if that helps, but I've done this before with no problems.
Make sure you don't have a rel=canonical link on your page pointing to a different URL. Perhaps another plugin is outputting it?
I am trying to integrate OAuth with my chrome extension. I am following the tutorial by google: https://developer.chrome.com/extensions/tut_oauth.html
I create ExOauth from the background.js (defined by me and it is loaded by background.html).
var oauth = ChromeExOAuth.initBackgroundPage({
'request_url': 'https://www.google.com/accounts/OAuthGetRequestToken',
'authorize_url': 'https://www.google.com/accounts/OAuthAuthorizeToken',
'access_url': 'https://www.google.com/accounts/OAuthGetAccessToken',
'consumer_key': 'anonymous',
'consumer_secret': 'anonymous',
'scope': 'https://docs.google.com/feeds/',
'app_name': Test app'
});
oauth.authorize(onAuthorized);
Here is the OnAuthorized method:
onAuthorized = function () {
// Start my application logic.
};
Am I missing something here? When I load the extension, it opens up several "Redirecting...." tabs.
The tutorial seems to be missing one file. If you open chrome_ex_oauth.html, you'll see that it tries to load 3 js files:
<script type="text/javascript" src="chrome_ex_oauthsimple.js"></script>
<script type="text/javascript" src="chrome_ex_oauth.js"></script>
<script type="text/javascript" src="onload.js"></script>
The onload.js file is not provided. The OAuth contacts example provides such a file, with the following content:
window.onload = function() {
ChromeExOAuth.initCallbackPage();
}
After adding this file, it seems to work just fine.
I know the Question is a bit older but i had the same Problem.
I made the mistake that i want to authenticate two oauth endpoint and call both times the ChromeExOAuth.initBackgroundPage({})
Obviously that's wrong cause i dont want to init my background page twice.
Maybe using the ..._oauthsimple.js will fix that