Dimensiones de video HTML5

105

Estoy tratando de obtener las dimensiones de un video que estoy superponiendo en una página con JavaScript, sin embargo, está devolviendo las dimensiones de la imagen del póster en lugar del video real, ya que parece que se está calculando antes de que se cargue el video.

Elliot
fuente
¿Te rendiste? ¡Aquí hay buenas pistas como respuestas!
Juan Mendes

Respuestas:

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

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

Šime Vidas
fuente
¿Es esto posible con el formato ogg ya que no creo que el video incluya tales metadatos?
Elliot
@Elliot Probé en Chrome en esta demostración: people.opera.com/howcome/2007/video/controls.html y funciona ...
Šime Vidas
Parece que el vínculo se ha roto de nuevo
Martin Delille
Lo siento, el enlace no está roto de hecho
Martin Delille
137

Cabe señalar que la solución actualmente aceptada por Sime Vidas no funciona en los navegadores modernos, ya que las propiedades videoWidth y videoHeight no se establecen hasta después de que se activa el evento "loadedmetadata ".

Si consulta esas propiedades lo suficientemente lejos después de renderizar el elemento VIDEO, a veces puede funcionar, pero en la mayoría de los casos esto devolverá valores de 0 para ambas propiedades.

Para garantizar que está obteniendo los valores de propiedad correctos, debe hacer algo como:

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

NOTA: No me molesté en tener en cuenta las versiones anteriores a la 9 de Internet Explorer que usan attachEvent en lugar de addEventListener, ya que las versiones anteriores a la 9 de ese navegador no admiten video HTML5, de todos modos.

natlee75
fuente
Obtengo valores de 100 tanto para el ancho como para el alto, y el video no tiene 100 px. No estoy seguro de por qué ...
Mikel
2
Desafortunadamente, esto no funciona en Chrome para Android 49; solo cuando el video ha comenzado a reproducirse, la información estará disponible. ¿Alguna idea adicional sobre esto? PS1: Solo probé esto con URL a archivos locales seleccionados usando un elemento de entrada de selector de archivos. PS2: funciona en iOS Safari.
Visionscaper
Creé
Visionscaper
2
Esto no funcionará el 100% de las veces. En raras ocasiones, videoWidth y videoHeight serán cero cuando se loadedmetadatadispara. Lo acabo de ver en Chromium 69. Escuchandoloadeddata es una apuesta más segura.
Cleong
18

Función lista para usar

Aquí hay una función lista para usar que devuelve las dimensiones de un video de forma asincrónica, sin cambiar nada en el 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) ;
    });

Aquí está el video utilizado para el fragmento si desea verlo: Big Buck Bunny

Yairopro
fuente
Excelente uso de la promesa de entregar datos de etiquetas de video de forma asincrónica, justo lo que estaba buscando gracias
Ray Andison
Excelente código y soporte de navegador decente: a partir de Chrome 32, Opera 19, Firefox 29, Safari 8 y Microsoft Edge, las promesas están habilitadas de forma predeterminada.
Jeff Clayton
13

Escuche el loadedmetadata evento que se envía cuando el agente de usuario acaba de determinar la duración y las dimensiones del recurso de medios

Sección 4.7.10.16 Resumen de eventos

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
fuente
Enlace correcto: w3.org/TR/html5/…
Visionscaper
1
@Visionscaper Fixed, gracias. Siéntete libre de hacer pequeñas modificaciones en las respuestas de otros cuando no cambien la intención original.
Juan Mendes
Donwvoter: ¡Agradecería una explicación para que esto pueda mejorarse!
Juan Mendes
1

Así es como se puede hacer en 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>
Ilich
fuente
-1

En Vuejs utilizo el siguiente código en la etiqueta 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
fuente