Web 视频和音频 API

发布于 2023-01-25 21:24:03 字数 11356 浏览 176 评论 0

学习如何通过浏览器API来控制视频和音频的播放。

1、HTML5 视频和音频

和元素允许我们把视频和音频嵌入到网页当中。就像我们在音频和视频内容文中展示的一样,一个典型的实现如下所示:

<video controls>
<source src="rabbit320.mp4" type="video/mp4">
<source src="rabbit320.webm" type="video/webm">
<p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p>
</video>

controls 属性,它会启用默认的播放设置。如果没有指定该属性,则播放器中不会显示相关控件:

使用原生浏览器控件的一个很大的问题在于,它们在各个浏览器中都不相同 — 对于跨浏览器的支持并不是很好!另一个问题是,在大多数浏览器中原生控件难以通过键盘来操作。

你可以通过隐藏本地控件(通过删除 controls 属性),然后使用 HTML,CSS 和 JavaScript 编写自己的代码来解决这两个问题。 在下一节中,我们将看到如何通过一些可用的工具来实现。

2、HTMLMediaElement API

作为HTML5规范的一部分,HTMLMediaElement API提供允许你以编程方式来控制视频和音频播放的功能—例如 HTMLMediaElement.play(), HTMLMediaElement.pause(),等。该接口对和两个元素都是可用的,因为在这两个元素中要实现的功能几乎是相同的。让我们通过一个例子来一步步演示一些功能。

html

打开 HTML.index 文件。你将看到一些功能;HTML由视频播放器和它的控件所控制:

<div class="player">
<video controls>
<source src="video/sintel-short.mp4" type="video/mp4">
<source src="video/sintel-short.mp4" type="video/webm">
<!-- fallback content here -->
</video>
<div class="controls">
<button class="play" data-icon="P" aria-label="play pause toggle"></button>
<button class="stop" data-icon="S" aria-label="stop"></button>
<div class="timer">
<div></div>
<span aria-label="timer">00:00</span>
</div>
<button class="rwd" data-icon="B" aria-label="rewind"></button>
<button class="fwd" data-icon="F" aria-label="fast forward"></button>
</div>
</div>
  • 播放器被嵌入在元素之中,所以如果有需要的话,可以把它作为一个单元整体来设置其样式。
  • <video>元素层包含两个<source>元素,这样可以根据浏览器来加载其所支持的视频格式。
  • 四个 <button> — play/pause, stop, rewind, and fast forward.
  • 每个<button> 都有一个class, 一个data-icon 属性来决定在每个按钮上显示什么和一个aria-label 属性为每一个按钮提供容易理解的描述, 即使我们没有在tags内提供可读的标签。当用户关注这些元素时含有aria-label 属性的内容也会被读出来。
  • 有一个设定的计时器/进度条 <div>用来记录已经播放的时长。为了展示效果, 提供了两个记录的装置 — 一个 <span> 包含了分钟和秒,和一个额外的<div> 用来创建一个垂直的随着时间增加而增长的进度条。完成版本看上去是这样的, 点击查看完成版本.

css

.controls 的样式

.controls {
visibility: hidden;
opacity: 0.5;
width: 400px;
border-radius: 10px;
position: absolute;
bottom: 20px;
left: 50%;
margin-left: -200px;
background-color: black;
box-shadow: 3px 3px 5px black;
transition: 1s all;
display: flex;
}
.player:hover .controls, player:focus .controls {
opacity: 1;
}
  • 我们从设置为 hidden 的自定义控件 visibility 开始。稍后在我们的JavaScript中, 我们将控件设置为 visible, 并且从<video> 元素中移除controls 属性。这是因为, 如果JavaScript由于某种原因没有加载, 用户依然可以使用原生的控件播放视频。
  • 默认情况下,我们将控件的opacity设置为0.5 opacity,这样当您尝试观看视频时,它们就不会分散注意力。 只有当您将鼠标悬停/聚焦在播放器上时,控件才会完全不透明。
  • 我们使用 Flexbox(display: flex) 布置控制栏内的按钮,以简化操作。

按钮图标

@font-face {
font-family: 'HeydingsControlsRegular';
src: url('fonts/heydings_controls-webfont.eot');
src: url('fonts/heydings_controls-webfont.eot?#iefix') format('embedded-opentype'),
url('fonts/heydings_controls-webfont.woff') format('woff'),
url('fonts/heydings_controls-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
button:before {
font-family: HeydingsControlsRegular;
font-size: 20px;
position: relative;
**content: attr(data-icon);**
color: #aaa;
text-shadow: 1px 1px 0px black;
}
  • ::before 选择器在每个 <button> 元素之前显示内容
  • 使用 content 属性将各情况下要显示的内容设置为 data-icon 属性的内容。例如在播放按钮的情况下,data-icon 包含大写的“P”。
  • 使用 font-family 将自定义Web字体应用于我们的按钮上。在该字体中“P”对应的是“播放”图标,因此播放按钮上显示“播放”图标。
  • 图标字体:减少HTTP请求,因为您不需要将这些图标作为图像文件下载。同时具有出色的可扩展性,以及您可以使用文本属性来设置它们的样式 —— 例如 color 和 text-shadow。

进度条的 CSS

.timer {
line-height: 38px;
font-size: 10px;
font-family: monospace;
text-shadow: 1px 1px 0px black;
color: white;
flex: 5;
position: relative;
}
.timer div {
position: absolute;
background-color: rgba(255,255,255,0.2);
left: 0;
top: 0;
width: 0;
height: 38px;
z-index: 2;
}
.timer span {
position: absolute;
z-index: 3;
left: 19px;
}
  • 我们将外部 .timer <div> 设为flex:5,这样它占据了控件栏的大部分宽度。 我们还设置 position: relative,这样我们就可以根据它的边界方便地定位元素,而不是<body> 元素的边界。
  • 内部 <div> position:absolute 绝对定位于外部 <div> 的顶部。 它的初始宽度为0,因此根本无法看到它。随着视频的播放,JavaScript将动态的增加其宽度。
  • <span> 也绝对位于计时器/进度条 timer 栏的左侧附近。
  • 我们还对内部 <div><span> 定义适当数值的 z-index ,以便进度条显示在最上层,内部 <div> 显示在下层。 这样,我们确保我们可以看到所有信息 —— 一个box不会遮挡另一个。

js

1、在与 index.html 文件相同的目录下创建新的JavaScript文件。命名为 custom-player.js。

2、在此文件的顶部,插入以下代码:

var media = document.querySelector('video');
var controls = document.querySelector('.controls');
var play = document.querySelector('.play');
var stop = document.querySelector('.stop');
var rwd = document.querySelector('.rwd');
var fwd = document.querySelector('.fwd');
var timerWrapper = document.querySelector('.timer');
var timer = document.querySelector('.timer span');
var timerBar = document.querySelector('.timer div');

3、接下来,在代码的底部插入以下内容:

media.removeAttribute('controls');
controls.style.visibility = 'visible';

这两行从视频中删除默认浏览器控件,并使自定义控件可见。

播放和暂停视频

1、播放视频:当按钮被点击就触发 playPauseMedia 函数

play.addEventListener('click', playPauseMedia);
function playPauseMedia() {
if(media.paused) {
play.setAttribute('data-icon','u');
media.play();
} else {
play.setAttribute('data-icon','P');
media.pause();
}
}

2、停止视频

stop.addEventListener('click', stopMedia);
media.addEventListener('ended', stopMedia);
function stopMedia() {
media.pause();
media.currentTime = 0;
play.setAttribute('data-icon','P');
}

在 HTMLMediaElement API 里是没有 stop() 的,只有 pause()

3、前进和后退

rwd.addEventListener('click', mediaBackward);
fwd.addEventListener('click', mediaForward);
var intervalFwd;
var intervalRwd;
function mediaBackward() {
clearInterval(intervalFwd);
fwd.classList.remove('active');
if(rwd.classList.contains('active')) {
rwd.classList.remove('active');
clearInterval(intervalRwd);
media.play();
} else {
rwd.classList.add('active');
media.pause();
intervalRwd = setInterval(windBackward, 200);
}
}
function mediaForward() {
clearInterval(intervalRwd);
rwd.classList.remove('active');
if(fwd.classList.contains('active')) {
fwd.classList.remove('active');
clearInterval(intervalFwd);
media.play();
} else {
fwd.classList.add('active');
media.pause();
intervalFwd = setInterval(windForward, 200);
}
}
function windBackward() {
if(media.currentTime <= 3) {
rwd.classList.remove('active');
clearInterval(intervalRwd); stopMedia();
} else {
media.currentTime -= 3;
}
}
function windForward() {
if(media.currentTime >= media.duration - 3) {
fwd.classList.remove('active');
clearInterval(intervalFwd);
stopMedia();
} else {
media.currentTime += 3;
}
}

更新过去的时间

media.addEventListener('timeupdate', setTime);
function setTime() {
var minutes = Math.floor(media.currentTime / 60);
var seconds = Math.floor(media.currentTime - minutes * 60);
var minuteValue;
var secondValue;
if (minutes < 10) {
minuteValue = '0' + minutes;
} else {
minuteValue = minutes;
}
if (seconds < 10) {
secondValue = '0' + seconds;
} else {
secondValue = seconds;
}
var mediaTime = minuteValue + ':' + secondValue;
timer.textContent = mediaTime;
var barLength = timerWrapper.clientWidth * (media.currentTime/media.duration);
timerBar.style.width = barLength + 'px';
}

调整播放跟停止

加入 stopMedia()、playPauseMedia()

rwd.classList.remove('active');
fwd.classList.remove('active');
clearInterval(intervalRwd);
clearInterval(intervalFwd);

总结

document.onclick = function(e) {
console.log(e.x) + ',' + console.log(e.y)
}

另见

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

森末i

暂无简介

文章
评论
27 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

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