youtube iframe api parameter rel=0 doesn't work - youtube-iframe-api

I need to hide related videos after watching the video. I set rel=0, but it is not working. I am using this page for testing. The rel checkbox value doesn't affect on shown related videos after watching video.
It doesn't work in google chrome. In mozilla firefox it properly works.

As of September 25, 2018, you are not be able to disable related videos. Instead, if the rel parameter is set to 0, related videos will come from the same channel as the video that was just played.
YouTube API

YouTube changed the rel=0 parameter as of September 2018 so that it no longer fully disables related videos.
However, you can work around this using the YouTube Player API to show custom HTML instead of related videos.
Here is some example code that displays a custom "replay" button over the video once it completes, hiding the related videos:
<style>
#playerWrap {
display: inline-block;
position: relative;
}
#playerWrap.shown::after {
content:"";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
cursor: pointer;
background-color: black;
background-repeat: no-repeat;
background-position: center;
background-size: 64px 64px;
background-image: url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgNTEwIDUxMCI+PHBhdGggZD0iTTI1NSAxMDJWMEwxMjcuNSAxMjcuNSAyNTUgMjU1VjE1M2M4NC4xNSAwIDE1MyA2OC44NSAxNTMgMTUzcy02OC44NSAxNTMtMTUzIDE1My0xNTMtNjguODUtMTUzLTE1M0g1MWMwIDExMi4yIDkxLjggMjA0IDIwNCAyMDRzMjA0LTkxLjggMjA0LTIwNC05MS44LTIwNC0yMDQtMjA0eiIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==);
}
</style>
<div>
<div id="playerWrap">
<iframe
width="640" height="360"
src="https://www.youtube.com/embed/0sDg2h3M1RE?enablejsapi=1"
frameborder="0"
></iframe>
</div>
</div>
<script>
var playerFrame = document.currentScript.previousElementSibling.children[0].children[0];
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(playerFrame, {
videoId: 'M7lc1UVf-VE',
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
document.getElementById("playerWrap").classList.add("shown");
}
}
document.getElementById("playerWrap").addEventListener("click", function() {
player.seekTo(0);
document.getElementById("playerWrap").classList.remove("shown");
});
</script>
For the minified code along with further description, details and instructions, view my blog post on the subject.

This is because you are most likely signed in on your Chrome browser, but not your Firefox browser.
&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

If you want to hide related video then you should call "player.stopVideo()" when player state is ended "PlayerState.ENDED".
PS: Sorry, english is not my first language.

Here i found a Solution. stopVideo on player state changed to ENDING
<!DOCTYPE html>
<html>
<head>
<title>Alternative to hide Related Video & Info</title>
<script src="https://www.youtube.com/iframe_api"></script>
</head>
<body>
<div id="playerWrapOuter">
<div id="playerWrap">
<?php
$embed = '<iframe width="560" height="315" src="https://www.youtube.com/embed/HjxYvcdpVnU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>';
preg_match('/src="(.+?)"/', $embed, $matches);
$src = $matches[1];
$params = array(
'width' => "640",
'height' => "360",
'enablejsapi' => 1,
'rel' => 0,
'modestbranding' => 1,
'showinfo' => 0,
);
$querystring = http_build_query($params, $src);
$new_src = $src.'?'. $querystring;
$embed = str_replace($src, $new_src, $embed);
$embed = str_replace( '<iframe ', '<iframe ', $embed );
echo $embed;
?>
</div>
</div>
<script>
(function() {
var player;
var playerFrame = document.currentScript.previousElementSibling.querySelector("iframe");
window.onYouTubeIframeAPIReady = function() {
player = new YT.Player(playerFrame, {
events: {
'onStateChange': onPlayerStateChange
}
});
};
window.onPlayerStateChange = function(event) {
if (event.data == YT.PlayerState.ENDED) {
player.stopVideo();
}
};
})();
</script>
</body>
</html>
Here is a fiddle demo: https://jsfiddle.net/Aishan/znabhuo2/
Hope that helps!!

As stated by Irina Kovalchuk above, as of September 25, 2018, you are not be able to disable related videos.
But I found a workaround:
setInterval(function () {
if (player.getCurrentTime() >= player.getDuration()-1) {
player.seekTo(1);
}
}, 100);
as soon as video reaches to end move seek pointer to start. It won't give time to show related videos. This workaround is suitable if you want to play video in loop

Mine wasn't working because the code spit out from the dev page https://developers.google.com/youtube/youtube_player_demo
was incomplete and missing the closing tag!

Checked this both with Chrome and Opera, it works.
https://jsfiddle.net/o8ztczn6/
<iframe width="560" height="315" src="https://www.youtube.com/embed/6UVZpQ8cLSQ?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
No related video is shown on finishing.

Related

Improve loading of a page with multiple iframes with the same source

I have on page with multiple iframes.
All these iframes have the same source (within the same domain that the main page which contains them all; each iframe just shows eventually a different area of this very same source).
It does work well according to this solution that I've followed:
Multiple Iframes sending ONE request to the same SRC
I do have all my iframes loaded (each of them showing correctly its own area of this common page).
But in fact each and every iframe does make an independent request to the source. And the page is quite slow to load.
Hence my question in order to improve this process:
is there a way to load the first iframe (f1 in the example), and only then to load all the others ones with the very "same content" (that to say with the same page -even if each of them shows a different area of it but this part already works well). I didn't manage to do this with a "srcdoc".
Ifames id in the html are f1, f2, f3, and so on:
<iframe style="border: 0px none; height: 1000px; width: 1000px; margin-left: -107px; margin-top: -547px; " id="f1" scrolling="no" src="MYSOURCE.html" >
</iframe>
`
`
<iframe style="border: 0px none; height: 1000px; width: 1000px; margin-left: -107px; margin-top: -685px; " id="f3" scrolling="no" srcdoc="" src="" >
and so on...
The first function waits for the first iframe to be loaded. Then the second one try to fill up the next ones with the same source page.
FuncOL = new Array();
function StkFunc(Obj) {
FuncOL[FuncOL.length] = Obj;
}
function loadingpageinf1(){
let oldDoc = f1.contentDocument;
let timer = setInterval(() => {
if (f1.contentDocument == oldDoc) return;
f1.contentDocument.addEventListener('DOMContentLoaded', () => {
f1.contentDocument.body.prepend('Hello, world!');
});
clearInterval(timer);
}, 100);
}
StkFunc(loadingpageinf1);
function Multipleiframes(){
var frames=window.frames;
for (var i=2; i<4; i++){
var frame="f"+i;
document.getElementById(frame).srcdoc = document.getElementById(f1).srcdoc ;
}
}
StkFunc(Multipleiframes);
window.onload = function() {
for(i=0; i<FuncOL.length; i++)
{FuncOL[i]();}
}
Thanks for your help.
you could send an ajax/fetch request to get the html page and render the html inside each of your iframe in response. that's one way to do it.
fetch('your_page.html')
.then(function(response) {
return response.text()
})
.then(function(html) {
var parser = new DOMParser();
var doc = parser.parseFromString(html, "text/html");
//you can iterate iframes and assign innerHTL
})
.catch(function(err) {
console.log('Failed to fetch page: ', err);
});
or you can also create blob url and assign it to iframe's src

Adding KML Layer to Google Map embedded in a Blogger Page

I have a Blogger page with an embedded Google map which works fine. When I try to use Google's Javascript API to add a KML layer on top of the map the map becomes entirely black apart from the navigation controls. If I set the kml layer back to null the underlying map appears again.
I have tested the exact same code in a local environment and it works fine. So the issue is with embedding the code within a Blogger page.
Below is my html and js. Does anyone have any idea what the issue might be?
Note that the example kml file I'm using below is just a skeleton without any placemarkers, but I've tried it with other kmls and got the same result.
<html>
<head>
<style type="text/css">
#map-canvas {
height: 480px;
width: 500px;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3" type="text/javascript"/>
<script type="text/javascript">
function initializeMap() {
var centre = new google.maps.LatLng(35.5906421,37.6945915);
var mapOptions = {
zoom: 3,
center: centre,
mapTypeId: google.maps.MapTypeId.TERRAIN
}
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var layer = new google.maps.KmlLayer({
url: 'http://trackmytour.com/Dpxc9.kml',
preserveViewport: true
});
layer.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initializeMap);
</script>
</head>
<body>
<p>
Here is where I'll be tracking my progress.<br>
<br>
<br>
</p>
<div id="map-canvas"/>
</body>
</html>

Image z-indexed over iframe play button that passes click through directly without js

Basically, is there a way to make an image/div "invisible" in the sense that user click passes right through it to div beneath it in z-space?
Example is Youtube video in iframe, but want custom play button. Catch is that it must be user pressing the native play button that initiates play. It cannot be triggered via js api or any automated method. So... essentially need to have user see the image, but have it act as if it is not there when user clicks.
Any suggestions?
EDIT 04-22-2015
Regarding your comment:
We can read in the doc that player.playVideo() don't count toward incremental YouTube brand channel video views. Only the native button play will work for this.
In fact we can read on the doc :
player.playVideo():Void Plays the currently cued/loaded video. The
final player state after this function executes will be playing (1).
Note: A playback only counts toward a video's official view count if
it is initiated via a native play button in the player.
source: https://developers.google.com/youtube/iframe_api_reference#playVideo
This information is confirmed by the official YouTube support
Part: YouTube public play count
The YouTube Video Player allows masthead video views to count directly
toward overall YouTube brand channel video views. For the YouTube view
to count, the user must click to start the video using the standard
YouTube play button. Autoplay videos don't count toward YouTube views.
Part:Standard VS chromeless
The chromeless YouTube Player lets you customize features like player
controls, while still pulling in YouTube-served videos. Aside from the
standard play button overlay, clicks on the chromeless player's custom
control buttons don't count toward incremental YouTube brand channel
video views.
source: https://support.google.com/richmedia/answer/2566092?hl=en
So i made a new solution with function hide() and show() of Jquery. With this solution, the user will click on the native button player and if the video is not playing there is an image head-on.
You need to use the element, and not the API
HTML
$(".player-video").mouseenter(function() {
$('.player-video').hide();
$('#player').show();
});
$("#player").mouseleave(function() {
$('.player-video').show();
$('#player').hide();
});
Javacript
<iframe id="player" width="560" height="315" src="https://www.youtube.com/embed/l-gQLqv9f4o" frameborder="0" allowfullscreen style="display:none"></iframe>
<div class="player-video">
</div>
Im made you another live example: http://jsbin.com/luqewajuse/1/edit?html,js,console,output
END EDIT
You can use:
<div id="player"></div>
<button class="play-video">Play</button> //can be button or whatever
$(".play-video").click(function() {
player.playVideo();
}
EDIT 31/01/2015
Regarding your comments and what you trying to do, i make you a live demo to show you how it work :
Live demo : http://jsbin.com/jefubusejo/2/edit?html,js,output
HTML:
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
.player-video {
width: 600px;
height: 340px;
background-image:url('http://www.hqsoul.com/wp-content/uploads/2014/11/Mark-Ronson-Uptown-Funk-ft.-Bruno-Mars.jpg');
}
</style>
</head>
<body>
<div id="player" style="display:none"></div>
<div class="player-video">
</div>
</body>
</html>
Javascript:
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;
$(".player-video").click(function() {
$('.player-video').hide();
$('#player').show();
onPlayerReady();
});
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'l-gQLqv9f4o',
events: {
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady() {
player.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();
}
function myclick() { console.log("Click") }
#front, #back {
position:absolute;
top:10px;
left:10px;
border:1px solid black;
width:100px;
height:100px;
}
#front {
width:80px;
border-radius:30px;
z-index:1;
border-color:red;
}
<div id="back" onclick="myclick()" >
<div id="front"></div>
</div>
<p id='this-tag'></p>

Iframe from Adsense (250x250) auto-resizes Iframe for Youtube on same page to 250x250

The same page ( www.goo.gl/xLAhN ) has a youtube video embedded in size 640x390 in an iframe using the following code: (3 variations of youtube embed code were tried all with same results)
`<iframe id="player" type="text/html" width="640" height="390" src="http://www.youtube.com/embed/GxTl1Ykbuww?enablejsapi=1&origin=origin-domain.com" frameborder="0"></iframe>`
The same page has one Adsense banner embedded in 250x250 in an iframe using the following code:
`<script type="text/javascript"><!--
google_ad_client = "ca-pub-xxxxxxxxxxxxx";
/* test */
google_ad_slot = "xxxxxxx";
google_ad_width = 250;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>`
100% of the time the youtube video displays at 250x250. Looking at the view source, the Youtube iframe now has a style element attached to it with 250x250 directive.
`<iframe id="player" type="text/html" width="640" height="390" src="http://www.youtube.com/embed/GxTl1Ykbuww?enablejsapi=1&origin=origin-domain.com" frameborder="0" style="width: 250px; height: 250px;"></iframe>`
If the adsense code is removed , youtube video loads in correct size.
Please help, after 5 days I think this is either CORS related, but there is nothing online about this problem. Somehow adsense is allowed to overcome cross domain restrictions and inject the youtube iframe with the size of its own.
The problem had to do with jquery that was part of the theme that beautified iframes
var win = jQuery(window),
iframes = jQuery('iframe:not(.slideshow iframe):not( iframe.no_resize)',container),
adjust_iframes = function() {
iframes.each(function() {
var iframe = jQuery(this),frame_parent_w = iframe.parent().width(),proportions = 16/9;
if(this.width && this.height) {
proportions = Math.round(this.width / this.height * 1000) / 1000;
iframes.css({
width:frame_parent_w,height: frame_parent_w / proportions});
}
});
};
adjust_iframes();
win.smartresize(adjust_iframes);
After I added :not(inside iframe) to the second line (since Adsense always has their iframe wrapped in inside tags, everything rendered as expected with the above code ignoring the Adsense iframe settings.

YouTube iframe embed not starting in HD

I'm trying to embed an HD YouTube video but no matter what I try, it only ever seems to load the 480p version.
According to YouTube, embedding an HD video is as simple as adding hd=1 to the URL:
<iframe src="//www.youtube.com/embed/{videoId}?hd=1" width="960" height="720" frameborder="0" allowfullscreen></iframe>
This, however, does not seem to be working, at least in my implementation of the iframe:
<iframe id="video-player" width="960" height="720" src="//www.youtube.com/embed/{videoId}?enablejsapi=1&autoplay=1&rel=0&modestbranding=1&showinfo=0&showsearch=0" frameborder="0" allowfullscreen></iframe>
The same is true with the Javascript API:
HTML:
<div id="video-player"></div>
JS:
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('video-player', {
height: '720',
width: '960',
videoId: '{videoId}',
playerVars: {
'controls': 1,
'autoplay': 1,
'hd': 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
player.playVideo();
}
Use this parameter:
vq=hd1080
Example:
<iframe src="https://www.youtube-nocookie.com/embed/SzTdgE04uA8?vq=hd1080" width="853" height="480"></iframe>
As per this answer on the YouTube support forum:
[The iframe embed] will attempt to "optimize" the experience and will work off
of the dimensions of the embed player to choose what quality to play
it back at by default.
If the embed is much smaller than 1280x750, such as 853x510 or 640x390, it will play 480p or 360p, regardless of whether the &hd=1 parameter is set.
(Emphasis mine)
I changed the dimensions of the iframe to 1280x720 and the video loaded at 720p resolution.
So, basically the iframe embed mechanism is intelligent and only loads the closest resolution according to the size of the iframe.
There is a trick you can do. Set the quality via JS. Its not guaranteed, but works on my site (ggreplayz.com):
https://developers.google.com/youtube/js_api_reference#Playback_quality
Example:
<iframe id="vid2" style="z-index: 1;" width="853" height="505" src="http://www.youtube.com/embed/<?php echo $vid2Array[0];?>?enablejsapi=1&wmode=transparent&hd=1" frameborder="0" allowfullscreen></iframe>
<script type="text/javascript">
...
function onYouTubePlayerAPIReady() {
player1 = new YT.Player('vid1', {
events: {
'onReady': onPlayerReady1
}
});
...
function onPlayerReady1(event) {
player1.setPlaybackQuality('hd720');
}
...
hd parameter has been deprecated: https://developers.google.com/youtube/player_parameters#Deprecated_Parameters
I use &hd=1&vq=hd720 for achieve that. It loads the 720p version even if the player is smaller. I got this information from this source.
I might be a little late, but I just discovered it only looks at the height of the video player.
When I try to embed a video 1000px wide, but only 408 pixels high (2.35:1 matte) it selects 360p >:|
After spending more than 5hrs searching and testing all the answers, the below code works for me.
Using Xcode 5, iOS 7.0.4 and iPad mini2.
- (void)viewWillAppear:(BOOL)animated
{
NSString *htmlString = #"<html><head>\
<meta name = \"viewport\" content = \"initial-scale = 1.0, user-scalable = yes, height = 640px, width = 360px\"/></head>\
<body style=\"background:#000;margin-top:0px;margin-left:0px\">\
<iframe id=\"ytplayer\" type=\"text/html\" width=\"640px\" height=\"360px\"\
src=\"http://www.youtube.com/embed/%#?vq=hd1080\"\
frameborder=\"0\"/>\
</body></html>";
htmlString = [NSString stringWithFormat:htmlString,self.videoId, self.videoId];
[self.videoPlayerView loadHTMLString:htmlString baseURL:[NSURL URLWithString:#"http://www.youtube.com"]];
}
The only important thing here is the aspect ratio that you set in your iframe (" width=\"640px\" height=\"360px\"), which are basically the ratios of 1280*720. And then set the same size for your UIWebView.
Hope this help someone.
Mine wasn't working at all. I tried everything including all these parameters
&hd=1&vq=hd720&quality=high
But it didn't work until I added this parameter:
&version=3

Resources