<视频>和 onloadedmetadata-event

发布于 2024-12-28 15:16:45 字数 956 浏览 1 评论 0原文

我想在 JavaScript 中使用 HTML5 视频元素的尺寸。 video-标签本身没有设置任何尺寸,因此我希望它能够缩放到视频的大小(它确实如此)。我的标记如下所示:

<video id="viddy" autoplay>
<source src="myvideo.mp4" type='video/mp4; codecs="avc1.42E01E"' />
</video>

当我仅使用 jQuery 获取元素的 height() 和/或 width() 时,我将获得默认值 300,因为它不会等待视频加载。 所以我在网上发现的内容(这里 和此处)是我应该等待 onloadedmetadata 事件。所以我试图在我的 JS 中执行以下操作:

var video = document.getElementById('viddy');
video.onloadedmetadata = function(e){
var dimensions = [video.videoWidth, video.videoHeight];
alert(dimensions);
} 

然而,该事件永远不会触发(尽管视频将加载并播放)并且我永远不会得到我的尺寸。 jQuery-bind('load', 以及我能想到的所有其他方式也会发生同样的情况。有什么想法吗?谢谢。

I'd like to use the dimensions of a HTML5 video element in JavaScript. The video-tag itself does not have any dimensions set, so I expect it to scale to the size of the video (which it does). My markup looks like this:

<video id="viddy" autoplay>
<source src="myvideo.mp4" type='video/mp4; codecs="avc1.42E01E"' />
</video>

When I just use jQuery to get the element's height() and/or width() I will get a default value of 300 as it will not wait for the video to load.
So what I found out on the web (here and here) is that I should be waiting for the onloadedmetadata-event. So I am trying to do the following in my JS:

var video = document.getElementById('viddy');
video.onloadedmetadata = function(e){
var dimensions = [video.videoWidth, video.videoHeight];
alert(dimensions);
} 

Yet, the event will never fire (although the video will load and play) and I'll never get my dimensions. Same happens with a jQuery-bind('load', and every other way I could think of. Any idea? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

飘然心甜 2025-01-04 15:16:45

将代码放入 HTML 头末尾的 function 中(例如,称为 init)并将其绑定到 DOMContentLoaded 事件:

function init() {
    var video = document.getElementById('viddy');
    video.onloadedmetadata = function(e){
        var dimensions = [video.videoWidth, video.videoHeight];
        alert(dimensions);
    }
}

document.addEventListener("DOMContentLoaded", init, false);
<video id="viddy" autoplay>
    <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm' />
</video>

对于 Chrome,

您应该将侦听器添加到:

video.addEventListener('loadedmetadata', function(e){

function init() {
    var video = document.getElementById('viddy');
    video.addEventListener('loadedmetadata', function(e){
        var dimensions = [video.videoWidth, video.videoHeight];
        alert(dimensions);
    });
}

document.addEventListener("DOMContentLoaded", init, false);
<video id="viddy" autoplay>
    <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm' />
</video>

使用 jQuery

$(document).ready(function() {
    $('#viddy').on('loadedmetadata', function() {
        var dimensions = [this.videoWidth, this.videoHeight];
        alert(dimensions);
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<video id="viddy" autoplay>
    <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm' />
</video>

Put your code into a function at the end of your HTML head (e.g. called init) and bind it to the DOMContentLoaded event:

function init() {
    var video = document.getElementById('viddy');
    video.onloadedmetadata = function(e){
        var dimensions = [video.videoWidth, video.videoHeight];
        alert(dimensions);
    }
}

document.addEventListener("DOMContentLoaded", init, false);
<video id="viddy" autoplay>
    <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm' />
</video>

For Chrome

You should change adding the listener to:

video.addEventListener('loadedmetadata', function(e){

function init() {
    var video = document.getElementById('viddy');
    video.addEventListener('loadedmetadata', function(e){
        var dimensions = [video.videoWidth, video.videoHeight];
        alert(dimensions);
    });
}

document.addEventListener("DOMContentLoaded", init, false);
<video id="viddy" autoplay>
    <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm' />
</video>

With jQuery

$(document).ready(function() {
    $('#viddy').on('loadedmetadata', function() {
        var dimensions = [this.videoWidth, this.videoHeight];
        alert(dimensions);
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<video id="viddy" autoplay>
    <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm' />
</video>

青巷忧颜 2025-01-04 15:16:45

TL;DRDOMContentLoaded 之后添加 loadedmetadata 监听器并不能保证在触发 loadedmetadata 事件之前添加监听器,但是,将事件侦听器添加到在视频元素之前使用src(例如document)和capture创建的元素> 阶段或将事件侦听器添加到视频元素内联作为属性将。

视频文件的尺寸将与视频文件元数据一起加载。因此,您需要等待 loadedmetadata 事件被触发,然后您才能从 html 视频元素的 videoWidthvideoHeight 属性获取尺寸,它们将在哪里设置和准备好,这些你都正确了。

注意DOMContentLoaded:在 dom 内容加载事件之后添加事件监听器只能保证 html 元素首先存在,以便能够添加事件监听器。这是做这件事的正确方法,这不是问题。相反,这是遇到问题的原因:在添加事件侦听器之前,元素的存在,带有 src 属性来加载数据,这有点像原因事件侦听器很容易错过它应该捕获和处理的事件。

当您将此事件侦听器添加到视频元素时,事件可能已经发生、传播并结束,因为您在使用其 src 属性创建的视频元素之后添加了事件处理程序。它将开始加载视频,从而加载视频元数据。如果速度足够慢,您的代码将有机会在加载视频元数据后的 loadedmetadata 事件结束之前添加到视频元素。

  1. 您需要在视频之前注册事件处理程序
    元素开始加载其视频文件。这是由 src
    属性,因此您需要在之前或同时添加处理程序
    添加 src 属性。

    您可以在视频元素本身上添加内联事件属性:
    。这里
    不确定处理程序是否也应该内联定义或只是定义
    也参考工作。

  2. 您可以在使用 src 属性创建视频元素之前添加事件侦听器。这意味着您需要将其添加到另一个祖先 html 元素中,该元素是在使用 src 属性创建视频元素之前创建的。此外,该事件不会冒泡,而是捕获。因此,您必须将其添加到事件的捕获阶段并添加到祖先元素,例如 document

document.addEventListener("loadedmetadata", function(e){
    // if necesssary one can add custom logic here for example to check if the event target is the element we are listening the event for with event.target
    var video = e.target;
    var dimensions = [video.videoWidth, video.videoHeight];
    alert(dimensions);
}, true);
<video id="viddy" autoplay>
    <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm' />
</video>

TL;DR Adding loadedmetadata listener after DOMContentLoaded will not guarantee the listener will be added before loadedmetadata event is fired, however, adding the event listener to an element created before the video element with src (e.g. document) and in capture phase or adding the event listener to the video element inline as an attribute will.

The dimensions of the video file will be loaded with the video file metadata. So you will need to wait loadedmetadata event to be fired then you will be able to get dimensions from videoWidth and videoHeight properties of the html video element, where they will be set and ready, these you got all correct.

Note for DOMContentLoaded: Adding the event listener after the dom content loaded event will only guarantee the exsitence of the html element in first place to be able to add an event listener on. That is the correct method of doing that thing and here it is not the issue. On the contrary, it is the cause that the issue in question has been run into: The element's existence, with a src attribute to load data, before the event listener added is kind of sort of the reason event listener is prone to miss the event it should catch and handle.

By the time you add this event listener to the video element, the event might have already happened, propagated and ended, since you add the event handler after the video element created with its src attribute. It will start loading video hence video metadata. If it is slow enough to do that your code will get a chance to be added to the video element before loadedmetadata event ended after video metadata has been loaded.

  1. You need to register the event handler before the video
    element starts loading its video file. Here it is by with src
    attribute, so you need to add the handler before or same time you
    add the src attribute.

    You can add an inlined event attribute on the video element itself:
    <video src="some-video-url" onloadedmetadata="somehandler">. Here
    not sure if the handler should be defined inline too or just
    referencing work too.

  2. You can add the event listener before the video element is created with a src attribute. That means you need to add it to another ancestor html element that is created before the video element is created wth a src attribute. Also that event does not bubble but captures. So, you have to add it for capture phase of the event and to a ancestor element, e.g. document.

document.addEventListener("loadedmetadata", function(e){
    // if necesssary one can add custom logic here for example to check if the event target is the element we are listening the event for with event.target
    var video = e.target;
    var dimensions = [video.videoWidth, video.videoHeight];
    alert(dimensions);
}, true);
<video id="viddy" autoplay>
    <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm' />
</video>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文