Lots of words here, so TL;DR I'm looking for a way to get the width and height of any given YouTube video.
I'm having the absolute hardest time getting correct video resolutions/aspect ratios from YouTube videos using the YouTube API. Long story short, I need a user-selected video to fill a container completely for use as a background video that content will be hovering over--in order to do this while losing the least amount of the video to overflow, I need to know the dimensions of the video so I can scale it up and center is properly.
I have fiddled with the OAuth Playground plenty (you'll probably also want to look at the YouTube Data API), but can't seem to find anything that actually gives me the dimensions of the video. The closest thing that I can find which is correct for SOME videos, but not all, is doing a GET with https://www.googleapis.com/youtube/v3/videos?part=player&id=XJK_uVyTBHc . part=player spits back with lots of stuff I don't want, plus some HTML for the embeded iframe video. The iframe tag contains a width and height, but these are not always correct.
For example, the video with ID XJK_uVyTBHc returns an iframe with width="480" and height="360", but when viewing on YouTube it shows my Viewport as 406x722px with the current and optimal resolution as 608x1080px, which are roughly the same aspect ratio (right click video, choose stats for nerds to see this). I haven't done very extensive testing, but can confirm that at the very least videos with 1920x1080px resolutions DO come back with an iframe tag that has the correct aspect ratio on the width and height attributes. I assume this is due to minimum heights and widths necessary for the YouTube controls to fit inside the video, but that doesn't help with my problem! :[
So, here we are in 2019... Is there still no good way to fetch the width and height of a YouTube video with a simple API call? Have I overlooked a particular API operation somewhere? Any help or additional resources would be greatly appreciated!
If you see the source code of the video you provided - videoId: XJK_uVyTBHc:
view-source:https://www.youtube.com/watch?v=XJK_uVyTBHc
You'll see a segment of code like this:
fmt_list":"22\/406x720...
I think this is value you're looking for. As you mentioned, the API returns the iframe and those values aren't the same as shown in the YouTube website.
Making more tests, I just selected a few random videos and get the iframe "with the settings offered by YouTube" - "by clicking the (share) button > insert video":
Microsoft Windows Mixed Reality update | October 2018:
<iframe width="560" height="315" src="https://www.youtube.com/embed/00vnln25HBg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Test Video Please Ignore - this is your sample video:
<iframe width="560" height="315" src="https://www.youtube.com/embed/XJK_uVyTBHc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
The Rasmus - In the Shadows [Crow Version] (Official Video):
<iframe width="560" height="315" src="https://www.youtube.com/embed/7gwO8-oqwFw" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Super Street Fighter IV Hakan Trailer:
<iframe width="560" height="315" src="https://www.youtube.com/embed/m6uxFzaB4sE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
lofi hip hop radio - beats to relax/study to:
<iframe width="560" height="315" src="https://www.youtube.com/embed/hHW1oY26kxQ" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
All previous iframes have the same width and height: width="560" and height="315".
I used Google API Explorer for create a demo with the videoIds from the above iframes for retrieve these results:
{
"items": [
{
"snippet": {
"title": "Microsoft Windows Mixed Reality update | October 2018"
},
"contentDetails": {
"dimension": "2d"
},
"player": {
"embedHtml": "<iframe width=\"480\" height=\"270\" src=\"//www.youtube.com/embed/00vnln25HBg\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
}
},
{
"snippet": {
"title": "Test Video Please Ignore"
},
"contentDetails": {
"dimension": "2d"
},
"player": {
"embedHtml": "<iframe width=\"480\" height=\"360\" src=\"//www.youtube.com/embed/XJK_uVyTBHc\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
}
},
{
"snippet": {
"title": "The Rasmus - In the Shadows [Crow Version] (Official Video)"
},
"contentDetails": {
"dimension": "2d"
},
"player": {
"embedHtml": "<iframe width=\"480\" height=\"360\" src=\"//www.youtube.com/embed/7gwO8-oqwFw\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
}
},
{
"snippet": {
"title": "Super Street Fighter IV Hakan Trailer"
},
"contentDetails": {
"dimension": "2d"
},
"player": {
"embedHtml": "<iframe width=\"480\" height=\"270\" src=\"//www.youtube.com/embed/m6uxFzaB4sE\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
}
},
{
"snippet": {
"title": "lofi hip hop radio - beats to relax/study to"
},
"contentDetails": {
"dimension": "2d"
},
"player": {
"embedHtml": "<iframe width=\"480\" height=\"270\" src=\"//www.youtube.com/embed/hHW1oY26kxQ\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>"
}
}
]
}
All previous results from the YouTube Data API vary its width and height values as follows:
width="480" and height="270".
width="480" and height="360".
Same results are available in this "try-it" demo I prepared for you.
I noticed also that "embedWidth" and "embedHeight" aren't returned - maybe such fields are deprecated, but I couldn't find any documentation about it.
Unfortunately, YouTube Data API is kind of limited for certain tasks - like this one.
Edit (26/10/2019): Thanks to mtkopone's comment:
embedWidth or embedHeight is returned if you specify maxWidth or
maxHeight as a query parameter to the videos:list request.
Related
It's taken me months to figure out how to show/hide certain content by days throughout the year, but now I'm stuck because the code gets too big for any browser to handle once I add every day for the entire year within the script.
Is there a way I can simply substitute each video's code for that day within just one embedded element? Trying to embed and then hide 371 videos is just too much.
The URL strings I'd need to swap out each day look like this:
5BZsAW78ch8
jEyvsHcQcLw
fBHx90y2QFo
_JMkjM4THd4
v2kh3s8RgYw
uhrrTXo1uRo
And the iframe code is like this:
<iframe width="560" height="315" src="https://www.youtube.com/embed/v2kh3s8RgYw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
The working code (for just 3 days) is as follows:
<script src="http://code.jquery.com/jquery-1.12.0.js"></script>
<div align="center" style="margin:50px;">
<div class="show"></div>
<div class="vid5"><iframe width="560" height="315" src="https://www.youtube.com/embed/v2kh3s8RgYw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
<div class="vid6"><iframe width="560" height="315" src="https://www.youtube.com/embed/uhrrTXo1uRo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
<div class="vid7"><iframe width="560" height="315" src="https://www.youtube.com/embed/" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div>
<script>
function show_hide_me () {
var myDate = new Date();
var hour = myDate.getHours();
var date = myDate.getDate();
var month = myDate.getMonth();
var minute = myDate.getMinutes()
if (month == 8 && date > 0 && date < 2){$('.vid5').show();$('.show').hide();} else {$('.vid5').hide();$('.show').show();}
if (month == 8 && date > 1 && date < 3){$('.vid6').show();$('.show').hide();} else {$('.vid6').hide();$('.show').show();}
if (month == 8 && date > 2 && date < 4){$('.vid7').show();$('.show').hide();} else {$('.vid7').hide();$('.show').show();}
}
show_hide_me();
</script>
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
var iframe_template = '<iframe width="560" height="315" src="https://www.youtube.com/embed/{0}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>';
// Set one video "case" for all days, for this you'll have to add 366 video_ids/cases...
switch (day) {
case 1:
document.getElementById("myDiv").innerHTML = iframe_template.replace("{0}", "5BZsAW78ch8");
break;
case 2:
document.getElementById("myDiv").innerHTML = iframe_template.replace("{0}", "jEyvsHcQcLw");
break;
case 3:
document.getElementById("myDiv").innerHTML = iframe_template.replace("{0}", "fBHx90y2QFo");
break;
// And so on...
default:
// You should have a default video - just in case:
var default_video_id = "ouf0ozwnU84";
document.getElementById("myDiv").innerHTML = iframe_template.replace("{0}", default_video_id);
break;
}
<div class="myDiv"></div>
You could modify your code in order to keep all video_ids ready for set once the day of the year is met with a condition.
I show here a brief xample, but, you have to modify your current code and set an ID to one of your divs that will contain the iframe, in this case, I'm using "myDiv" as ID.
Example:
<div id="myDiv"></div>
Credit: Answer to: "JavaScript calculate the day of the year (1 - 366)"
Modified code (please note, this is just how I would do it):
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
var iframe_template = '<iframe width="560" height="315" src="https://www.youtube.com/embed/{0}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>';
// Set one video "case" for all days, for this you'll have to add 366 video_ids/cases...
switch (day) {
case 1:
document.getElementById("myDiv").innerHTML = iframe_template.replace("{0}", "5BZsAW78ch8");
break;
case 2:
document.getElementById("myDiv").innerHTML = iframe_template.replace("{0}", "jEyvsHcQcLw");
break;
case 3:
document.getElementById("myDiv").innerHTML = iframe_template.replace("{0}", "fBHx90y2QFo");
break;
// And so on...
default:
// You should have a default video - just in case:
var default_video_id = "ouf0ozwnU84";
document.getElementById("myDiv").innerHTML = iframe_template.replace("{0}", default_video_id);
break;
}
Side note: It's up to you, but, I would consider a server-side operation that returns the video_id for the day and not keep all your videos_id hard-coded.
I have embedded videos from youtube, rightdisplay div shows the images of the videos. my code is playing video after clicking only first image. i want to know if i click on any image, the video should be played in the rightdisplay div. if i click on second or other images the video is not played.
$API_key = '';
$maxResults = 10;
$api_url = 'https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&q='.urlencode($query).'&maxResults='.$maxResults.'&key='.$API_key.'';
$videoList=json_decode(file_get_contents($api_url, true));
echo "<div class='left-display'>";
//$videodata = $videoList->items[0]->snippet->videoId;
echo '<iframe id="play-video" width="560" height="315" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>';
//echo "<br>";
//$videotitle = $videoList->items[0]->snippet->title;
//echo $videotitle;
echo "</div>";
echo "<div class='right-display'>";
echo "<h4>Up Next</h4>";
foreach($videoList->items as $item)
{
if(isset($item->id->videoId))
{
echo '<div class="youtube-video">
<div class="display">
<img id="image" width="240" height="150" src="https://i.ytimg.com/vi/'.$item->id->videoId.'/default.jpg" data="https://www.youtube.com/embed/'.$item->id->videoId.'">
<p>'. $item->snippet->title .'</p>
</div>
</div>';
}
}
echo "</div>";
?>
<script type="text/javascript">
$('#image').click(function()
{
var value = $("#image").attr("data");
$('#play-video').attr("src", value);
});
</script>
IDs have to be unique. You have multiple elements with ID image. Selecting #image gives you only the first because non-unique IDs aren't even valid. Use classes instead.
Also, in your click handler, you are yet again referring to a selector, so the attribute you get will be from the first element matching the selector and not from the one actually clicked. Use this instead.
So, to fix your issues, change id="image" to class="image" and change the Javascript code as explained:
$('.image').click(function() {
const value = $(this).attr('data')
$('#play-video').attr('src', value)
})
The 1 and 3 are id of button and v1 and v3 are id of iframe(youtube emmbedded).
i have already used a simple .show() and .hide() but the audio remained of hidden iframe so i am using .remove() and .show().
when i use .remove() the other iframe is gone completely and only iframe remains is of that button which i pressed which i want.
however when i press button 3 the removed iframe is not able to load, is there a way to reload it?
the iframes i am using are :-
<iframe width="560" height="315" id="v1" src="https://www.youtube.com/embed/xGRjCa49C6U?modestbranding=1&controls=0&autoplay=1&loop=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" ></iframe>
<iframe width="560" height="315" id="v3" src="https://www.youtube.com/embed/9V9wr1AaIxY?modestbranding=1&controls=0&autoplay=1&loop=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" ></iframe>
and this is the js:-
$(function(){
$('#1').on('click',function(){
$('#v1').show();
var getframe = document.getElementById("v3");
getframe.remove();
});
$('#3').on('click',function(){
$('#v3').show();
var getframe = document.getElementById("v1");
getframe.remove();
});
});
Remove() method removes the element from the dom and its hard to reload.
So this can be done like the following.
Load YouTube iFrame API:-
<script src="https://www.youtube.com/iframe_api"></script>
Create two different players that references the existing iFrames
$(function(){
window.YT.ready(function() {
var player1 = new YT.Player('v1');
var player3 = new YT.Player('v3');
$('#1').on('click',function(){
$('#v1').show();
player1.unMute();
$('#v3').hide();
player3.mute();
});
$('#3').on('click',function(){
$('#v3').show();
player3.unMute();
$('#v1').hide();
player1.mute();
});
});
});
Demo
Hope this helps
I have this simple html with a video div and a button:
<div class = "video-row">
<iframe width="560" height="315" src="https://www.youtube.com/embed/QmHCn5xXHjI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<div class="add-button green-button light-button">Add video</div>
</div>
I want to send a data the video's src to a java servlet on button click:
$(document).on("click", ".add-button", function () {
sendData();
});
var sendData = function() {
$.ajax({
url: "addcomedian",
type: "post", //send it through get method
data: {
number: 4,
sender: "add-button",
url: url,
},
success:
...
}
How do I get the url of the video which is the value of src tag? There would be many videos like that on a page and an add button for each video.
Find the clicked element parent, then find the iframe child:
$(document).on("click", ".add-button", function (event) {
var button = $(event.target); // Find the button that was clicked
// Find the video element, first finding the parent
var videoElement = button.parents(".video-row").find("iframe");
console.log(videoElement.attr("src")); // get the 'src' attribute
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class = "video-row">
<iframe width="160" height="90" src="https://www.youtube.com/embed/QmHCn5xXHjI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<div class="add-button green-button light-button">Add video</div>
</div>
I am trying to change a YouTube video iframe source with jQuery, but looks like running into cross origin issue. My jquery code:
var videourl = $(".videourl").html();
$(".actualyoutube iframe").attr('src',videourl);
iframe gets new src value, but no video is displayed. Any ideas?
extended explanation:
There is a popup div with embeded youtube video
<div class="youtubepopup">
<div class="closeyoutube">X</div>
<div class="actualyoutube">
<iframe width="420" height="315" src="" frameborder="0" allowfullscreen></iframe>
</div>
</div>
There is a certain td which contains a new src url. There is no other place or way to get this url except from this td.
<td class="videourl">//youtube.com/whatevervideo</td>
And there is a script that should add src on open popup and remove on closing.
var videourl = $(".videourl").html();
$(".youtubecap").click(function() {
$(".actualyoutube iframe").attr('src', videourl);
$(".youtubepopup").fadeIn('slow');
});
$(".closeyoutube").click(function() {
$(".youtubepopup").fadeOut('slow');
$(".actualyoutube iframe").removeAttr('src');
});
$(".youtubepopup").click(function() {
$(".youtubepopup").fadeOut('slow');
});
p.s. now that i laid it out, user3385530 is probably right
You cannot show pages from www.youtube.com inside an iframe. The correct way is to use their video embed codes inside your web page. IFrame embeds are easier, the URL you need to display in an iframe looks like this:
http://www.youtube.com/embed/VIDEO_ID_GOES_HERE
Just place an iframe such as this inside your web page:
<div class="actualyoutube">
<iframe width="560" height="315" src="http://www.youtube.com/embed/VIDEO_ID_GOES_HERE" frameborder="0" allowfullscreen></iframe>
</div>
Finally, assuming you are able to extract video id from the URLs using jQuery, you can use this to display videos*:
var videoid = "S2ISrpNM-0s";
$(".actualyoutube iframe").remove();
$('<iframe width="420" height="315" frameborder="0" allowfullscreen></iframe>')
.attr("src", "http://www.youtube.com/embed/" + videoid)
.appendTo(".actualyoutube");
* Changing the src property of an iframe that is already displaying a YouTube video did not work; I therefore suggest destroy-iframe-recreate-iframe approach.
<div class="service-video-media">
<iframe id="main-play" width="560" height="315" src="https://www.youtube.com/embed/uTcj2v85y34" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<div class="video-list">
<img src="https://img.youtube.com/vi/uTcj2v85y34/1.jpg" video-id="uTcj2v85y34" />
<img src="https://img.youtube.com/vi/jRuR4GaSsBI/1.jpg" video-id="jRuR4GaSsBI" />
<img src="https://img.youtube.com/vi/ec7aQPLSBsU/1.jpg" video-id="ec7aQPLSBsU" />
<img src="https://img.youtube.com/vi/uTcj2v85y34/1.jpg" video-id="uTcj2v85y34" />
<img src="https://img.youtube.com/vi/jRuR4GaSsBI/1.jpg" video-id="jRuR4GaSsBI" />
<img src="https://img.youtube.com/vi/ec7aQPLSBsU/1.jpg" video-id="ec7aQPLSBsU" />
</div>
</div>
<script>
jQuery(document).ready(function(){
jQuery('.video-list img').on('click',function () {
var videoId = jQuery(this).attr('video-id');
var videoUrl = 'https://www.youtube.com/embed/'+videoId;
jQuery('#main-play').attr('src',videoUrl);
});
});
</script>
This will not work because page is parsed and only on refresh with new ulr will happen.
You need to use ajax to pre-load the page with new url and then to set iframe.