自定義視頻播放器(功能包括:播放/暫停,全屏,跳播)


最終效果:

 

1、demo結構

fontawesome字體下載:http://fontawesome.dashgame.com/

loading.gif:百度loading.gif選擇一張下載

 

2、index.html

  功能包括:播放/暫停,全屏,跳播

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>自定義視頻播放器</title>
    <link rel="stylesheet" href="./css/font-awesome.min.css">
    <link rel="stylesheet" href="./css/index.css">                   
</head>
<body>
<h3 class="player-title">視頻播放器</h3>
<div class="player-container">
    <video src="./mp4/test.mp4"></video>
    <div class="controls-container">
        <!-- 播放/暫停 -->
        <a href="javascript:;" class="switch fa fa-play"></a>
        <!-- 全屏 -->
        <a href="javascript:;" class="expand fa fa-expand"></a>
        <!-- 進度條 -->
        <div class="progress"><!-- 進度條底色 -->
            <div class="bar"></div><!-- 進度條最外層,用於事件控制 -->
            <div class="loaded"></div><!-- 已加載 -->
            <div class="current-progress"></div><!-- 已播放 -->
        </div>
        <!-- 當前播放時間, 視頻總長 -->
        <div class="time">
            <span class="current-time">00:00:00</span>
            \
            <span class="total-time">00:00:00</span>
        </div>
    </div>
</div>

<script type="text/javascript">
    // 播放器
    const video = document.querySelector('video');
    // "播放/暫停"切換按鈕
    const switchBtn = document.querySelector('.switch');
    // 當前播放時間span
    const currentTimeSpan = document.querySelector('.current-time')
    // 視頻總時長
    const totalTimeSpan = document.querySelector('.total-time')
    // 當前播放進度條
    const currentProgress = document.querySelector('.current-progress')
    // 獲取進度條最外層,用於事件控制
    const bar = document.querySelector('.bar');

    // 實現"播放/暫停"
    switchBtn.onclick = function() {
        // 播放與暫停的切換
        if (video.paused) {
            video.play();
        } else {
            video.pause();
        }
        // 播放與暫停圖標的切換
        this.classList.toggle('fa-pause');
        this.classList.toggle('fa-play');
    }

    // 實現"全屏"
    const playerContainer = document.querySelector('.player-container');
    document.querySelector('.expand').onclick = function() {
        if(playerContainer.requestFullScreen){
            playerContainer.requestFullScreen();
        } else if(playerContainer.webkitRequestFullScreen){
            playerContainer.webkitRequestFullScreen();
        } else if(playerContainer.mozRequestFullScreen){
            playerContainer.mozRequestFullScreen();
        } else if(playerContainer.msRequestFullScreen){
            playerContainer.msRequestFullScreen();
        }
    }

    // 當視頻文件可以播放時觸發
    // 當跳播時,修改了video.currentTime,也會觸發該事件
    video.oncanplay = function() {
        console.log('觸發oncanplay事件, video.currentTime=', video.currentTime)
        if (video.currentTime === 0) {
            setTimeout(function() {
                console.log('視頻緩存完成,可以播放了。。。')
                // 顯示視頻第一幀畫面
                video.style.display = 'block'
                // 獲取當前視頻文件總時長
                const totalTime = video.duration;
                console.log(`當前視頻文件總時長: ${totalTime}秒`); // 單位為秒, 292.975736
                // 頁面顯示視頻總時長
                totalTimeSpan.innerHTML = getTime(totalTime);
            }, 2000)
        }

    }

    // 當視頻播放的時候會觸發ontimeupdate事件,進度條同步,當前時間同步
    // 當跳播時,修改了video.currentTime,也會觸發該事件
    video.ontimeupdate = function() {
        console.log('觸發ontimeupdate事件。。。')
        // 獲取當前時間
        const currentTime = video.currentTime;
        // 計算出視頻的總時長
        const totalTime = video.duration;
        // 顯示當前播放時間
        currentTimeSpan.innerHTML = getTime(currentTime);
        //進度條同步: 當前時間/總時間
        const value = currentTime / totalTime;
        currentProgress.style.width = value * 100 + "%";
        //當播放完畢之后,播放暫停按鈕要轉換成暫停按鈕
        if (currentTime === totalTime) {
            switchBtn.classList.remove('fa-pause');
            switchBtn.classList.add('fa-pause');
        }
    }

    // 實現視頻跳播
    bar.onclick = function(e) {
        // 獲取鼠標點擊位置相對bar最左側的距離
        const offset = getOffsetX(e);
        // 獲取bar的寬度
        const barWidth = this.style.width || this.clientWidth || this.offsetWidth || this.scrollWidth;
        console.log(`offset=${offset}, barWidth=${barWidth}`)
        const percent = offset / barWidth;
        const currentTime = percent * video.duration;
        video.currentTime = currentTime;
    }

    function getTime(time) {
        //轉換時長
        let h = Math.floor(time / 3600);
        let m = Math.floor(time % 3600 / 60);
        let s = Math.floor(time % 60);
        //轉換格式
        h = h > 10 ? h : "0" + h;
        m = m > 10 ? m : "0" + m;
        s = s > 10 ? s : "0" + s;
        return h + ":" + m + ":" + s;
    }

    // 火狐瀏覽器不支持e.offsetX,解決方法
    function getOffsetX(e){
        var e = e || window.event;
        var srcObj = e.target || e.srcElement;
        if (e.offsetX) {
            return e.offsetX;
        } else {
            var rect = srcObj.getBoundingClientRect();
            var clientx = e.clientX;
            return clientx - rect.left;
        }
    }
</script>
</body>
</html>

 

3、index.css

body {
    padding: 0;
    margin: 0;
    font-family: 'microsofy yahei';
    background-color: #F7F7F7;
}

a {
    text-decoration: none;
}

.player-title {
    width: 100%;
    margin: 0 auto;
    line-height: 100px;
    font-size: 40px;
    text-align: center;
}

.player-container {
    width: 720px;
    height: 360px;
    margin: 0 auto;
    background: url('../images/loading.gif') center no-repeat;
    background-size: cover;
    position: relative;
}
video {
    height: 100%;
    margin: 0 auto;
    display: none;
}

/* ================ 播放器控制面板樣式 start ================ */
.controls-container {
    width: 720px;
    height: 40px;
    position: absolute;
    left: 0px;
    bottom: -40px;
    background-color: #000;
}

/* 播放/暫停 */
.controls-container .switch {
    width: 20px;
    height: 20px;
    display: block;
    font-size: 20px;
    color: #fff;
    position: absolute;
    left: 10px;
    top: 10px;
}
/* 全屏 */
.controls-container .expand {
    width: 20px;
    height: 20px;
    display: block;
    font-size: 20px;
    color: #fff;
    position: absolute;
    right: 10px;
    top: 10px;
}
/* 進度條 */
.controls-container .progress {
    width: 430px;
    height: 10px;
    position: absolute;
    left: 40px;
    bottom: 15px;
    background-color: #555;
}
.controls-container .progress .bar {
    /*width: 100%;*/
    width: 430px;
    height: 100%;
    border-radius: 3px;
    cursor: pointer;
    position: absolute;
    left: 0;
    top: 0;
    opacity: 0;
    z-index: 999;
}
.controls-container .progress .loaded {
    width: 60%; /* 視頻緩存的進度, 后期可動態變化 */
    height: 100%;
    background-color: #999;
    border-radius: 3px;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
}
.controls-container .progress .current-progress {
    width: 0%; /* 初始播放進度為0 */
    height: 100%;
    background-color: #fff;
    border-radius: 3px;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 3;
}
.controls-container .time {
    height: 20px;
    position: absolute;
    left: 490px;
    top: 10px;
    color: #fff;
    font-size: 14px;
}
/* ================ 播放器控制面板樣式 end ================ */

 

4、測試

  1)打開index.html頁面,視頻加載完成打印"視頻緩存完成,可以播放了。。。";

  2)點擊進度條某個位置,首先觸發了bar.onclick事件,計算並更新video.currentTime;然后觸發了ontimeupdate事件和oncanplay事件。

 

  3)點擊播放按鈕;

  4)播放完畢后,發現一個小bug

  解決:

  刪除代碼:

//當播放完畢之后,播放暫停按鈕要轉換成暫停按鈕
// if (currentTime === totalTime) {
//     switchBtn.classList.remove('fa-pause');
//     switchBtn.classList.add('fa-pause');
// }

  添加代碼:

// 視頻播放完畢,重置播放狀態為初始狀態
video.onended = function() {
    video.currentTime = 0;
    switchBtn.classList.remove('fa-pause');
    switchBtn.classList.add('fa-pause');
}

 ---


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM