前言

自定义个播放器,组件都是用的原生的,所以有点丑,重点关注业务逻辑吧。

界面大概长下面这个样子。

大家可以看着界面,在脑海中想一下自己会如何实现这个视频播放器。可以问自己以下几个问题:

  • 这个组件会接受那些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文件,有的浏览器可以放,有的浏览器就放不了的问题。

音视频标签

<video controls poster="1.jpg" src="1.mp4" loop muted></video>
<audio controls src="1.mp3"></audio>

src指定资源地址,poster为视频指定一张封面图,controls表示浏览器应该显示UI控件(每个浏览器样式不同)

常用属性

下面是video和audio的通用属性

常用事件

video和audio通用事件

常用方法

  • play() 控制视频开始播放
  • pause() 控制视频暂停播放

有了上述的属性、事件及方法,我们就可以做很多事了,比如自定义播放器,使用播放器本地预览视频等。

整体思路如下

  1. 该组件接收一个视频的src作为参数
  2. 监听onLoadedMetadata事件,获取视频时长(duration),真实宽高(videoWidth,videoHeight)
  3. 点击播放/暂停时,调用视频元素的play/pause方法
  4. 播放时,监听onTimeUpdate,获取当前播放时间(currentTime),计算出进度条的进度
  5. 拖动进度条,设置视频当前播放时间,与步骤4相反
  6. 视频初始加载时,显示loading。即组件初次渲染时,loading属性默认为true,即显示加载效果,当视频元数据加载时,取消loading
  7. 视频卡顿时,显示loading。该功能的实现是监听的onWaiting事件,不卡顿时,取消loading,监听的是onCanPlay事件

代码实现

代码是用React实现的,用Vue也是一样的,关注业务逻辑即可。如果大家有需求,我可以再更新下这篇文章,添加上Vue的代码。

注意:dom原生事件在react中需要前面加个on,然后写成驼峰的形式

function formatDuration(duration) {
    var sec_num = parseInt(duration, 10); // don't forget the second param
    var 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.target
        setDuration(duration)
        setSize({width:videoWidth,height:videoHeight})
        setWaiting(false)
    }
    // 控制播放暂停
    const handlePlay=(play)=>{
        const v=videoDom.current
        if(play){
            setPause(false)
            v.play()
        }else{
            setPause(true)
            v.pause()
        }

    }
    // 拖动slider时改变视频currentTime
    const onSliderChange=(e)=>{
        setCurTime(e.target.value)
        videoDom.current.currentTime=e.target.value

    }
    // 监听video timeupdate
    const onTimeUpdate=()=>{
        const v=videoDom.current
        setCurTime(v.currentTime)
        if(v.ended){
            handlePlay(false)
            v.currentTime=0
        }
    }
    // 卡顿时,显示加载中提示
    const onWaiting=()=>{
        setWaiting(true)
    }
    // 可以播放时,隐藏加载中提示
    const onCanPlay=()=>{
        setWaiting(false)
    }
    return <div className="video-wrapper">
            <video ref={videoDom}  src={src} onLoadedMetadata={onLoad} onTimeUpdate={onTimeUpdate} onWaiting={onWaiting} onCanPlay={onCanPlay}  ></video>
            {/* 视频加载时显示loading */}
            {waiting && <div className="waiting">loading...</div>}
            <div className="video-controls">
                {/* 播放按钮 */}
                {isPause? <button onClick={()=>{handlePlay(true)}}>播放</button>: <button onClick={()=>{handlePlay(false)}}>暂停</button>}
                {/* 进度条 */}
                <input type="range" min="0" max={duration}  value={curTime} onChange={onSliderChange}/>
                {/* 时间信息和分辨率信息 */}
                <span>{formatDuration(curTime)}/{formatDuration(duration)}</span>
                <span>分辨率:{size.width}x{size.height}</span>
            </div>
        </div>
}
export default VideoPlayer

样式写了一点点,VideoPlayer.css

.video-wrapper{
    width:800px;
}
.video-wrapper>video{
    width: 100%;
}

.video-controls{
    margin-top: 20px;
}

本文的重点不在于React,React只是一个载体,同样的逻辑可以很容易地用Vue实现,重点在于自定义一个视频播放器的逻辑。

总结

到此这篇关于浏览器中视频播放器实现的基本思路与代码的文章就介绍到这了,更多相关浏览器中视频播放器实现内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

浏览器中视频播放器实现的基本思路与代码的更多相关文章

  1. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  2. VUE响应式原理的实现详解

    这篇文章主要为大家详细介绍了VUE响应式原理的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

  3. 五分钟理解keep alive用法及原理

    这篇文章主要为大家介绍了keep alive用法及原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. iOS基于AVFoundation 制作用于剪辑视频项目

    这篇文章主要为大家介绍了利用AVFoundation 制作用于剪辑视频的项目,可以实现视频扩展或者回退的功能,感兴趣的小伙伴快来跟随小编一起学习吧

  5. jQuery插件JWPlayer视频播放器用法实例分析

    这篇文章主要介绍了jQuery插件JWPlayer视频播放器用法,结合实例形式分析了JWPlayer插件播放视频的相关操作技巧,需要的朋友可以参考下

  6. android实现音乐播放器

    这篇文章主要为大家详细介绍了android实现音乐播放器,拥有播放、暂停、重新播放和停止等功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  7. 使用Compose制作抖音快手视频进度条Loading动画效果

    这篇文章主要为大家介绍了使用Compose制作抖音快手视频进度条Loading动画效果,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  8. PHP架构及原理知识点详解

    这篇文章主要介绍了PHP架构及原理知识点以及相关实例讲解,需要的朋友们参考下。

  9. DialogFragment运行原理及使用方法详解

    这篇文章主要介绍了DialogFragment运行原理及使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  10. iOS中的音频服务和音频AVAudioPlayer音频播放器使用指南

    这里我们要介绍的是AVAudio ToolBox框架中的AudioServicesPlaySystemSound函数创建的服务,特别适合用来制作铃声,下面就简单整理一下iOS中的音频服务和音频AVAudioPlayer音频播放器使用指南:

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部