Dimensões de vídeo HTML5

105

Estou tentando obter as dimensões de um vídeo que estou sobrepondo em uma página com JavaScript, no entanto, ele está retornando as dimensões da imagem do pôster em vez do vídeo real, pois parece que está sendo calculado antes de o vídeo ser carregado.

Elliot
fonte
Você desistiu? Existem boas pistas como respostas aqui!
Juan Mendes

Respostas:

105
<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

Especificação: https://html.spec.whatwg.org/multipage/embedded-content.html#the-video-element

Šime Vidas
fonte
Isso é possível com o formato ogg, pois não acho que o vídeo incluirá esses metadados?
Elliot
@Elliot Eu testei no Chrome nesta demonstração: people.opera.com/howcome/2007/video/controls.html e funciona ...
Šime Vidas
Parece que o link está quebrado novamente
Martin Delille
Desculpe, o link não foi quebrado de fato
Martin Delille
137

Deve-se notar que a solução atualmente aceita acima pela Sime Vidas não funciona realmente em navegadores modernos, uma vez que as propriedades videoWidth e videoHeight não são definidas até que o evento "carregadometadata" seja disparado.

Se acontecer de você consultar essas propriedades o suficiente após o elemento VIDEO ser renderizado, às vezes pode funcionar, mas na maioria dos casos, isso retornará valores 0 para ambas as propriedades.

Para garantir que você está obtendo os valores de propriedade corretos, você precisa fazer algo como:

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

NOTA: Não me preocupei em contabilizar as versões anteriores a 9 do Internet Explorer que usam attachEvent em vez de addEventListener, uma vez que as versões anteriores a 9 desse navegador não suportam vídeo HTML5, de qualquer maneira.

natlee75
fonte
Estou recebendo valores de 100 para largura e altura, e o vídeo não tem 100 px. Não sei por que ...
Mikel
2
Isso não funciona no Chrome para Android 49, infelizmente; somente quando o vídeo começa a ser reproduzido, as informações ficam disponíveis. Mais alguma informação sobre isso? PS1: Eu só tentei isso com URLs para arquivos locais selecionados usando um elemento de entrada do seletor de arquivo. PS2: funciona no iOS Safari.
Visionscaper
Eu criei esta questão no rastreador cromo bug: bugs.chromium.org/p/chromium/issues/detail?id=598218
Visionscaper
2
Isso não funcionará 100% das vezes. Em raras ocasiões, videoWidth e videoHeight serão zero quando loadedmetadatadisparados. Acabei de ver no Chromium 69. Ouvir loadeddataé uma aposta mais segura.
cleong
18

Função pronta para usar

Aqui está uma função pronta para usar que retorna as dimensões de um vídeo de forma assíncrona, sem alterar nada no documento .

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

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

		// place a listener on it
		video.addEventListener( "loadedmetadata", function () {
			// retrieve dimensions
			let height = this.videoHeight;
			let width = this.videoWidth;
			// send back result
			resolve({
				height : height,
				width : width
			});
		}, false );

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


// ---- Use ---- //
getVideoDimensionsOf("http://clips.vorwaerts-gmbh.de/VfE_html5.mp4")
   .then(({width, height}) => {
	console.log("Video width: " + width) ;
	console.log("Video height: " + height) ;
    });

Aqui está o vídeo usado para o trecho, se você quiser vê-lo: Big Buck Bunny

Yairopro
fonte
Excelente uso da promessa de fornecer dados de tag de vídeo de forma assíncrona, exatamente o que eu estava procurando, obrigado
Ray Andison
Ótimo código e tem suporte de navegador decente: No Chrome 32, Opera 19, Firefox 29, Safari 8 e Microsoft Edge, as promessas são ativadas por padrão.
Jeff Clayton
13

Ouça o loadedmetadataevento que é despachado quando o agente do usuário acaba de determinar a duração e as dimensões do recurso de mídia

Seção 4.7.10.16 Resumo do evento

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

videoTagRef.addEventListener('loadedmetadata', function(e){
    console.log(videoTagRef.videoWidth, videoTagRef.videoHeight);
});
Juan Mendes
fonte
Link correto: w3.org/TR/html5/...
Visionscaper
1
@Visionscaper Fixed, obrigado. Sinta-se à vontade para fazer pequenas alterações nas respostas de outras pessoas, quando elas não alterarem a intenção original.
Juan Mendes de
Donwvoter: Eu gostaria de uma explicação para que isso possa ser melhorado!
Juan Mendes de
1

É assim que pode ser feito no 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>
Ilyich
fonte
-1

Em Vuejs eu uso o seguinte código na tag montada.

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
    },
});
Aseem
fonte