jQuery - Get height of video before it finishes loading - javascript

I have an 8MB video set to "object-fit:contain" and need to retrieve its height before it finishes loading on mobile devices. Reason I need the height earlier is to position content overlaying the video by matching the video height on this content container.
I am not looking for the actual height of the video, but the height as rendered in the user's browser / viewport.
If I try to get the height while it's loading, I get a much smaller value (200 some pixels) than what it ends up being (usually 600 some pixels). I've been able to get the height AFTER it loads using the load() function, but this method is very slow because my video is 8MB in size.
Is there any workaround?
jQuery(document).ready(function($){
function vidHeight() {
var newHeight = jQuery('#section-feature-device video').height();
jQuery(".elementor-element-0113321").css("height", newHeight+"px");
}
jQuery(window).load(function () {
var win = jQuery(this);
if (win.width() <= 767) {
vidHeight();
}
});
});

If you are planing to get the intrinsic height of the video, you may use the event listener loadedmetadata.
document.getElementById('video').addEventListener('loadedmetadata', (e) => console.info(e.target.videoHeight));
<video controls="true" poster="" id="video">
<source type="video/mp4" src="http://www.w3schools.com/html/mov_bbb.mp4">
</video>

I found how to find the video height by knowing the video width was 100%, therefore I just multiply the viewport width by the aspect ratio of the video.
jQuery(document).ready(function($){
function vidHeight() {
var viewportWidth = jQuery(window).width();
var videoHeight = viewportWidth * 0.5625;
jQuery("#section-feature").css("height", videoHeight+"px");
//console.log("Video height is "+videoHeight)
}
vidHeight();
jQuery(window).on('resize', vidHeight);
});

Related

Why window.innerWidth is wrong?

I'm trying to make a canvas JavaScript game, so i added this in code
window.addEventListener("resize", () => {
console.log("resi2ze");
canvasElement.width = window.innerWidth;
canvasElement.height = window.innerHeight;
});
But when I resize browser window, canvas height is bigger than body height
(for example, body height is 465px, and canvas height is 462px). How can I prevent it, so canvas height would be same as window height?
Seems like the scrollbar itself is an issue, because it adds few pixels.
I always add overflow: hidden to body so scrollbar doesn't show up.

Get Width and Height of HTML5 Video using JavaScript?

I've tried several answers found here.
This code works in Firefox and outputs the right size, but not in Chrome or IE.
Mainly I am trying to get just the width.
Example
I have the output the width under the video using 3 examples.
https://jsfiddle.net/a8a1o8k2/
JavaScript
https://stackoverflow.com/a/4129189/6806643
var vid1 = document.getElementById("video");
vid1.videoHeight; // returns the intrinsic height of the video
vid1.videoWidth; // returns the intrinsic width of the video
returns 0
https://stackoverflow.com/a/9333276/6806643
var vid2 = document.getElementById("video");
vid2.addEventListener( "loadedmetadata", function (e) {
var width = this.videoWidth,
height = this.videoHeight;
}, false );
returns 0
https://stackoverflow.com/a/16461041/6806643
var vid3 = document.getElementById("video");
var videotag_width = vid3.offsetWidth;
var videotag_height = vid3.offsetHeight;
sometimes returns the correct value
sometimes returns 300 (default player size if no video source)
Edit: improved solution after I have actually read the crossbrowser issue.
The solution below should work on both Chrome and Firefox. The issue is that Firefox treats readyState differently than Chrome.
var vid2 = document.getElementById("video");
vid2.addEventListener("loadedmetadata", getmetadata);
if (vid2.readyState >= 2) {
getmetadata(vid2);
}
function getmetadata(){
document.getElementById('output2').innerHTML = "Test 2: " + vid2.videoWidth;
}
Updated JSFiddle
If you are trying to define the size of your video with java script im not sure what you are actually trying to do, althought it seems to me like you just want it to be customizable like this example.
If we presume the video was embedded the code below might do the trick
// Find all YouTube videos
var $allVideos = $("iframe[src^='//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();
You can also refer to this page how it actually works and there is also an CSS and HTML example of dynamic video rescaling as well:
https://css-tricks.com/NetMag/FluidWidthVideo/Article-FluidWidthVideo.php

Get dimensions of HTML5 video (playing region - not division) during playback

I have a HTML video in a division. When the user changes the size of the HTML window the playing area of the video changes to maintain its aspect ratio leaving boarders around the video (depending on how the window is resized).
Is there a way of obtaining the dimensions of the actual playback region of the video within a division (not the division itself).
I've tried:
console.log($("#video").css("height"));
Where #video is the id of the video itself, but it seems to return the division height, not the video playback area.
This needs to happen within a window resize event handler:
$( window ).resize(function() {
//Detect playback window size
}
My solution was to get the original video size (see HTML5 Video Dimensions) and then compute the height and width based on the original aspect ratio.
The problem, as explained in that page, is that those dimensions are only retrieved after loading the metadata (which in my test page happened only after playing the video). The way to make the video load the metadata is to use the preload="metadata" attribute on the video tag.
The rest is just combining these:
var aspectratio=1;
resizeHandler();
$("video").on('loadedmetadata',function() {
var width = this.videoWidth;
var height = this.videoHeight;
aspectratio=width/height;
resizeHandler();
});
function dis(v) { return Math.round(v*100)/100; }
function resizeHandler() {
var height=$('video').height();
var width=$('video').width();
var actualHeight=Math.min(height,width/aspectratio);
var actualWidth=Math.min(width,height*aspectratio);
$('#spnInfo').text('ratio: '+dis(aspectratio)+' width: '+dis(width)+', height:'+dis(height)+' ,actual width: '+dis(actualWidth)+', actual height:'+dis(actualHeight));
}
$(window).resize(resizeHandler);
$('#btnResize').click(function() {
$('video').css({height:Math.random()*600+50,width:Math.random()*600+50});
$(window).trigger('resize');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" id="btnResize" value="Resize" /><span id="spnInfo"></span><br/>
<video poster="http://corrupt-system.de/assets/media/sintel/sintel-trailer.jpg" controls=""
preload="metadata" style="width:200px; height:500px">
<source src="http://corrupt-system.de/assets/media/sintel/sintel-trailer.m4v" type="video/mp4">
<source src="http://corrupt-system.de/assets/media/sintel/sintel-trailer.webm" type="video/webm">
</video>

change src in iframe which depend on viewport size

I'm quite new in website area
I'm trying to change src in my iframe which the src content is a table along with the width and height which make it not responsive
I'm trying to change the src which depend on the size of the viewport
here is my code
<iframe width="100%" height="410" scrolling="yes" frameborder="0" scrolling="no" allowtransparency="true" src="http://tools.fxempire.com/sidebar-quotes.php?instruments=5,10,1,2,4,3&width=375&height=410&text_color=333&text_hover_color=082F60"></iframe>
<div id="fxempire_link" style="width:500px;font-size: 11px;">
The Free Charts are Powered by <a rel="nofollow" style="text-decoration: underline;" target="_blank" href="http://www.fxempire.com">FXEmpire.com</a> - Your Leading Financial Portal</div>
I'm trying to change the following width inside the src automatically
src="http://tools.fxempire.com/sidebar-quotes.php?instruments=5,10,1,2,4,3&width=375&height=410&text_color=333&text_hover_color=082F60"
but i don't get any idea to do it
is there a way to do it??what I found in internet is all using either link or button to change the src
well because of the Access-Control-Allow-Origin you can not do it with ajax, you could do it with php, but i dont know legal/illegal this would be.
By using iframe it works this way, but only really sluggish cause the iframe needs a lot time to load...:
$(window).bind('load resize',function(){
var windowH = $(window).height(),
windowW = $(window).width();
$('#iframe').attr('src','//tools.fxempire.com/sidebar-quotes.php?instruments=5,10,1,2,4,3&width='+windowW+'&height='+windowH+'&text_color=333&text_hover_color=082F60');
$('#iframe').css({'height':windowH+'px', 'width':windowW+'px'});
})
http://jsfiddle.net/ebjsd8xx/3/
EDIT:
I changed the code a little bit for better performance but, well - the graph still loads freaking slow, but it's the same on their preview..
var resizeTimer;
$(window).load(function(){
$(window).trigger('resize');
});
$(window).resize(function(e){
var windowH = $(window).height(),
windowW = $(window).width();
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
$('#iframe').attr('src','http://tools.fxempire.com/sidebar- quotes.php?instruments=5,10,1,2,4,3&width='+windowW+'&height='+windowH+'&text_color=333&text_hover_color=082F60');
$('#iframe').css({'height':windowH+'px', 'width':windowW+'px'});
}, 250);
})
http://jsfiddle.net/ebjsd8xx/7/
Maybe like this?
jQuery(document).ready(function(){
var iframe=jQuery('iframe'),/** target iFrame */
src=iframe.attr('src'); /** src of iFrame */
/** check viewport size */
if (window.innerWidth<945){
/** remove width value from src */
src=src.replace(/(&width=[0-9]+)/,'');
/** add new width */
src+='&width=275';
/** PROFIT */
iframe.attr('src',src);
}
});
On jsfiddle
For me the simplest way to select a src given the viewport size was with a small script, where your iframe has the id="vid"
<script>
var w = window.matchMedia("(max-width: 700px)");
var vid = document.getElementById("vid");
if (w.matches) {
vid.src = "media/test_1.mp4";
} else {
vid.src = "media/test_2.mp4";
}
</script>
That will pick the source when you load the page the first time, but wouldn't change it if you resize the viewport later, foor that you need to listen to resize event (this might help).

How do I get the new dimensions of an element *after* it resizes due to a screen orientation change?

I'm working on a mobile web app, and in my page I have a div element with its width set to 100%.
I need to set the height of this div so that the height is correct for a set aspect ratio. So for example, if the screen was sized to 300 pixels wide and the ratio was 3:2, my script should grab the width of the div (which at this point should be 300px) and set the height to 200px.
On first load, this works perfectly. However, if I rotate the screen of my phone to landscape, the width of the div obviously changes, so I need to reset its height in order to keep the correct ratio.
My problem is that I can't find an event which fires after the elements are resized. There is an orientationchange event built into jQuery Mobile, which helpfully fires when the screen is rotated from portrait to landscape and vice-versa:
$(window).bind('orientationchange', function (e) {
// Correctly alerts 'landscape' or 'portrait' when orientation is changed
alert(e.orientation);
// Set height of div
var div = $('#div');
var width = div.width();
// Shows the *old* width, i.e the div's width before the rotation
alert(width);
// Set the height of the div (wrongly, because width is incorrect at this stage)
div.css({ height: Math.ceil(width / ratio) });
});
But this event seems to fire before any of the elements in the page have resized to fit the new layout, which means (as mentioned in the comments) I can only get the pre-rotation width of the div, which is not what I need.
Does anyone know how I can get the div's new width, after things have resized themselves?
A few methods for you to try:
(1) Set a timeout inside your orientationchange event handler so the DOM can update itself and the browser can draw all the changes before you poll for the new dimension:
$(window).bind('orientationchange', function (e) {
setTimeout(function () {
// Get height of div
var div = $('#div'),
width = div.width();
// Set the height of the div
div.css({ height: Math.ceil(width / ratio) });
}, 500);
});
It won't make too big of a difference but note that Math.ceil takes a lot longer to complete (relatively) than Math.floor since the latter only has to drop everything after the decimal point. I generally just pass the browser the un-touched float number and let it round where it wants to.
(2) Use the window.resize event instead to see if that updated fast enough for you:
$(window).bind('resize', function (e) {
// Get height of div
var div = $('#div'),
width = div.width();
// Set the height of the div
div.css({ height: Math.ceil(width / ratio) });
});
On a mobile device this will fire when the orientation changes since the size of the browser view-port will also change.
(3) If you are updating the size of this <div> element because it holds an image, just apply some CSS to the image to make it always be full-width and the correct aspect ratio:
.my-image-class {
width : 100%;
height : auto;
}

Categories