当前位置:网站首页>requestVideoFrameCallback() 简单实例
requestVideoFrameCallback() 简单实例
2022-07-28 22:41:00 【InfoQ】
<template>
<div id="app">
<div class="player-container">
<div class="title">requestVideoFrameCallback() 简单实例</div>
<div class="item-container left">
<div class="item-container-in">
<video controls playsinline muted autoplay></video>
<div class="item-header">Video</div>
</div>
</div>
<div class="item-container right">
<div class="item-container-in">
<canvas></canvas>
<div class="item-header">Canvas</div>
</div>
</div>
<div class="fps-info" v-if="fpsInfo">
<strong>FPS:</strong>
<i>{{ fpsInfo }}</i>
</div>
<div class="metadata-info" v-if="metadata">
<textarea readonly v-model="metadata"></textarea>
</div>
</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
fpsInfo: null,
metadata: null,
};
},
mounted() {
this.init();
},
methods: {
init() {
const video = document.querySelector("video");
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
video.addEventListener("play", () => {
if (
!("requestVideoFrameCallback" in HTMLVideoElement.prototype)
) {
return alert(
"你的浏览器不支持接口 `Video.requestVideoFrameCallback()`"
);
}
});
let width = canvas.width;
let height = canvas.height;
let paintCount = 0;
let startTime = 0.0;
const updateCanvas = (now, metadata) => {
if (startTime === 0.0) {
startTime = now;
}
ctx.drawImage(video, 0, 0, width, height);
const elapsed = (now - startTime) / 1000.0;
const fps = (++paintCount / elapsed).toFixed(3);
this.fpsInfo = !isFinite(fps) ? 0 : fps;
this.metadata = JSON.stringify(metadata, null, 2);
video.requestVideoFrameCallback(updateCanvas);
};
video.src = "https://vjs.zencdn.net/v/oceans.mp4";
video.requestVideoFrameCallback(updateCanvas);
},
},
};
</script>
<style>
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
background: #000;
}
.title {
position: absolute;
left: 0;
top: 30;
height: 60px;
line-height: 60px;
font-size: 24px;
color: #fff;
text-align: center;
width: auto;
right: 0px;
background-color: #000;
z-index: 100;
border-bottom: 1px rgba(255, 255, 255, 0.6) solid;
}
.player-container {
width: 100%;
height: 100vh;
overflow: hidden;
position: relative;
}
.item-container {
position: absolute;
width: 50%;
height: 100%;
padding: 50px;
top: 0px;
z-index: 1;
}
.item-container.left {
left: -5px;
border-right: 1px rgba(255, 255, 255, 0.6) solid;
}
.item-container-in {
width: 100%;
height: 100%;
position: relative;
}
.item-header {
position: absolute;
width: 100%;
height: 100%;
top: 100px;
z-index: 9;
color: rgba(255, 255, 255, 0.8);
font-weight: 700;
}
.item-container.right {
right: -5px;
border-left: 1px rgba(255, 255, 255, 0.6) solid;
}
.item-container canvas,
.item-container video {
position: absolute;
left: 50%;
top: 50%;
margin: -180px 0px 0px -320px;
width: 640px;
height: 360px;
}
.item-container::before {
position: absolute;
content: "";
width: 1px;
height: 100%;
overflow: hidden;
background-color: rgba(#fff, 0.6);
}
.fps-info {
position: absolute;
width: 200px;
height: 50px;
line-height: 20px;
font-family: Arial, Helvetica, sans-serif;
left: 50px;
bottom: 50px;
z-index: 10;
padding: 15px;
background-color: rgba(255, 255, 255, 0.5);
text-align: left;
color: #000;
}
.fps-info i {
font-style: normal;
}
.metadata-info {
position: absolute;
width: 600px;
height: 180px;
line-height: 20px;
font-family: Arial, Helvetica, sans-serif;
right: 50px;
bottom: 50px;
z-index: 10;
padding: 15px;
background-color: rgba(255, 255, 255, 0.5);
text-align: left;
color: #000;
}
.metadata-info textarea {
display: block;
width: 100%;
height: 100%;
background-color: transparent;
border: none;
}
</style>

requestVideoFrameCallback()边栏推荐
- 还在写大量 if 来判断?一个规则执行器干掉项目中所有的 if 判断...
- Detailed explanation of the usage of exists in MySQL
- @PostConstruct注解详解
- Installation and use of pnpm
- Samsung asset management (Hong Kong) launched yuancosmos ETF to focus on investing in the future tuyere track
- Idea connection database
- PHP语言基础知识(超详细)
- Geth installation
- Applet verification code login
- Dynamic programming (V)
猜你喜欢

IDEA 连接 数据库

Do like and in indexes in MySQL go

Advanced area of attack and defense world web masters supersqli

Laravel permission control

flyway的快速入门教程

Newscenter, advanced area of attack and defense world web masters

15. Model evaluation and selection

PTA (daily question) 7-71 character trapezoid

动态规划问题(八)

乱打日志的男孩运气怎么样我不知道,加班肯定很多!
随机推荐
2022dasctfjuly empowerment competition (reappearance)
【开发教程10】疯壳·开源蓝牙心率防水运动手环-蓝牙 BLE 收发
PTA (daily question) 7-70 diamond
Event extraction and documentation (2008-2017)
17. Design of machine learning system
110道 MySQL面试题及答案 (持续更新)
Geth installation
软考 --- 数据库(4)SQL语句
html+css+php+mysql实现注册+登录+修改密码(附完整代码)
[development tutorial 10] crazy shell · open source Bluetooth heart rate waterproof sports Bracelet - Bluetooth ble transceiver
MQ 消息丢失、重复、积压问题,如何解决?
Sword finger offer 41. median in data flow
Applet waterfall flow, upload pictures, simple use of maps
ACM SIGIR 2022 | interpretation of selected papers of meituan technical team
Dynamic programming problem (VIII)
Advanced area of attack and defense world web masters -baby Web
Advanced area of attack and defense world web masters ics-06
Application and principle of distributed current limiting redistribution rratelimiter
Alibaba Code代码索引技术实践:为Code Review提供本地IDE的阅读体验
最长上升子序列