项目设置完成:Visual Studio Code 显示项目结构。
- 打开终端并运行以下命令:
yarn dev
这将创建一个开发服务器,用于托管您的网页。打开 Vite 提供的 URL。
使用“yarn dev”命令启动 Vite 开发服务器。
打开链接后http://localhost:5173/
,您应该会看到以下内容:
执行“yarn dev”命令后显示的初始用户界面。
恭喜!您已成功完成开发环境的设置,这将使我们能够高效地构建自定义 HTML5 视频播放器。
故障排除:如果您发现设置未按预期运行,请不要担心。只需删除项目文件夹并重复此过程即可。您可能错过了某个步骤,或者某些工具可能未正确安装。此外,请仔细检查您的 Tailwind CSS 和 PostCSS 配置文件,以确保它们包含如上所示的正确代码。
如何使用 Tailwind CSS 构建自定义 UI
本节涵盖构建自定义 HTML5 视频播放器 UI 所需的所有样式。我们将逐步讲解整个流程。
首先,将以下链接标签复制并粘贴到 HTML 的头部,位于样式表链接的上方:
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
这使我们能够使用Materialize CSS 图标,这对于在 UI 中设置按钮样式至关重要。
接下来,我们重点介绍如何在标记中设置视频元素的样式。只需body
使用下面提供的代码片段替换该元素即可:
<body class="bg-indigo-950 p-10">
<div
id="container"
class="w-4/5 h-4/5 mx-auto rounded-lg overflow-hidden relative group"
>
<figure>
<video class="w-full">
<source src="/your-video.mp4" />
</video>
</figure>
</div>
<script type="module" src="/main.js"></script>
</body>
提供的代码片段包含视频元素的标记和样式,以及一个用作整个视频播放器 UI 容器的外部 div。视频元素嵌套在 figure 元素中。
对于source
元素,请指定要播放的视频的路径。您可以在线查找视频,下载后将其添加到项目文件夹中的“public”目录。然后,将元素src
的属性链接到视频文件。您可以在此处source
找到免费的可下载视频。
接下来,让我们使用您在 HTML 中链接的Materialize CSS Icons来设置控件的样式。将以下代码片段放置在figure
body 元素内的元素下方。
<div
id="controls"
class="opacity-0 p-5 absolute bottom-0 left-0 w-full transition-opacity duration-300 ease-linear group-hover:opacity-100"
>
<div id="progress-bar" class="h-1 w-full bg-white cursor-pointer mb-4">
<div
id="progress-indicator"
class="h-full w-9 bg-indigo-800 transition-all duration-500 ease-in-out"
></div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center justify-between">
<button
id="rewind"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-3xl w-12">replay_10 </i>
</button>
<button
id="play-pause"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-5xl inline-block w-12"
>play_arrow</i
>
</button>
<button
id="fast-forward"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-3xl w-12">forward_10 </i>
</button>
</div>
<div>
<button
id="volume"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-3xl">volume_up</i>
</button>
</div>
</div>
</div>
此代码段定义了视频播放器控件的布局和行为。首先,设置一个容器 div ( <div id="controls">
) 来容纳所有控件元素。该容器最初是不可见的 ( ),当用户将鼠标悬停在其上方 ( ) 时opacity-0
,它会通过平滑的过渡效果 ( ) 变为可见。transition-opacity duration-300 ease-linear
group-hover:opacity-100
容器内有一个进度条 ( <div id="progress-bar">
),用于跟踪视频的播放进度。它由一个白色背景条 ( ) 和一个可移动的靛蓝色bg-white
指示器( ) 组成。进度条具有响应功能,允许用户跳转到视频的不同部分。<div id="progress-indicator">
bg-indigo-800
进度条下方是各种功能的控制按钮。倒回、播放/暂停和快进按钮被分组在一个弹性容器 ( <div class="flex items-center justify-between">
) 内。每个按钮 ( <button>
) 的样式设置为hover:scale-125
在鼠标悬停时略微放大 ( )。
- 倒退按钮 (
<button id="rewind">
) 包含一个图标 ( <i class="material-icons text-white text-3xl w-12">replay_10</i>
),表示倒退十秒。
- 播放/暂停按钮 ( ) 包含一个在播放和暂停状态之间切换的
<button id="play-pause">
图标 ( )。<i class="material-icons text-white text-5xl w-12">play_arrow</i>
- 快进按钮 (
<button id="fast-forward">
) 包含一个图标 ( <i class="material-icons text-white text-3xl w-12">forward_10</i>
),表示快进十秒。
<button id="volume">
另外,控制按钮右侧还有一个音量按钮 ( )。它包含一个音量图标 ( <i class="material-icons text-white text-3xl w-12">volume_up</i>
)。
总的来说,这段代码结合了 HTML 和 Tailwind CSS 类,为视频播放器创建了一组功能齐全、外观吸引人的控件。
最后的难题是禁用默认浏览器功能,我们不希望我们的自定义 HTML5 视频播放器与浏览器提供的默认样式发生冲突或被其覆盖。
将下面的代码片段复制并粘贴到您的style.css
文件中,位于 Tailwind CSS 指令的正下方:
@layer base {
video::-webkit-media-controls {
display: none;
}
video::-webkit-media-controls-play-button {
display: none;
}
video::-webkit-media-controls-volume-slider {
display: none;
}
video::-webkit-media-controls-mute-button {
display: none;
}
video::-webkit-media-controls-timeline {
display: none;
}
video::-webkit-media-controls-current-time-display {
display: none;
}
}
这段代码用于自定义 WebKit 浏览器引擎(常用于 Safari 和某些版本的 Google Chrome 等浏览器)为该<video>
元素提供的默认媒体控件的外观和行为。
块中的每条 CSS 规则@layer base
都针对默认媒体控件的特定部分,并通过将其display
属性设置为 来隐藏它们none
。以下是每条规则的详细说明:
video::-webkit-media-controls
:此规则针对元素的所有媒体控件<video>
,并将其完全隐藏。通过隐藏这些控件,您可以使用 JavaScript 和 CSS 实现自定义控件,从而在不同浏览器中提供更加个性化且一致的用户体验。
video::-webkit-media-controls-play-button
:此规则针对默认媒体控件中的播放按钮并将其隐藏。如果我们使用自定义播放按钮设计或以编程方式处理播放控制,则可能需要隐藏播放按钮。
video::-webkit-media-controls-volume-slider
:此规则以默认媒体控件中的音量滑块为目标,并将其隐藏。与隐藏播放按钮类似,如果您要实现自己的音量控制界面,也可以选择隐藏音量滑块。
video::-webkit-media-controls-mute-button
:此规则以默认媒体控件中的静音按钮为目标,并将其隐藏。如果您有自定义的静音/取消静音按钮,或者想要通过编程管理音频静音,则可以隐藏默认静音按钮。
video::-webkit-media-controls-timeline
:此规则以默认媒体控件中的时间线(进度条)为目标,并将其隐藏。通过隐藏时间线,您可以实现自定义样式和其他功能的进度条。
video::-webkit-media-controls-current-time-display
:此规则以默认媒体控件中的当前时间显示为目标,并将其隐藏。如果您要实现用于显示当前播放时间的自定义界面,则可以隐藏默认显示。
总的来说,此代码允许完全自定义 WebKit 浏览器提供的默认媒体控件,让您为网站上的视频播放创建独特且量身定制的用户体验。
检查您的本地主机 URL 以查看显示的自定义 UI,如下所示:
自定义视频播放器 UI,无需鼠标悬停,控件隐藏。
然而,悬停时,控件将淡入,UI 将显示如下:
自定义视频播放器 UI,鼠标悬停时可看到控件。
就这样!您已经成功构建了一个自定义的 HTML5 视频播放器。现在,是时候使用 JavaScript 来开发控件和功能,让它焕发生机了。我们将在接下来的章节中逐步讲解。
如何实现播放和暂停功能
要在 HTML5 自定义视频播放器上实现播放和暂停功能,首先需要使用标记中相应的 ID 选择播放和暂停按钮。您也可以选择视频元素。然后,您将使用浏览器中 JavaScript 提供的视频 API 以编程方式控制播放。现在就开始吧。
"use strict";
const playNpauseBtn = document.querySelector("#play-pause");
const video = document.querySelector("video");
从上面的代码片段来看:
"use strict";
确保 JavaScript 在严格模式下运行,捕获常见的编码错误。
const playNpauseBtn = document.querySelector("#play-pause");
使用其 ID 从 HTML 中选择播放/暂停按钮。
const video = document.querySelector("video");
从 HTML 中选择视频元素。
接下来,让我们创建两个函数:
playNpauseFn
:此功能将处理视频的播放和暂停。
updatePlayNPauseIcon
:此功能将根据视频的当前状态更新播放和暂停图标。例如,如果视频正在播放,则会显示暂停图标,反之亦然。
现在,让我们检查一下它在下面的代码片段中如何发挥作用。
function playNpauseFn() {
video.paused ? video.play() : video.pause();
}
function updatePlayNPauseIcon() {
const icon = playNpauseBtn.querySelector("i");
icon.textContent = "";
icon.textContent = video.paused ? "play_arrow" : "paused";
}
让我们了解一下发生了什么。首先从playNpauseFn
函数开始,当它被调用时,它会使用 Video API 中提供的方法检查视频的当前状态paused
。如果视频已暂停,则播放视频。否则,暂停视频。这是使用 JavaScript 中的三元运算符实现的。
或者,您可以使用 if/else 语句重写此语句,如下所示:
function playNpauseFn() {
if (video.paused) {
video.play();
} else {
video.paused();
}
}
上面的代码示例完成与以前版本相同的任务 – 任何一个都可以工作。
现在,我们来看看第二个函数。updatePlayNPauseIcon
该函数根据视频的当前状态更新播放和暂停图标。我们来回顾一下它的实现方式。
查看下面的图标样式:
<button
id="play-pause"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-5xl inline-block w-12">play_arrow</i>
</button>
这段代码创建了一个 ID 为“play-pause”的按钮,该按钮包含一个由<i>
标签指定的图标。Materialize CSS 使用标签内的文本“play_arrow”<i>
来显示匹配的图标。如果您更改标签内的文本<i>
,Materialize CSS 也会相应地更新图标。
现在,我们来关注负责更新图标的函数。下面单独看一下:
function updatePlayNPauseIcon() {
const icon = playNpauseBtn.querySelector("i");
icon.textContent = "";
icon.textContent = video.paused ? "play_arrow" : "paused";
}
此函数updatePlayNPauseIcon()
负责根据视频的当前状态更新播放/暂停图标。
- 它首先选择播放/暂停按钮内的图标元素。
- 然后,它会清除图标内所有现有的文本内容。
- 最后,如果视频暂停,则将图标的文本内容设置为“play_arrow”;如果视频正在播放,则设置为“paused”。这会动态更改按钮上显示的图标,以反映当前的播放状态。
注意:以编程方式更新图标的方式可能因图标服务及其 API 而异。此特定实现特定于 Materialize CSS 图标。
接下来,让我们将这些函数连接到触发它们的事件。让我们看看它是如何工作的:
video.addEventListener("play", updatePlayNPauseIcon);
video.addEventListener('click', playNpauseFn)
video.addEventListener("pause", updatePlayNPauseIcon);
playNpauseBtn.addEventListener("click", playNpauseFn);
在此代码中:
video.addEventListener("play", updatePlayNPauseIcon);
:此行向视频元素添加了一个事件监听器,专门监听“play”事件。当视频开始播放时,它会触发该updatePlayNPauseIcon
函数,并相应地更新播放/暂停图标。
video.addEventListener('click', playNpauseFn)
:此行向视频元素添加了一个事件监听器,用于监听“click”事件。当视频被点击时,会触发playNpauseFn
相应的函数,播放或暂停视频。
video.addEventListener("pause", updatePlayNPauseIcon);
:此行向视频元素添加一个事件监听器,用于监听“暂停”事件。当视频暂停时,它会触发该updatePlayNPauseIcon
函数来更新播放/暂停图标。
playNpauseBtn.addEventListener("click", playNpauseFn);
:此行向播放/暂停按钮元素添加一个事件监听器。当点击按钮时,会触发playNpauseFn
播放或暂停视频的函数。
我们在两个选定元素上设置了四个事件监听器。让我们来分解一下具体发生了什么:
- 视频元素监听“play”事件。当视频开始播放时,它会触发
updatePlayNPauseIcon
,并根据视频的当前状态更新图标。
- 视频元素还会监听点击事件。点击后会触发
playNpauseFn
,从而在播放和暂停视频之间切换。
- 此外,视频元素会监听“暂停”事件。当视频暂停时,它会触发
playNpauseFn
,切换视频的播放状态。
- 播放/暂停按钮元素也会监听点击事件。点击后,它会触发
playNpauseFn
,在播放和暂停视频之间切换。
本节到此结束。现在您可以尝试播放和暂停功能了。视频应该可以正常暂停和播放,图标也会正确更新。
目前您的自定义视频播放器应该执行以下操作:
测试播放和暂停功能
在下一节中,我们将实现倒带和快进功能。
如何实现快退和快进功能
现在我们已经实现了播放和暂停功能,接下来要添加的功能是快退和快进。这些常用功能允许用户在视频中按设定的秒数快进或快退。
首先,让我们使用 ID 从 HTML 文档中选择相应的按钮并将它们存储在变量中:
const rewindBtn = document.querySelector("#rewind");
const fastForwardBtn = document.querySelector("#fast-forward");
完成后,您需要构建负责实现快退和快进功能的函数。以下是代码片段:
function rewindNforwardFn(type) {
video.currentTime += type === "rewind" ? -10 : 10;
}
这个函数名为rewindNforward
,负责快退或快进视频。它的工作原理如下:
- 它需要一个名为的参数
type
,该参数指示您是要倒退还是快进。
- 如果
type
是“倒带”,则会从视频的当前播放时间中减去 10 秒(video.currentTime
)。
- 如果
type
不是“倒带”(表示要快进),则会在视频的当前播放时间上增加 10 秒。这允许用户以 10 秒为间隔向后或向前浏览视频,具体取决于 的值type
。
接下来,您需要连接按钮上的事件监听器来触发该rewindNforward
功能。
rewindBtn.addEventListener("click", () => rewindNforwardFn("rewind"));
fastForwardBtn.addEventListener("click", () => rewindNforwardFn("forward"));
此代码为快退和快进按钮添加了事件监听器。当点击快退按钮时,它会触发rewindNforward
带有参数“rewind”的函数,表示您想要快退视频。
类似地,当单击快进按钮时,它会触发rewindNforward
带有参数“forward”的函数,表示您想要快进视频。
请随意测试并观察它在用户界面(UI)上的运行情况。
测试快退和快进功能
如何实现静音和取消静音功能
要添加静音和取消静音功能,您需要遵循与之前功能相同的流程。
首先使用下列querySelector
方法从 HTML 文档中选择音量按钮:
const volumeBtn = document.querySelector("#volume");
然后,创建负责静音和取消静音视频的功能,并在发生任一事件时相应地更新图标。
function muteNunmuteFn() {
video.muted = video.muted ? false : true;
}
function updateVolumeIcon() {
const icon = volumeBtn.querySelector("i");
icon.textContent = "";
icon.textContent = video.muted ? "volume_off" : "volume_up";
}
该代码包含两个函数:
muteNunmuteFn()
:此功能切换视频的静音状态。如果视频当前处于静音状态,则取消静音。否则,将视频静音。
updateVolumeIcon()
:此函数用于更新音量按钮上显示的音量图标。它会清除所有现有的图标内容,然后如果视频已静音,则将图标文本设置为“volume_off”,如果视频未静音,则将图标文本设置为“volume_up”。
最后一步是将函数与事件监听器连接起来,以便在事件触发时执行它们。以下是相关代码片段:
video.addEventListener("volumechange", updateVolumeIcon);
volumeBtn.addEventListener("click", muteNunmuteFn);
这段代码设置了两件事:
- 它为视频元素添加了一个事件监听器,用于监听“volumechange”事件。当该事件发生时(即音量发生变化时),会触发该
updateVolumeIcon
函数来更新音量图标。
- 它为音量按钮添加了一个事件监听器。当点击音量按钮时,它会触发该
muteNunmuteFn
函数,在视频静音和取消静音之间切换。
play
与和事件类似pause
,视频也会volumechange
在音量或静音状态发生变化时触发一个事件。您可以设置视频监听此事件,因此当该事件发生时,事件监听器会运行相应的函数来更新音量图标。
测试静音和取消静音功能
如何根据视频时间更新进度条
在本节中,您将了解如何在视频播放时更新进度条,以便用户跟踪他们在视频中的进度。
目前,进度条不会随着视频播放和时间变化而移动。我们将修复这个问题
首先,您需要移除进度条的固定宽度样式。它最初是为了样式设置而添加的,但现在不再需要,因为您将使用 JavaScript 动态调整宽度。将 div 元素中的类名从 更新为 ,w-9
并w-0
使用 id 为“progress-indicator”。
<div id="progress-bar" class="h-1 w-full bg-white cursor-pointer mb-4">
<div
id="progress-indicator"
class="h-full w-0 bg-indigo-800 transition-all duration-500 ease-in-out"
></div>
</div>
接下来实现进度条的更新,第一步是选中进度条指示器元素。该元素的宽度会随着视频时间的推移而增加。以下是实现该功能的代码片段:
const progressIndicator = document.querySelector("#progress-indicator");
一旦选择了进度指示器,您的下一个任务就是实现负责更新它的功能。
function updateProgress() {
const progressPercentage = (video.currentTime / video.duration) * 100;
progressIndicator.style.width = `${progressPercentage}%`;
}
在上面的代码片段中,调用的函数updateProgress
通过将视频的当前时间除以其总时长,然后乘以 100 来计算视频进度的百分比。此百分比用于设置进度指示器元素的宽度,直观地表示已观看了多少视频。
让我们分解一下这个函数。第一行代码计算视频当前时长占总时长的百分比。计算方法是将当前时间除以视频总时长。例如,如果视频时长为 30 秒,当前时间为 3 秒,则 3 除以 30 等于 0.1。
然后把这个小数乘以 100 得到百分比。所以,0.1 乘以 100 等于 10。这意味着你已经完成了 30 秒视频的 10%。
最后,您使用这个百分比来相应地更新进度指示器的宽度。
接下来,我们添加一个触发该函数的事件监听器。请参阅下面的代码片段:
video.addEventListener('timeupdate', updateProgress);
与视频 API 中的其他事件类似,还有一个名为 的事件。此事件在视频的 发生变化timeupdate
时触发。因此,随着时间的更新,每次触发该事件时都会自动执行该函数,从而使进度指示器相应更新。currentTime
updateProgress
测试时间进度功能
如何实现搜索功能
搜索功能是视频播放器至关重要的方面。虽然快退和快进对于短时间的跳跃很有效,但用户通常希望更大幅度地跳转到视频的特定部分。点击快退或快进只会以固定的增量移动,这可能会让用户感到沮丧。因此,搜索功能在这种情况下显得尤为重要。
让我们首先从文档对象模型 (DOM) 中选择进度条元素。
const progessBar = document.querySelector("#progress-bar");
使用 ID 从 DOM 获取进度条后,下一步就是构造查找函数。具体实现如下代码片段:
function seekingFn(e) {
const updatedTime = (e.offsetX / progessBar.offsetWidth) * video.duration;
video.currentTime = updatedTime;
}
让我们分解该函数并了解发生了什么。
该函数seekingFn
根据用户在进度条上点击的位置调整视频的当前播放时间。它通过将点击位置相对于进度条宽度的水平偏移量除以进度条的总宽度来计算更新时间。然后,将其乘以视频的总时长。最后,将计算出的更新时间设置为视频的当前时间。
接下来,添加事件监听器:
let mouseIsDown = false;
progessBar.addEventListener("mousedown", () => (mouseIsDown = true));
progessBar.addEventListener("mouseup", () => (mouseIsDown = false));
progessBar.addEventListener("click", seekingFn);
progessBar.addEventListener("mousemove", (e) => mouseIsDown && seekingFn);
在上面的代码片段中,代码处理进度条上的鼠标事件以实现寻求功能:
mouseIsDown
是一个跟踪鼠标按钮是否被按下的变量。
- 当鼠标按钮被按下时(
mousedown
事件),mouseIsDown
设置为 true。
- 当鼠标按钮被释放(
mouseup
事件)时,mouseIsDown
设置为 false。
- 当点击进度条(
click
事件)时,seekingFn
触发该函数以定位到点击的位置。
- 当鼠标移动到进度条上(
mousemove
事件)时,如果mouseIsDown
为真,即按下鼠标按钮,则seekingFn
触发该函数,允许在拖动鼠标时进行搜索。
测试搜索功能
如何添加键盘导航以实现无障碍功能
我们的视频播放器目前支持鼠标和光笔等指针设备。但我们的目标是确保那些可能没有或无法使用这些设备的用户也能轻松使用。因此,我们致力于让定制的 HTML5 视频播放器无需指针设备即可使用,而是使用键盘。
使用空格键播放和暂停
我们先来改进一下播放和暂停功能。在大多数视频播放器中,我们通常使用键盘上的空格键来切换视频的播放和暂停。这是我们要实现的第一个键盘导航功能。
下面是一段代码片段,演示了如何实现这一点:
window.addEventListener("keyup", (e) => {
if (e.code === "Space") {
playNpauseFn();
}
});
这段代码监听键盘上某个按键的释放,也就是“keyup”事件。如果释放的键恰好是空格键,则会触发切换视频播放和暂停的函数。你只需要重复使用之前编写的函数即可。
以下是代码的逐步解释:
window.addEventListener("keyup", (e) => { ... })
:
- 您正在向对象添加事件监听器
window
。
- 当释放某个键(
keyup
事件)时,会触发此监听器。
(e) => { ... }
:
- 这是一个在事件发生时执行的箭头函数
keyup
。
- 该
e
参数表示包含有关事件的信息的事件对象。
if (e.code === "Space") { ... }
:
- 此条件检查释放的键是否是空格键。
e.code
提供触发事件的键的代码。
playNpauseFn();
:
- 如果释放的键是空格键,则调用此函数。
- 该
playNpauseFn
功能负责在播放和暂停视频之间切换。
使用箭头键快退和快进
除了使用空格键播放和暂停之外,您还可以使用左箭头键倒退视频,使用右箭头键快进视频。
在前面播放和暂停功能的代码片段的基础上,您可以合并箭头键来实现视频的后退和快进。
window.addEventListener("keyup", (e) => {
if (e.code === "Space") {
playNpauseFn();
} else if (e.code === "ArrowLeft") {
rewindNforwardFn("rewind");
} else if (e.code === "ArrowRight") {
rewindNforwardFn("forward");
} else {
return;
}
});
这段代码在 window 对象上为 keyup 事件设置了一个事件监听器。当任意键被释放时,都会触发传入的回调函数,回调函数会以事件为参数。回调函数内部包含条件语句,用于判断按下的是哪个键:
- 如果按下的键是空格键(“Space”),
playNpauseFn
则执行该功能,在视频的播放和暂停之间切换。
- 如果按下的键是左箭头键(“ArrowLeft”),
rewindNforwardFn
则使用参数“rewind”调用该函数,表示视频应该倒回。
- 如果按下的键是右箭头键(“ArrowRight”),
rewindNforwardFn
则使用参数“forward”调用该函数,表示视频应快进。
- 如果按下的键不是空格键、左箭头或右箭头,则函数将返回而不执行任何操作。
您的代码现在应该是什么样子
我们现在完成了自定义 HTML5 视频播放器的构建。恭喜你学习了本课程。
如果您遇到任何困难或遗漏了任何步骤,请不要担心。您可以在下面找到每个主要文件的代码片段:
索引.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
<link rel="stylesheet" href="./style.css" />
<title>HTML5 Custom Video Player</title>
</head>
<body class="bg-indigo-950 p-10">
<div
id="container"
class="w-4/5 h-4/5 mx-auto rounded-lg overflow-hidden relative group"
>
<figure>
<video class="w-full">
<source src="/oceans.mp4" />
</video>
</figure>
<div
id="controls"
class="opacity-0 p-5 absolute bottom-0 left-0 w-full transition-opacity duration-300 ease-linear group-hover:opacity-100"
>
<div id="progress-bar" class="h-1 w-full bg-white cursor-pointer mb-4">
<div
id="progress-indicator"
class="h-full w-0 bg-indigo-800 transition-all duration-500 ease-in-out"
></div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center justify-between">
<button
id="rewind"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-3xl w-12">replay_10 </i>
</button>
<button
id="play-pause"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-5xl inline-block w-12"
>play_arrow</i
>
</button>
<button
id="fast-forward"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-3xl w-12">forward_10 </i>
</button>
</div>
<div>
<button
id="volume"
class="transition-all duration-100 ease-linear hover:scale-125"
>
<i class="material-icons text-white text-3xl">volume_up</i>
</button>
</div>
</div>
</div>
</div>
<script type="module" src="/main.js"></script>
</body>
</html>
样式.css
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
video::-webkit-media-controls {
display: none;
}
video::-webkit-media-controls-play-button {
display: none;
}
video::-webkit-media-controls-volume-slider {
display: none;
}
video::-webkit-media-controls-mute-button {
display: none;
}
video::-webkit-media-controls-timeline {
display: none;
}
video::-webkit-media-controls-current-time-display {
display: none;
}
}
main.js
"use strict";
const playNpauseBtn = document.querySelector("#play-pause");
const video = document.querySelector("video");
const rewindBtn = document.querySelector("#rewind");
const fastForwardBtn = document.querySelector("#fast-forward");
const volumeBtn = document.querySelector("#volume");
const progressIndicator = document.querySelector("#progress-indicator");
const progessBar = document.querySelector("#progress-bar");
function playNpauseFn() {
video.paused ? video.play() : video.pause();
}
function updatePlayNPauseIcon() {
const icon = playNpauseBtn.querySelector("i");
icon.textContent = "";
icon.textContent = video.paused ? "play_arrow" : "paused";
}
function rewindNforwardFn(type) {
video.currentTime += type === "rewind" ? -10 : 10;
}
function muteNunmuteFn() {
video.muted = video.muted ? false : true;
}
function updateVolumeIcon() {
const icon = volumeBtn.querySelector("i");
icon.textContent = "";
icon.textContent = video.muted ? "volume_off" : "volume_up";
}
function updateProgress() {
const progressPercentage = (video.currentTime / video.duration) * 100;
progressIndicator.style.width = `${progressPercentage}%`;
}
function seekingFn(e) {
const updatedTime = (e.offsetX / progessBar.offsetWidth) * video.duration;
video.currentTime = updatedTime;
}
video.addEventListener("play", updatePlayNPauseIcon);
video.addEventListener("click", playNpauseFn);
video.addEventListener("pause", updatePlayNPauseIcon);
playNpauseBtn.addEventListener("click", playNpauseFn);
rewindBtn.addEventListener("click", () => rewindNforwardFn("rewind"));
fastForwardBtn.addEventListener("click", () => rewindNforwardFn("forward"));
video.addEventListener("volumechange", updateVolumeIcon);
volumeBtn.addEventListener("click", muteNunmuteFn);
video.addEventListener("timeupdate", updateProgress);
let mouseIsDown = false;
progessBar.addEventListener("mousedown", () => (mouseIsDown = true));
progessBar.addEventListener("mouseup", () => (mouseIsDown = false));
progessBar.addEventListener("click", seekingFn);
progessBar.addEventListener("mousemove", (e) => mouseIsDown && seekingFn);
window.addEventListener("keyup", (e) => {
if (e.code === "Space") {
playNpauseFn();
} else if (e.code === "ArrowLeft") {
rewindNforwardFn("rewind");
} else if (e.code === "ArrowRight") {
rewindNforwardFn("forward");
} else {
return;
}
});
或者,您也可以在我上传的附件找到所有代码。
您可以通过此处访问实时站点。
视频 API 提供了丰富的功能供您尝试,例如添加播放速率控制、音量调节,甚至字幕。您还可以通过动画和交互来增强项目,并确保其对移动设备的响应能力,甚至可以为移动设备启用横屏模式。
想要获得更多灵感和想法,欢迎点击此处查看我的项目版本。
结论
恭喜!您已阅读完本文,并获得了构建自定义 HTML5 视频播放器的宝贵实践经验。通过整合键盘导航并优化可访问性,您确保了流畅的用户体验。
感谢您的阅读,下次再见!