Wymiary wideo HTML5

105

Próbuję uzyskać wymiary filmu, którego nakładam na stronę za pomocą JavaScript, jednak zwraca on wymiary obrazu plakatu zamiast rzeczywistego wideo, ponieważ wydaje się, że jest obliczany przed załadowaniem wideo.

Elliot
źródło
Poddałeś się? Tutaj są dobre wskazówki jako odpowiedzi!
Juan Mendes,

Odpowiedzi:

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

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

Šime Vidas
źródło
Czy jest to możliwe w przypadku formatu ogg, ponieważ nie sądzę, aby film zawierał takie metadane?
Elliot
@Elliot Testowałem w Chrome na tym demo: people.opera.com/howcome/2007/video/controls.html i działa ...
Šime Vidas
Wygląda na to, że łącze znowu się zepsuło
Martin Delille
Przepraszamy, link nie jest uszkodzony
Martin Delille
137

Należy zauważyć, że obecnie akceptowane powyżej rozwiązanie autorstwa Sime Vidas w rzeczywistości nie działa w nowoczesnych przeglądarkach, ponieważ właściwości videoWidth i videoHeight są ustawiane dopiero po uruchomieniu zdarzenia „loadmetadata”.

Jeśli zdarzy się, że zapytasz o te właściwości wystarczająco długo po wyrenderowaniu elementu VIDEO, może to czasami zadziałać, ale w większości przypadków zwróci wartości 0 dla obu właściwości.

Aby zagwarantować, że otrzymujesz prawidłowe wartości właściwości, musisz zrobić coś w następujący sposób:

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

UWAGA: Nie zawracałem sobie głowy uwzględnianiem wersji Internet Explorera sprzed 9, które używają attachEvent zamiast addEventListener, ponieważ wersje tej przeglądarki starsze niż 9 i tak nie obsługują wideo HTML5.

natlee75
źródło
Otrzymuję wartości 100 zarówno dla szerokości, jak i wysokości, a wideo nie ma 100 pikseli. Nie wiem dlaczego ...
Mikel
2
Niestety nie działa to w Chrome na Androida 49; dopiero po rozpoczęciu odtwarzania filmu informacje stają się dostępne. Jakieś dalsze spostrzeżenia na ten temat? PS1: Próbowałem tego tylko z adresami URL do plików lokalnych wybranych za pomocą elementu wejściowego selektora plików. PS2: działa na iOS Safari.
Visionscaper,
Utworzyłem ten problem w narzędziu do śledzenia błędów chromu: bugs.chromium.org/p/chromium/issues/detail?id=598218
Visionscaper
2
To nie zadziała w 100% przypadków. W rzadkich przypadkach videoWidth i videoHeight będą wynosić zero podczas loadedmetadatapożarów. Właśnie to widziałem w Chromium 69. Słuchanie loadeddatajest bezpieczniejszym zakładem.
cleong
18

Funkcja gotowa do użycia

Oto gotowa do użycia funkcja, która zwraca wymiary wideo asynchronicznie, bez zmiany czegokolwiek w dokumencie .

// ---- 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) ;
    });

Oto film użyty we fragmencie, jeśli chcesz go zobaczyć: Big Buck Bunny

Yairopro
źródło
Świetne wykorzystanie obietnicy asynchronicznego dostarczania danych tagów wideo, właśnie tego szukałem, dzięki
Ray Andison,
Świetny kod i przyzwoita obsługa przeglądarki: od Chrome 32, Opera 19, Firefox 29, Safari 8 i Microsoft Edge obietnice są domyślnie włączone.
Jeff Clayton,
13

Nasłuchuj loadedmetadatazdarzenia, które jest wywoływane, gdy agent użytkownika właśnie określił czas trwania i wymiary zasobu multimedialnego

Sekcja 4.7.10.16 Podsumowanie zdarzeń

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
źródło
Poprawny link: w3.org/TR/html5/…
Visionscaper,
1
@Visionscaper Fixed, dzięki. Nie krępuj się wprowadzać drobnych zmian w odpowiedziach innych osób, jeśli nie zmieniają one pierwotnego zamiaru.
Juan Mendes
Donwvoter: Byłbym wdzięczny za wyjaśnienie, aby można było to poprawić!
Juan Mendes,
1

Oto, jak można to zrobić w 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>
Iljicz
źródło
-1

W Vuejs używam następującego kodu w zamontowanym tagu.

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
źródło