浏览器中视频播放器实现的基本思路与代码
目录
- 前言
- 浏览器中的音视频知识总结
- 视频编码
- 封装格式
- 音视频标签
- 常用属性
- 常用事件
- 常用方法
- 整体思路如下
- 代码实现
- 总结
前言 自定义个播放器,组件都是用的原生的,所以有点丑,重点关注业务逻辑吧。
界面大概长下面这个样子。
大家可以看着界面,在脑海中想一下自己会如何实现这个视频播放器。可以问自己以下几个问题:
- 这个组件会接受那些props
- 如何获取视频的基本信息,包括时长,分辨率等
- 暂停、播放如何实现
- 拖动进度条的逻辑如何实现
- 视频初始加载显示loading如何处理
- 视频播放过程中卡顿显示loading如何处理
浏览器中的音视频知识总结
视频编码
视频,其实就是一系列连续播放的图片,如果1s钟播放24张图片,视频的帧率就是24。
如果视频的的尺寸是1920*1080,即一张图片的尺寸是1920*1080*3 bytes,乘3是因为一个像素点3个比特,分别存放rbg,那么一个30分钟的视频所需要的存储空间如下:
//1s视频需要的存储空间为:1920*1080*3*24 bytes//30min视频需要的存储空间:1920*1080*3*24 * 60*30=250.28GB
可以看到,非常大,所以视频需要压缩,于是就有了编码(codec)的概念。视频的编码格式可以理解为压缩格式,不同的编码格式压缩率不同,常见的编码格式有 h264,mpeg4,vp8等。
此外,需要注意的一点是,因为编码格式是有版权问题的,所以不同的浏览器支持的编码格式不同,所以就会出现有些编码格式的视频在某些浏览器播放不了,或者只有声音没有画面的情况。
我们前端开发只需要记住一点,主流浏览器支持的视频编码格式是h264。
封装格式
一个视频文件内会包含视频流和音频流,还有一些元数据,例如分辨率信息,标题等,这个文件的格式我们称为封装格式,可以理解为打包格式,常见的mp4,webp,mov,mpeg等都是封装格式。
封装格式往往是与视频编码无关的,一个mp4文件,里面的视频流编码可以是h264,也可以是mpeg,所以就会出现,同样都是mp4文件,有的浏览器可以放,有的浏览器就放不了的问题。
音视频标签
src指定资源地址,poster为视频指定一张封面图,controls表示浏览器应该显示UI控件(每个浏览器样式不同)
常用属性
下面是video和audio的通用属性
文章图片
常用事件
video和audio通用事件
文章图片
常用方法
- play() 控制视频开始播放
- pause() 控制视频暂停播放
整体思路如下
- 该组件接收一个视频的src作为参数
- 监听onLoadedMetadata事件,获取视频时长(duration),真实宽高(videoWidth,videoHeight)
- 点击播放/暂停时,调用视频元素的play/pause方法
- 播放时,监听onTimeUpdate,获取当前播放时间(currentTime),计算出进度条的进度
- 拖动进度条,设置视频当前播放时间,与步骤4相反
- 视频初始加载时,显示loading。即组件初次渲染时,loading属性默认为true,即显示加载效果,当视频元数据加载时,取消loading
- 视频卡顿时,显示loading。该功能的实现是监听的onWaiting事件,不卡顿时,取消loading,监听的是onCanPlay事件
代码实现
代码是用React实现的,用Vue也是一样的,关注业务逻辑即可。如果大家有需求,我可以再更新下这篇文章,添加上Vue的代码。
注意:dom原生事件在react中需要前面加个on,然后写成驼峰的形式
function formatDuration(duration) {var sec_num = parseInt(duration, 10); // don't forget the second paramvar hours= Math.floor(sec_num / 3600); var minutes = Math.floor((sec_num - (hours * 3600)) / 60); var seconds = sec_num - (hours * 3600) - (minutes * 60); if (hours< 10) {hours= "0"+hours; }if (minutes < 10) {minutes = "0"+minutes; }if (seconds < 10) {seconds = "0"+seconds; }return hours+':'+minutes+':'+seconds; }import React, { createRef, useState } from 'react'import './VideoPlayer.css'function VideoPlayer({src}){const videoDom=createRef()// 视频当前播放时间const [curTime,setCurTime]=useState(0)// 视频时长const [duration,setDuration]=useState(0)// 视频状态,是否暂停const [isPause,setPause]=useState(true)// 视频真是尺寸const [size,setSize]=useState({width:1920,height:1080})// 视频加载中const [waiting,setWaiting]=useState(true)// 视频元数据加载成功const onLoad=(e)=>{const {duration,videoWidth,videoHeight}=e.targetsetDuration(duration)setSize({width:videoWidth,height:videoHeight})setWaiting(false)}// 控制播放暂停const handlePlay=(play)=>{const v=videoDom.currentif(play){setPause(false)v.play()}else{setPause(true)v.pause()}}// 拖动slider时改变视频currentTimeconst onSliderChange=(e)=>{setCurTime(e.target.value)videoDom.current.currentTime=e.target.value}// 监听video timeupdateconst onTimeUpdate=()=>{const v=videoDom.currentsetCurTime(v.currentTime)if(v.ended){handlePlay(false)v.currentTime=0}}// 卡顿时,显示加载中提示const onWaiting=()=>{setWaiting(true)}// 可以播放时,隐藏加载中提示const onCanPlay=()=>{setWaiting(false)}return {/* 视频加载时显示loading */}{waiting && loading...}{/* 播放按钮 */}{isPause? : }{/* 进度条 */}{/* 时间信息和分辨率信息 */}{formatDuration(curTime)}/{formatDuration(duration)}分辨率:{size.width}x{size.height}}export default VideoPlayer
样式写了一点点,VideoPlayer.css
.video-wrapper{width:800px; }.video-wrapper>video{width: 100%; }.video-controls{margin-top: 20px; }
本文的重点不在于React,React只是一个载体,同样的逻辑可以很容易地用Vue实现,重点在于自定义一个视频播放器的逻辑。
总结 【浏览器中视频播放器实现的基本思路与代码】到此这篇关于浏览器中视频播放器实现的基本思路与代码的文章就介绍到这了,更多相关浏览器中视频播放器实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 热闹中的孤独
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 异地恋中,逐渐适应一个人到底意味着什么()
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- “成长”读书社群招募
- 2020-04-07vue中Axios的封装和API接口的管理