利用 JavaScript 构建高级视频播放器

前言

在当今数字化的时代,视频内容在我们的日常生活中扮演着至关重要的角色。无论是在线教育、娱乐还是信息传播,一个能够满足用户需求的播放器都能极大地提升用户体验。

html部分

首先我们页面是这样的。

视频上方有一个文件输入框,视频居中在页面上。视频的右边有一个滑块,用来控制视频的播放速度;滑块上的数值为播放速率。

html 复制代码
<main class="container">
    <label for="file-upload" class="custom-file-upload">
        <input type="file" id="file-upload" accept="video/*">
        上传视频
    </label>
    <div id="video-container">
        <div class="wrapper">
            <!-- 行内块元素 -->
            <video src="" width="765" height="430" controls id="video"></video>
            <div class="speed">
                <div class="speed-bar">1x</div>
            </div>
        </div>
    </div>
</main>

思路

首先我们用wrapper盒子包括视频和滑块,再用container盒子包括wrapper盒子和文件输入框。这样我们就有大概的html框架思路。

  • container盒子的标签我们使用main而不使用div,是因为mian更具有语义化,表示这个页面的主体内容。
  • label标签用于将表单中的输入元素(如文本输入框、单选按钮、复选框等)与相关的文本描述关联起来。label标签通过将 for 属性值设置为输入元素的 id 属性值,建立与输入元素的关联。
  • 在input标签中type="file"表示该输入框为文件输入框。accept="video/*"表示该文件输入框只接收视频文件。
  • video标签的controls表示显示视频控制器。

css部分

首先在写css代码的第一步就是清除所有标签的默认内边距和外边距。

css 复制代码
* {
    margin: 0;
    padding: 0;
}

然后我们为了让我们的页面更好看,我们可以添加页面背景,我们要将背景添加到body标签中才能覆盖整个页面。

css 复制代码
body {
    background-image: url(./11.jpg);
    background-size: 100%;
}

我们看wrapper盒子里的css样式。

css 复制代码
.wrapper {
    /* 固定定位,以浏览器屏幕(可视窗口)为参考系 */
    position: fixed;
    /* 相对于浏览器屏幕向左移动百分之五十 */
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
}

为了让将 .wrapper元素固定在浏览器窗口的中央位置。

  • 首先给.wrapper元素相对于浏览器窗口进行定位
  • 将元素的左侧和顶部定位到窗口的 50% 位置
  • 使用 translate 方法将元素在水平和垂直方向上各移动自身宽度和高度的 50%,以实现居中效果。

display: flex; 将元素设置为 Flex 布局,允许在该元素内进行灵活的子元素排列。

滑块的css样式

css 复制代码
.speed {
    width: 50px;
    height: 430px;
    background-color: #fff;
    border-radius: 50px;
    /* 允许内容溢出并隐藏 */
    overflow: hidden;
}

.speed-bar {
    width: 100%;
    height: 16%;
    background: linear-gradient(to bottom, #2376ae, #c16ecf);
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
}
  • .speed-bar元素生成了一个从顶部的#2376ae 到底部的#c16ecf 的线性渐变。
css 复制代码
background: linear-gradient(to bottom, #2376ae, #c16ecf);
  • 使用 flex 布局,使子元素在水平和垂直方向上居中对齐。

    css 复制代码
    display: flex;
    justify-content: center;
    align-items: center;
  • 设置鼠标指针为指针样式

    css 复制代码
    cursor: pointer;

JavaScript部分

我们现在还不知道要视频的URL,我们要获得视频的URL并且赋值给id为"video"的video标签的src属性。

javascript 复制代码
const fileUpload = document.getElementById('file-upload');
const video = document.getElementById('video');

fileUpload.addEventListener('change', function (e) {
    const file = e.target.files[0];
    const reader = new FileReader();
    reader.onload = function (e2) {
        video.src = e2.target.result;
    }
    reader.readAsDataURL(file)
})

首先我们是思路是这样:

  • 首先我们创建一个fileUpload对象获取#file-upload元素,创建一个video对象获取#video元素
  • 对fileUpload对象添加一个change事件监听,实现当用户更改上传文件时,触发事件处理函数function(e)实现读取文件并且使video标签获取视频的URL。
  • function(e)里的function(e2)函数是在读取完文件后使video标签获取视频的URL。

接下来我们要通过JavaScript实现当鼠标在 .speed元素上移动时,实时根据鼠标的位置来调整 .speed-bar 元素的高度,并同步更新视频的播放速度。

JavaScript 复制代码
var speed = document.querySelector('.speed')
var speedBar = document.querySelector('.speed-bar')

speed.addEventListener('mousemove', function (e) {
    var y = e.pageY - speed.getBoundingClientRect().top
    var percent = y / speed.offsetHeight
    var height = Math.round(percent * 100) + '%'
    speedBar.style.height = height
    var min = 0.4
    var max = 4
    var palySpeed = percent * (max - min) + min
    speedBar.textContent = palySpeed.toFixed(2) + 'x'
    video.playbackRate = palySpeed
})
  • 首先获取页面上具有 .speed'类和.speed-bar的元素
  • 为 speed 元素添加鼠标移动事件监听器
    • 获取鼠标在 speed 元素上的垂直位置(相对于元素顶部)
    • 计算垂直位置占 speed 元素高度的百分比
    • 将百分比转换为实际的高度值,并取整后加上 '%' 符号
    • 使用 JavaScript 修改 speedBar 元素的高度为计算得到的高度
    • 设置最小和最大播放速度范围,根据百分比计算实际的播放速度,将播放速度显示在 speedBar 元素的文本内容中
    • 将视频的播放速度设置为计算得到的播放速度

效果展示

快动手制作一个属于自己的视频播放器吧。

相关推荐
m0_748247552 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
m0_748255022 小时前
前端常用算法集合
前端·算法
真的很上进2 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203982 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2343 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
如若1233 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~4 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语4 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport4 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg4 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全