检测视频分辨率变化
Posted
技术标签:
【中文标题】检测视频分辨率变化【英文标题】:Detecting video resolution changes 【发布时间】:2016-11-21 04:19:47 【问题描述】:使用一些编解码器和容器,视频可以在中途更改分辨率。这对于 RTC 风格的视频流尤其常见,其中分辨率可以根据可用带宽放大/缩小。在其他情况下,录制设备可能会旋转,视频可能会从纵向翻转到横向,反之亦然。
在网页上播放这些视频(简单的<video>
标签)时,如何检测 javascript 何时发生这种大小变化?
我能想到的最好的方法是验证每一帧的视频大小,但是这种方法有相当多的开销。如果有办法在视频更改大小或触发事件时触发回调,那将是最好的。
严重调整大小的示例视频:https://bugzilla.mozilla.org/attachment.cgi?id=8722238
【问题讨论】:
onresize
或 onratechange
有什么帮助吗?
你有一个视频的例子可以用来测试吗? :)
@dandavis 是的,这些视频肯定存在。这是一个示例:bugzilla.mozilla.org/attachment.cgi?id=8722238 在 VLC 中播放(不是全屏或最大化,VLC 设置为在视频大小更改时调整大小)并观看 VLC 调整大小。
@guest271314 实际视频调整大小,应用程序窗口随之调整大小。
我找不到任何证据表明您的示例视频使用 MPC 或 <video>
标签改变了分辨率。再说一次,我想相信你,但我从未见过你所说的东西是常见的,甚至是可能的......请记住,视频图像与视频编码是分开的,并且可能会发生内部缩放,但视频播放器不会参与此类事件。
【参考方案1】:
现在有一个resize
事件,当视频分辨率改变时触发。
html
<p data-content="resolution"></p>
<video src="https://bug1250345.bmoattachments.org/attachment.cgi?id=8722238"></video>
JavaScript
document.querySelector('video').addEventListener('resize', (e) =>
document.querySelector('[data-content="resolution"]').textContent = [
e.target.videoWidth,
e.target.videoHeight
].join('x');
);
(JSFiddle:http://jsfiddle.net/qz61o2xt/)
参考资料:
HTML Living Standard Media Events - resize Chromium Bug: Add a 'resize' event to elements for when the video data changes dimensions Chromium Bug: Fire 'resize' event on initial metadata load, too.【讨论】:
奇怪的是它还没有在 MDN 上,FF 似乎支持它,Safari 也支持它,而且它似乎至少在 3 年以来就在规范中......但是 MDN 中 DOM 事件的排序让我很不情愿自己制作一个页面(已经有一个/Web/Events/resize,所以也许他们应该将所有媒体事件收集在一个子目录中,但这将是很多工作......无论如何,someone asked for this 3 years ago.【参考方案2】:看看这是否有帮助我不确定。
链接 - https://www.w3.org/2010/05/video/mediaevents.html
【讨论】:
【参考方案3】:您可以使用loadedmetadata
事件定义全局变量或使用Element.dataset
反映.videoWidth
、.videoHeight
元素的初始属性<video>
;在 timeupdate
事件的 <video>
最初存储和当前事件 .videoWidth
、.videoHeight
值,如果属性之一更改调用函数
window.onload = function()
function handleResolutionChange(event)
// do stuff if `.videoWidth` or `.videoHeight` changed from initial value
var video = document.querySelector("video");
video.addEventListener("loadedmetadata", function(event)
event.target.dataset.width = event.target.videoWidth;
event.target.dataset.height = event.target.videoHeight;
)
video.addEventListener("timeupdate", function(event)
if (+event.target.dataset.width !== event.target.videoWidth
&& +event.target.dataset.height !== event.target.videoHeight)
// call `handleResolutionChange` one or more times
// if `event.target` `.videoWidth` or `.videoHeight` changed
handleResolutionChange.call(event.target, event)
)
【讨论】:
谢谢,但这与每帧轮询视频高度/宽度并没有太大区别。没有我可以听的活动吗? @Brad “但这与每帧轮询视频高度/宽度并没有太大区别。” 你怎么能知道没有检查几乎每一帧的帧的属性? “没有我可以听的事件吗?” 不确定你的意思?您可能可以创建一个自定义函数来递归检查.videoWidth
、.videoHeight
;或者您可以监听<video>
元素的timeupdate
事件,它应该返回相同的结果。
拥有一个 timeupdate 事件根本不会占用太多性能,即使在移动设备上也是如此
@guest271314 我希望有一个事件,当视频改变分辨率时,底层播放器会立即通知我。
这段代码不会在测试视频上触发任何事件,所以两者之一是错误的..以上是关于检测视频分辨率变化的主要内容,如果未能解决你的问题,请参考以下文章