HTML5 Video Dimensions
Asked Answered
C

7

135

I'm trying to get the dimensions of a video of which I'm overlaying onto a page with JavaScript, however it is returning the dimensions of the poster image instead of the actual video as it seems it's being calculated before the video is loaded.

Croaker answered 8/11, 2010 at 23:25 Comment(1)
Did you give up? There are good clues as answers here!Deductible
C
128
<video id="foo" src="foo.mp4"></video>

var vid = document.getElementById("foo");
vid.videoHeight; // returns the intrinsic height of the video
vid.videoWidth; // returns the intrinsic width of the video

Spec: https://html.spec.whatwg.org/multipage/embedded-content.html#the-video-element

Chemism answered 8/11, 2010 at 23:47 Comment(5)
Is this possible with the ogg format as I don't think the video will include such metadata?Croaker
@Croaker I tested in Chrome on this demo: people.opera.com/howcome/2007/video/controls.html and it works...Greeting
It seems the link is broken againCorduroys
Sorry the link is not broken in factCorduroys
always zero when playing a local file with URL.createObjectURL( file )Olivann
C
176

It should be noted that the currently accepted solution above by Sime Vidas doesn't actually work in modern browsers since the videoWidth and videoHeight properties aren't set until after the "loadedmetadata" event has fired.

If you happen to query for those properties far enough after the VIDEO element is rendered it may sometimes work, but in most cases this will return values of 0 for both properties.

To guarantee that you're getting the correct property values you need to do something along the lines of:

var v = document.getElementById("myVideo");
v.addEventListener( "loadedmetadata", function (e) {
    var width = this.videoWidth,
        height = this.videoHeight;
}, false );

NOTE: I didn't bother accounting for pre-9 versions of Internet Explorer which use attachEvent instead of addEventListener since pre-9 versions of that browser don't support HTML5 video, anyway.

Caen answered 17/2, 2012 at 18:12 Comment(4)
I am getting values of 100 for both width and height, and video doesn't have 100px. Not sure why...Wilbur
This doesn't work on Chrome for Android 49 unfortunately; only when the video has started playing the info becomes available. Any further insight on this? PS1: I only tried this with URLs to local files selected using an file selector input element. PS2 : it does work on iOS Safari.Arwood
I created this issue at the chromium bug tracker : bugs.chromium.org/p/chromium/issues/detail?id=598218Arwood
This won't work 100% of the times. On rare occasions videoWidth and videoHeight will be zero when loadedmetadata fires. I just saw it on Chromium 69. Listening for loadeddata is a safer bet.Tricot
C
128
<video id="foo" src="foo.mp4"></video>

var vid = document.getElementById("foo");
vid.videoHeight; // returns the intrinsic height of the video
vid.videoWidth; // returns the intrinsic width of the video

Spec: https://html.spec.whatwg.org/multipage/embedded-content.html#the-video-element

Chemism answered 8/11, 2010 at 23:47 Comment(5)
Is this possible with the ogg format as I don't think the video will include such metadata?Croaker
@Croaker I tested in Chrome on this demo: people.opera.com/howcome/2007/video/controls.html and it works...Greeting
It seems the link is broken againCorduroys
Sorry the link is not broken in factCorduroys
always zero when playing a local file with URL.createObjectURL( file )Olivann
O
40

Ready-to-use function

Here's a ready to use function which returns the dimensions of a video asynchrously, without changing anything in the document.

// ---- Definitions ----- //

/**
 Returns the dimensions of a video asynchrounsly.
 @param {String} url Url of the video to get dimensions from.
 @return {Promise<{width: number, height: number}>} Promise which returns the dimensions of the video in 'width' and 'height' properties.
 */
function getVideoDimensionsOf(url){
    return new Promise(resolve => {
        // create the video element
        const video = document.createElement('video');

        // place a listener on it
        video.addEventListener( "loadedmetadata", function () {
            // retrieve dimensions
            const height = this.videoHeight;
            const width = this.videoWidth;

            // send back result
            resolve({height, width});
        }, false);

        // start download meta-datas
        video.src = url;
    });
}


// ---- Use ---- //
getVideoDimensionsOf("https://www.w3schools.com/html/mov_bbb.mp4")
   .then(console.log);

Here's the video used for the snippet if you wish to see it : Big Buck Bunny

Outrageous answered 27/7, 2017 at 15:27 Comment(3)
Great use of a promise to deliver video tag data asynchronously, just what I was looking for thanksTolentino
Great code, and has decent browser support: As of Chrome 32, Opera 19, Firefox 29, Safari 8 & Microsoft Edge, promises are enabled by default.Merrick
Run this code snippet gives UndefinedAnnalee
D
15

Listen for the loadedmetadata event which is dispatched when the user agent has just determined the duration and dimensions of the media resource

Section 4.7.10.16 Event summary

https://www.w3.org/TR/html5/semantics-embedded-content.html#eventdef-media-loadedmetadata

videoTagRef.addEventListener('loadedmetadata', function(e){
    console.log(videoTagRef.videoWidth, videoTagRef.videoHeight);
});
Deductible answered 9/11, 2010 at 1:3 Comment(2)
Correct link : w3.org/TR/html5/…Arwood
@Arwood Fixed, thanks. Feel free to make small edits other's answers when they don't change the original intention.Deductible
U
3

This is how it can be done in Vue:

<template>
    <div>
        <video src="video.mp4" @loadedmetadata="getVideoDimensions"></video>
    </div>
</template>

<script>
export default {
    methods: {
        getVideoDimensions (e) {
            console.log(e.target.videoHeight)
            console.log(e.target.videoWidth)
        }
    }
}
</script>
Useless answered 15/10, 2019 at 14:56 Comment(0)
S
1

This should also be noted
that in some cases such as HLS streams the "onmetadataloaded" does not work either.
in those cases, this solution works perfect.

var video = document.getElementById("video")
video.onplaying = function () {
    var width = video.videoWidth
    var height = video.videoHeight
    console.log("video dimens loaded w="+width+" h="+height)
}
Steffens answered 23/1, 2022 at 7:39 Comment(0)
P
-1

In Vuejs I use following code in mounted tag.

var app = new Vue({
    el: '#id_homepage',
    mounted: function () {
        var v = document.getElementById("id_video");
        var width = v.offsetWidth;
        v.height = Math.floor(width*(9/16)); // dynamically setting video height to maintain aspect ratio
    },
});
Phoenician answered 26/9, 2019 at 6:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.