Did youtube introduce a bug today on control=2 parameters? - youtube

I've been using the iframe embed with control=2 parameter as described by the docs for years.
https://developers.google.com/youtube/player_parameters
Today 7/20/17 all the placeholder thumbnails have stopped showing.
I can still see the thumbnail in the resulting css code as a background image url. The Thumbnail though just doesn't show.
So to recap while the following still show a thumbnail
<iframe width="560" height="315" src="https://www.youtube.com/embed/1sO5OKez0JQ?rel=0&controls=1" frameborder="0" allowfullscreen></iframe>
Changing the value of control to 2, does not show the thumbnail anymore
<iframe width="560" height="315" src="https://www.youtube.com/embed/1sO5OKez0JQ?rel=0&controls=2" frameborder="0" allowfullscreen></iframe>

I've also noticed that bug for a week approximatively.
But actually there's a better way to load a Youtube iframe that costs less ressources than the classic controls=2 parameter.
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<style>
.youtube-player{position:relative;width:560px;height:315px;cursor:pointer;background-color:#000000}
.youtube-player img{width:100%;height:auto;-webkit-transition: .4s all;-moz-transition: .4s all;transition: .4s all;}
.youtube-player .play{position:absolute;cursor:pointer;width:67px;height:47px;left:50%;margin-left:-34px;top:50%;margin-top:-24px;background:#ffffff;border-radius:20px;opacity:.8}
.youtube-player .play i{margin-top:-10px}
.youtube-player .play i:before{font-size:68px}
.youtube-player iframe{width:100%;height:100%;}
.youtube-player:hover .play{opacity:1}
.youtube-player:hover .play i{color:#cc181e}
</style>
<div class="youtube-player" data-id="0LRoDMe3mGk"></div>
<script>
document.addEventListener("DOMContentLoaded",
function() {
var div, n,
v = document.getElementsByClassName("youtube-player");
for (n = 0; n < v.length; n++) {
div = document.createElement("div");
div.setAttribute("data-id", v[n].dataset.id);
div.innerHTML = ytplayerThumb(v[n].dataset.id);
div.onclick = ytplayerIframe;
v[n].appendChild(div);
}
});
function ytplayerThumb(id) {
var thumb = '<img src="https://i.ytimg.com/vi/0LRoDMe3mGk/mqdefault.jpg">',
play = '<div class="play"><i class="fa fa-youtube-play" aria-hidden="true"></i></div>';
return thumb.replace("ID", id) + play;
}
function ytplayerIframe() {
var iframe = document.createElement("iframe");
var embed = "https://www.youtube.com/embed/0LRoDMe3mGk?autoplay=1";
iframe.setAttribute("src", embed.replace("ID", this.dataset.id));
iframe.setAttribute("frameborder", "0");
iframe.setAttribute("allowfullscreen", "1");
this.parentNode.replaceChild(iframe, this);
}
</script>
This is of course considering you already load Fontawesome for other purposes. If not you should adapt the play button the way it suits you.
Regards,

Related

Why does video return to blurry thumb at end?

I have rel=0 in my embed code so when the video ends it returns to the start. But it's displaying the thumbnail for the video, after returning, with the thumbnail blown up to the full video size, so the image is extremely blurry. How can I get the full 1280 x 720 image I uploaded for the thumb to be displayed?
Thanks
You could, for example, detect when the video has ended and then overlay the video with your image. For example:
HTML:
<script src="//www.youtube.com/iframe_api"></script>
<div id='yt_container'>
<iframe id='element_id' width="853" height="480" src="//www.youtube.com/embed/LqeN31x-5gE?autoplay=1&enablejsapi=1&rel=0&start=248" frameborder="0" allowfullscreen></iframe>
<!--Seems like people always forget to encode & as &-->
<!--The "start" parameter was added for easier testing-->
<!--The `enablejsapi=1` parameter is required for this to work. For more information, see https://developers.google.com/youtube/iframe_api_reference
<div id='player_overlay_image'> </div>
</div>
CSS:
iframe,img,div{/*If you use this on a real web page, you will want to make these rules more specific*/
padding:0;
margin:0
}
div#yt_container{
position:relative;/* https://stackoverflow.com/a/105035/1419007 */
}
div#player_overlay_image{/* The high-resolution image for when your video has ended. Includes a ▶ button. */
display:block;
position:absolute;
top: 29px;
background: url('//i.imgur.com/JhDUWdI.png');
width:853px;
height:408px;
display: none;
cursor:pointer;
}
div#player_overlay_image:hover{/* ▶ button in active state. */
background: url(//i.imgur.com/ljKjsD4.png);
}
JavaScript:
var yt_player;
function onYouTubeIframeAPIReady() {
yt_player = new YT.Player('element_id', {
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
if(event.data === YT.PlayerState.ENDED){
//Display overlay image
document.getElementById('player_overlay_image').style.display='block';
}
}
document.getElementById('player_overlay_image').addEventListener('click', function(evt){
//Hide overlay image
document.getElementById('player_overlay_image').style.display='none';
//Play video
yt_player.playVideo();
}, false);
(See the YouTube Player API Reference for iframe Embeds for more information.)
http://jsfiddle.net/y3Xqj/1/
I had the same problem and it didn't got solved by itself. This is how I solved the issue:
I used the youtube iframe api and rewinded the video to the start once the video ended, that way the thumbnail looks good as it was when the page loaded.
YoutubeF is the iframe id.
Code:
var YTplayer;
function onYouTubeIframeAPIReady()
{
YTplayer = new YT.Player('YoutubeF', { events: { 'onStateChange': onYTPlayerStateChange } });
}
function onYTPlayerStateChange(event)
{
if (event.data == 0)
{
YTplayer.seekTo(0, false)
}
}
Enjoy!

Can you hide the controls of a YouTube embed without enabling autoplay?

<iframe width="100%" height="100%" src="//www.youtube.com/embed/qUJYqhKZrwA?autoplay=1&showinfo=0&controls=0" frameborder="0" allowfullscreen>
If you remove ?autoplay=1 the video does not work. Looks like you cannot use the controls parameter without autoplay enabled.
Not sure why this is not mentioned in the YouTube embed writeup.
Hope I'm wrong.
https://developers.google.com/youtube/player_parameters#controls
Set autoplay=0
<iframe width="100%" height="100%" src="//www.youtube.com/embed/qUJYqhKZrwA?autoplay=0&showinfo=0&controls=0" frameborder="0" allowfullscreen>
As seen here: Autoplay=0 Test
To continue using the iframe YouTube, you should only have to change ?autoplay=1 to ?autoplay=0.
Another way to accomplish this would be by using the YouTube JavaScript Player API. (https://developers.google.com/youtube/js_api_reference)
Edit: the YouTube JavaScript Player API is no longer supported.
<div id="howToVideo"></div>
<script type="application/javascript">
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = false;
ga.src = 'http://www.youtube.com/player_api';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
var done = false;
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('howToVideo', {
height: '390',
width: '640',
videoId: 'qUJYqhKZrwA',
playerVars: {
controls: 0,
disablekb: 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(evt) {
console.log('onPlayerReady', evt);
}
function onPlayerStateChange(evt) {
console.log('onPlayerStateChange', evt);
if (evt.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
console.log('stopVideo');
player.stopVideo();
}
</script>
Here is a jsfiddle for the example: http://jsfiddle.net/fgkrj/
Note that player controls are disabled in the "playerVars" part of the player. The one sacrifice you make is that users are still able to pause the video by clicking on it. I would suggest writing a simple javascript function that subscribes to a stop event and calls player.playVideo().
use autoplay=0
autoplay takes 2 values.
Values: 0 or 1. Default is 0. Sets whether or not the initial video will autoplay when the player loads.
the important part
autoplay=0&showinfo=0&controls=0
Here is the demo for ur problem FIDDLE
?modestbranding=1&autohide=1&showinfo=0&controls=0
autohide=1
is something that I never found... but it was the key :) I hope it's help
If you add this ?showinfo=0&iv_load_policy=3&controls=0 before the end of your src, it will take out everything but the bottom right YouTube logo
working example: http://jsfiddle.net/42gxdf0f/1/
Follow this https://developers.google.com/youtube/player_parameters for more info about video controls like:
<iframe id="video_iframe" width="660" height="415" src="http://www.youtube.com/v/{{course_url}}?start=7&autoplay=0&showinfo=0&iv_load_policy=3&rel=0"
frameborder="0"
allowfullscreen></iframe>
start=7&autoplay=0&showinfo=0&iv_load_policy=3&rel=0"
frameborder="0"
all controls are described in there
To remove you tube controls and title you can do something like this
<iframe width="560" height="315" src="https://www.youtube.com/embed/zP0Wnb9RI9Q?autoplay=1&showinfo=0&controls=0" frameborder="0" allowfullscreen ></iframe>
code with output
showinfo=0 is used to remove title and &controls=0 is used for remove controls like volume,play,pause,expend.
You can hide the "Watch Later" Button by using "Youtube-nocookie" (this will not hide the share Button)
Adding controls=0 will also remove the video control bar at the bottom of the screen and using modestbranding=1 will remove the youtube logo at bottom right of the screen
However using them both doesn't works as expected (it only hides the video control bar)
<iframe width="100%" height="100%" src="https://www.youtube-nocookie.com/embed/fNb-DTEb43M?controls=0" frameborder="0" allowfullscreen></iframe>
Autoplay works only with /v/ instead of /embed/, so change the src to:
src="//www.youtube.com/v/qUJYqhKZrwA?autoplay=1&showinfo=0&controls=0"

Custom thumbnail or splash screen for embedded youtube video

Full Disclosure Confession: This is not a question, but a question with some answers.
I did not initially like the three choices of thumbnails that Youtube.com selected, so ...
Question: How do I display a custom thumbnail or splash screen for my embedded youtube video?
Answer #1: Accept Monetization option with Youtube.com and a button to create a custom thumbnail magically appears. NOTE: this was definitely NOT an acceptable option for me since my Youtube movie, entitled "My Love Song Forever", is a Love Song to my wife (whose lyrics I wrote and whose production I shared in). Have random ads appear together with my Love Song to my bride of over 51 years ... not a chance!!!
Answer #2: By pass such a requirement using css and frames:
var videoSrc = "http://www.youtube.com/embed/MxuIrIZbbu0";
var videoParms = "?autoplay=1&fs=1&hd=1&wmode=transparent";
// style of thumbNail's image must equal style of video for the 2 to overlap
var youtubeVideo = "" +
"<div>" +
"<iframe class='ls_video' src='" + videoSrc + videoParms + "'>" +
"</iframe>" +
"</div>";
var theThumbNail = "" +
"<div onclick=\"this.innerHTML = youtubeVideo;\">" +
"<img class='ls_video' src='images/MLSFthumbnail.jpg' style='cursor:pointer' alt='splash' \/> " +
"</div>";
document.write (theThumbNail);
I read somewhere that the thumbnail should spec at 1280px by 840px, so that is what I did.
IN THE INTEREST OF FULL DISCLOSURE, writing your own custom thumbnail THIS WAY will defeat the natural view counting that Youtube.com keeps track of. View counting will happen ONLY WHEN you go the monetization route.
THE CHOICE IS YOURS.
BOTTOM LINE ... I chose to be concerned about the View Count, so I regretfully chose one of the 3 thumbnail choices that Youtube.com offered;
See --- http://lovesongforever.com
Just copy and paste the code in an HTML file and enjoy the happy coding.
Using youtube api to manage the youtubed embedded video thumbnail.
<!DOCTYPE html>
<html>
<body>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script>
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: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
}
});
}
function onPlayerReady(event) {
$('#play_vid').click(function() {
event.target.playVideo();
});
}
$(document).ready(function() {
$('#player').hide();
$('#play_vid').click(function() {
$('#player').show();
$('#play_vid').hide();
});
});
</script>
<div id="player"></div>
<img id="play_vid" src="YOUR_IMAGE_PATH" />
</body>
</html>

Shrink a YouTube video to responsive width

I have a YouTube video embedded on our website and when I shrink the screen to tablet or phone sizes it stops shrinking at around 560px in width. Is this standard for YouTube videos or is there something that I can add to the code to make it go smaller?
You can make YouTube videos responsive with CSS. Wrap the iframe in a div with the class of "videowrapper" and apply the following styles:
.videowrapper {
float: none;
clear: both;
width: 100%;
position: relative;
padding-bottom: 56.25%;
padding-top: 25px;
height: 0;
}
.videowrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
The .videowrapper div should be inside a responsive element. The padding on the .videowrapper is necessary to keep the video from collapsing. You may have to tweak the numbers depending upon your layout.
If you are using Bootstrap you can also use a responsive embed. This will fully automate making the video(s) responsive.
http://getbootstrap.com/components/#responsive-embed
There's some example code below.
<!-- 16:9 aspect ratio -->
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="..."></iframe>
</div>
<!-- 4:3 aspect ratio -->
<div class="embed-responsive embed-responsive-4by3">
<iframe class="embed-responsive-item" src="..."></iframe>
</div>
Refined Javascript only solution for YouTube and Vimeo using jQuery.
// -- After the document is ready
$(function() {
// Find all YouTube and Vimeo videos
var $allVideos = $("iframe[src*='www.youtube.com'], iframe[src*='player.vimeo.com']");
// Figure out and save aspect ratio for each video
$allVideos.each(function() {
$(this)
.data('aspectRatio', this.height / this.width)
// and remove the hard coded width/height
.removeAttr('height')
.removeAttr('width');
});
// When the window is resized
$(window).resize(function() {
// Resize all videos according to their own aspect ratio
$allVideos.each(function() {
var $el = $(this);
// Get parent width of this video
var newWidth = $el.parent().width();
$el
.width(newWidth)
.height(newWidth * $el.data('aspectRatio'));
});
// Kick off one resize to fix all videos on page load
}).resize();
});
Simple to use with only embed:
<iframe width="16" height="9" src="https://www.youtube.com/embed/wH7k5CFp4hI" frameborder="0" allowfullscreen></iframe>
Or with responsive style framework like Bootstrap.
<div class="row">
<div class="col-sm-6">
Stroke Awareness
<div class="col-sm-6>
<iframe width="16" height="9" src="https://www.youtube.com/embed/wH7k5CFp4hI" frameborder="0" allowfullscreen></iframe>
</div>
</div>
Relies on width and height of iframe to preserve aspect ratio
Can use aspect ratio for width and height (width="16" height="9")
Waits until document is ready before resizing
Uses jQuery substring *= selector instead of start of string ^=
Gets reference width from video iframe parent instead of predefined element
Javascript solution
No CSS
No wrapper needed
Thanks to #Dampas for starting point.
https://stackoverflow.com/a/33354009/1011746
I used the CSS in the accepted answer here for my responsive YouTube videos - worked great right up until YouTube updated their system around the start of August 2015. The videos on YouTube are the same dimensions but for whatever reason the CSS in the accepted answer now letterboxes all our videos. Black bands across top and bottom.
I've tickered around with the sizes and settled on getting rid of the top padding and changing the bottom padding to 56.45%. Seems to look good.
.videowrapper {
position: relative;
padding-bottom: 56.45%;
height: 0;
}
#magi182's solution is solid, but it lacks the ability to set a maximum width. I think a maximum width of 640px is necessary because otherwhise the youtube thumbnail looks pixelated.
My solution with two wrappers works like a charm for me:
.videoWrapperOuter {
max-width:640px;
margin-left:auto;
margin-right:auto;
}
.videoWrapperInner {
float: none;
clear: both;
width: 100%;
position: relative;
padding-bottom: 50%;
padding-top: 25px;
height: 0;
}
.videoWrapperInner iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<div class="videoWrapperOuter">
<div class="videoWrapperInner">
<iframe src="//www.youtube.com/embed/C6-TWRn0k4I"
frameborder="0" allowfullscreen></iframe>
</div>
</div>
I also set the padding-bottom in the inner wrapper to 50 %, because with #magi182's 56 %, a black bar on top and bottom appeared.
Modern simple css solution
The new aspect-ratio is the modern solution to this problem.
aspect-ratio: 16 / 9;
That's all you need to make a div, image, iframe size automatically. Samples.
It's got good support, but is not yet in Safari (will be for upcoming iOS15) - so for now you'll still need to use a fallback. You can achieve that with the #supports feature
.element
{
aspect-ratio: 16 / 9;
#supports not (aspect-ratio: 16 / 9)
{
// take your pick from the other solutions on this page
}
}
Assuming your development browser does support this property be sure to test without it by commenting out both aspect-ratio and #supports.
This is old thread, but I have find new answer on https://css-tricks.com/NetMag/FluidWidthVideo/Article-FluidWidthVideo.php
The problem with previous solution is that you need to have special div around video code, which is not suitable for most uses. So here is JavaScript solution without special div.
// Find all YouTube videos - RESIZE YOUTUBE VIDEOS!!!
var $allVideos = $("iframe[src^='https://www.youtube.com']"),
// The element that is fluid width
$fluidEl = $("body");
// Figure out and save aspect ratio for each video
$allVideos.each(function() {
$(this)
.data('aspectRatio', this.height / this.width)
// and remove the hard coded width/height
.removeAttr('height')
.removeAttr('width');
});
// When the window is resized
$(window).resize(function() {
var newWidth = $fluidEl.width();
// Resize all videos according to their own aspect ratio
$allVideos.each(function() {
var $el = $(this);
$el
.width(newWidth)
.height(newWidth * $el.data('aspectRatio'));
});
// Kick off one resize to fix all videos on page load
}).resize();
// END RESIZE VIDEOS
If you are using Bootstrap 5.0, you can use .ratio
https://getbootstrap.com/docs/5.0/helpers/ratio/
Example
<div class="ratio ratio-16x9">
<iframe src="https://www.youtube.com/embed/zpOULjyy-n8?rel=0" title="YouTube video" allowfullscreen></iframe>
</div>
With credits to previous answer https://stackoverflow.com/a/36549068/7149454
Boostrap compatible, adust your container width (300px in this example) and you're good to go:
<div class="embed-responsive embed-responsive-16by9" style="height: 100 %; width: 300px; ">
<iframe class="embed-responsive-item" src="https://www.youtube.com/embed/LbLB0K-mXMU?start=1841" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0"></iframe>
</div>
Okay, looks like big solutions.
Why not to add width: 100%; directly in your iframe. ;)
So your code would looks something like <iframe style="width: 100%;" ...></iframe>
Try this it'll work as it worked in my case.
Enjoy! :)
I make this with simple css as follows
HTML CODE
<iframe id="vid" src="https://www.youtube.com/embed/RuD7Se9jMag" frameborder="0" allowfullscreen></iframe>
CSS CODE
<style type="text/css">
#vid {
max-width: 100%;
height: auto;
}

iframe prevents iScroll scrolling on mobile Safari

I am using iScroll on my mobile enable website (using iPhone here) to scroll inside a div.
In this this div, I have an iframe with a fixed height like this:
<body>
<div id="iscroller">
<iframe id="theIframe"></iframe>
Other stuff
</div>
</body>
Now, while scrolling within the div, everything works as expected but I cannot scroll when the scrolling gesture begins on the iframe.
The problem is described here pretty well: https://github.com/cubiq/iscroll/issues/41
So, I used the css workaround from that post by applying pointer-events:none to the iframe.
Now scrolling works perfectly but I cannot click any links which are defined within the iframe because all click/touch events on the iframe seems to be blocked due to pointer-events: none.
So, I thought:
"Ok, while the user scrolls, I need pointer-events:none. If he is
not scrolling (and instead clicking), I must set pointer-events:auto
in order to let the click/touch events pass."
So I did this:
CSS
#theIframe{pointer-events:none}
JavaScript
$("#theIframe").bind("touchstart", function(){
// Enable click before click is triggered
$(this).css("pointer-events", "auto");
});
$("#theIframe").bind("touchmove", function(){
// Disable click/touch events while scrolling
$(this).css("pointer-events", "none");
});
Even adding this doesn't work:
$("#theIframe").bind("touchend", function(){
// Re-enable click/touch events after releasing
$(this).css("pointer-events", "auto");
});
No matter what I do: Either scrolling doesn't work or clicking the link inside the iframe doesn't work.
Doesn't work. Any ideas?
I found the perfect solution. Works great on iOS and Android.
The basic idea is to put a div layer on top of that iframe. This way scrolling works smoothly.
If the user wants to tap/click on an element on that iframe I simply catch that click on the layer, save the x and y coordinates and trigger a click event on the iframe's content at these coordinates:
HTML:
<div id="wrapper">
<div id="layer"></div>
<iframe id="theIframe"></iframe>
</div>
Other stuff
CSS:
#layer{
position:absolute;
opacity:0;
width:100%;
height:100%;
top:0;
left:0;
right:0;
bottom:0;
z-index:2
}
JavaScript:
$('#layer').click(function(event){
var iframe = $('#theIframe').get(0);
var iframeDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
// Find click position (coordinates)
var x = event.offsetX;
var y = event.offsetY;
// Trigger click inside iframe
var link = iframeDoc.elementFromPoint(x, y);
var newEvent = iframeDoc.createEvent('HTMLEvents');
newEvent.initEvent('click', true, true);
link.dispatchEvent(newEvent);
});
I found a solution for this, it happens to be close to what other guys already mentioned on github but this may be useful for whoever wants to find a fast working resolution for this problem.
I'm assuming a few things, like there's only one iscroll container, here represented as ID. This is not properly tested and needs refactor. It's working in my project, but I changed it here slightly for the example but I guess you'll easily understand what you need to do:
var $iscroll = $('#iscroll');
document.addEventListener('touchstart', function(e) {
if ($iscroll.find('iframe').length > 0){
$.each($iscroll.find('iframe'), function(k,v){
var $parent = $(v).parent().first();
if ($parent.find('.preventTouch').length == 0){
$('<div class="preventTouch" style="position:absolute; z-index:2; width:100%; height:100%;"></div>')
.prependTo($parent);
};
$parent
.css('position', 'relative').css('z-index', 1);
});
$iscroll.find('.preventTouch').on('click', function(e){
e.preventDefault();
e.stopPropagation();
return false;
});
};
};
document.addEventListener('touchend', function(e) {
if ($iscroll.find('iframe').length > 0){
setTimeout(function(){
var $iscroll = $('#iscroll');
$iscroll.find('.preventTouch').remove();
$iscroll.find('iframe').css('z-index', '');
$iscroll.find('.preventTouch').off('click');
}, 400);
};
};
Thanks for looking!

Resources