Размеры видео HTML5


105

Я пытаюсь получить размеры видео, которое я накладываю на страницу с помощью JavaScript, однако он возвращает размеры изображения плаката вместо фактического видео, поскольку кажется, что он рассчитывается до загрузки видео.


Вы сдались? Здесь есть хорошие подсказки в качестве ответов!
Хуан Мендес,

Ответы:


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

Спецификация: https://html.spec.whatwg.org/multipage/embedded-content.html#the-video-element


Возможно ли это с форматом ogg, поскольку я не думаю, что видео будет включать такие метаданные?
Эллиот

@Elliot Я тестировал эту демонстрацию в Chrome: people.opera.com/howcome/2007/video/controls.html, и это работает ...
Шиме Видас,

Похоже, связь снова разорвана
Мартин

Извините, ссылка на самом деле не битая
Мартин

137

Следует отметить, что в настоящее время принятое выше решение от Sime Vidas фактически не работает в современных браузерах, поскольку свойства videoWidth и videoHeight не устанавливаются до тех пор, пока не сработает событие loadedmetadata.

Если вы запрашиваете эти свойства достаточно далеко после визуализации элемента VIDEO, это иногда может работать, но в большинстве случаев это вернет значения 0 для обоих свойств.

Чтобы гарантировать, что вы получаете правильные значения свойств, вам нужно сделать что-то вроде:

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

ПРИМЕЧАНИЕ. Я не беспокоился об учете версий Internet Explorer до 9, которые используют attachEvent вместо addEventListener, поскольку версии этого браузера до 9 в любом случае не поддерживают видео HTML5.


Я получаю значения 100 для ширины и высоты, а видео не имеет 100 пикселей. Не уверен, почему ...
Mikel

2
К сожалению, это не работает в Chrome для Android 49; информация становится доступной только тогда, когда начинается воспроизведение видео. Любое дальнейшее понимание этого? PS1: Я пробовал это только с URL-адресами локальных файлов, выбранных с помощью элемента ввода селектора файлов. PS2: он работает в iOS Safari.
Visionscaper,

Я создал эту проблему в системе отслеживания ошибок хрома: bugs.chromium.org/p/chromium/issues/detail?id=598218
Visionscaper,

2
Это не сработает в 100% случаев. В редких случаях videoWidth и videoHeight будут равны нулю при loadedmetadataсрабатывании. Я только что видел это на Chromium 69. Слушать loadeddata- безопаснее.
cleong

18

Готовая к использованию функция

Вот готовая к использованию функция, которая асинхронно возвращает размеры видео, ничего не меняя в документе .

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

Вот видео, используемое для фрагмента, если вы хотите его увидеть: Big Buck Bunny


Отличное использование обещания предоставлять данные видео тегов асинхронно, именно то, что я искал, спасибо
Рэй Эндисон

Отличный код и достойная поддержка браузеров: начиная с Chrome 32, Opera 19, Firefox 29, Safari 8 и Microsoft Edge обещания включены по умолчанию.
Джефф Клейтон

13

Слушайте loadedmetadataсобытие, которое отправляется, когда пользовательский агент только что определил продолжительность и размеры медиаресурса.

Раздел 4.7.10.16 Сводка события

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

videoTagRef.addEventListener('loadedmetadata', function(e){
    console.log(videoTagRef.videoWidth, videoTagRef.videoHeight);
});

Правильная ссылка: w3.org/TR/html5/…
Visionscaper

1
@Visionscaper Исправлено, спасибо. Не стесняйтесь вносить небольшие правки в ответы других, если они не меняют первоначального намерения.
Хуан Мендес

Donwvoter: Буду признателен за объяснение, чтобы это можно было улучшить!
Хуан Мендес,

1

Вот как это можно сделать во 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>

-1

В Vuejs я использую следующий код в установленном теге.

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
    },
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.