前端练习五:HTML5音乐播放器

html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <link rel="stylesheet" href="css/main.css">
</head>
<body>
    <input type="file" id="file" accept="audio/mp3,audio/ogg" multiple>
    <article id="music-player">
        <audio id="player">
        </audio>

        <section id="music-content">
            <div id="album-picture">
                <img src="img/timg.jpg" id="picture">
            </div>

            <span id="add-music" title="添加音乐"><i class="fa fa-upload" aria-hidden="true"></i></span>

            <div>
                <h3 id="music-title">Welcome to you!</h3>
                <p id="music-singer">Have a good time!</p>
            </div>

            <div id="music-control">
                <button id="music-stop">
                    <i class="fa fa-play" aria-hidden="true" id="control-icon"></i>
                </button>

                <button id="music-pre" title="上一首">
                    <i class="fa fa-fast-backward" aria-hidden="true"></i>
                </button>

                <button id="music-next" title="下一首">
                    <i class="fa fa-fast-forward" aria-hidden="true"></i>
                </button>

                <div id="sound-icon">                    
                    <i class="fa fa-volume-up" aria-hidden="true" id="volume"></i>
                    <i class="fa fa-minus-circle" aria-hidden="true" id="volume-down" title="降低"></i>
                    <progress value="10" max="10" id="music-sound"></progress>
                    <i class="fa fa-plus-circle" aria-hidden="true" id="volume-up" title="提高"></i>
                </div>
            </div>
        </section>
        <aside>
            <div><progress value="0" max="100" id="music-progress"></progress></div>
            <span id="current-time">0:00</span><span id="duration">/0:00</span>
            <img src="img/loop.png" id="play-style-loop" title="顺序播放" class="">    
            <img src="img/random.png" id="play-style-random" title="随机播放" class="hidden">    
        </aside>
    </article>

    <article id="music-list">
        <ul id="musics"></ul>
    </article>

    <script src="js/app.js"></script>
</body>
</html>

 

css文件:main.css

*,*::after,*::before {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html,body {
    height: 100%;
    overflow: hidden;
    font-family: sans-serif;
}
body {
    background-image: linear-gradient(to top, #c1dfc4 0%, #deecdd 100%);
}

article#music-player {
    width: 518px;
    height: 260px;
    margin: 12px auto;
    margin-bottom: 0px;
    padding: 18px;

    border-top-left-radius: 12px;
    border-top-right-radius: 12px;
    background-image: linear-gradient(to right, #243949 0%, #517fa4 100%);
    box-shadow: 1px 0px 2px 2px rgba(0,0,0,.1);
}

section#music-content {
    width: 100%;
    height: 70%;
}

aside {
    width: 100%;
    height: 30%;
}

div#album-picture {
    float: left;

    width: 26%;
    height: 128px;
    margin-right: 36px;

    -webkit-animation: rotate 16s linear 0s infinite;

    border: 2px solid #fff;
    border-radius: 50%;
}

div#album-picture img {
    width: 100%;
    height: 100%;

    border-radius: 50%;
}

#music-title {
    font-size: 18px;
    font-weight: 500;
    margin-bottom: 8px;
    color: #fff;
}

#music-singer {
    font-size: 12px;

    color: #aaa;
}

#music-content {
    position: relative;
}
#music-control {
    display: flex;

    align-items: center;
    position: absolute;
    bottom: 8px;
    left: 164px;
}

#music-stop,
#music-pre,
#music-next {
    font-size: 14px;

    margin-right: 8px;

    cursor: pointer;

    color: #fff;
    border: 2px solid #fff;
    border-radius: 50%;
    background-image: linear-gradient(to top, #1e3c72 0%, #1e3c72 1%, #2a5298 100%);
}

#music-stop:hover,
#music-pre:hover,
#music-next:hover {
    background-image: linear-gradient(to bottom, #1e3c72 0%, #1e3c72 1%, #2a5298 100%);
}

#music-stop, #music-pre, #music-next {
    outline: none;
}

#music-stop {
    width: 48px;
    height: 48px;
}

#music-pre,
#music-next {
    width: 32px;
    height: 32px;
}

#sound-icon {
    font-size: 16px;

    display: flex;

    margin-left: 12px;

    color: #eee;

    justify-content: center;
    align-items: center;
}

#music-sound {
    width: 100px;
    height: 8px;
    margin-left: 8px;

    border-radius: 8px;
    border:1px solid #517fa4;
    cursor: pointer;
}

#music-sound:hover {
    color: #fff;
}

#sound-icon > i {
    margin-left: 4px;

    cursor: pointer;
}

aside {
    margin-top: 18px;
    position: relative;
}

aside div {
    display: flex;

    width: 100%;
    height: 20px;

    border-radius: 12px;
    background: #fff;

    align-items: center;
    justify-content: center;
}
aside progress {
    width: 98%;
    height: 14px;

    border-radius: 12px;
    border: none;
    cursor: pointer;
    background-color: #fff;
}


progress::-webkit-progress-value {
    border-radius: 12px;
    background-image: linear-gradient(to right, #243949 0%, #517fa4 100%);
}

progress::-webkit-progress-bar {
    background-color: #fff;
}

progress::-moz-progress-bar {
    border-radius: 12px;
    background-image: linear-gradient(to right, #243949 0%, #517fa4 100%);
}

#current-time {
    font-size: 12px;

    margin-left: 6px;

    color: #fff;
}

#play-style-loop,#play-style-random {
    display: inline-block;
    position: absolute;
    right: 12px;
    bottom: 12px;
    cursor: pointer;
    visibility: visible;
}

#play-style-loop.hidden, #play-style-random.hidden {
    visibility: hidden;
}

span#duration {
    font-size: 12px;

    margin-left: 6px;

    color: #aaa;
}

#volume-up:hover,
#volume-down:hover {
    color: #fff;
}

@-webkit-keyframes rotate {
    from {
        transform: rotate(0deg);
    } to {
        transform: rotate(360deg);
    }
}

#file {
    display: none;
}

#add-music {
    margin-top: 12px;
    display: inline;
    float: right;
    font-size: 16px;
    color: #fff;
    margin-top: 8px;
    border: none;
    cursor: pointer;
}

article#music-list {
    width: 518px;
    height: 380px;
    margin: 0px auto;
    background-image: linear-gradient(to right, #243949 0%, #517fa4 100%);
    box-shadow: 1px 0px 2px 2px rgba(0,0,0,.1);
    border-bottom-left-radius: 12px;
    border-bottom-right-radius: 12px;
    border-top: 4px solid #fff;
    font-family: sans-serif;
    color: #fff;
    font-size: 18px;
    line-height: 2.5;
    overflow: auto;
}

#music-list ul {
    list-style: none;
}

#music-list li {
    border-bottom: 1px solid #fff;
    padding-left: 24px;
    cursor: pointer;
    position: relative;
}

#music-list li.selected {
    background-color: #243949;
}

#music-list li:hover {
    background-color: #243949;
}
li.play {
    color: #06c;
}

::-webkit-scrollbar {
    background-image: linear-gradient(to right, #243949 0%, #517fa4 100%);
    border-radius: 12px;
}

::-webkit-scrollbar-thumb {
    background-color: #fff;
    border-radius: 12px;
}

::-moz-scrollbar {
    background: linear-gradient(#333, #111);
    border-radius: 12px;
}

::selection {
    background-color: transparent;
}

::-moz-selection {
    background-color: transparent;
}

 

js文件:app.js

(function() {
    var musicControl = document.getElementById("music-stop"),
        player = document.getElementById("player"),
        controlIcon = document.getElementById("control-icon"),
        durationElement = document.getElementById("duration"),
        currentTimeElement = document.getElementById("current-time"),
        progressElement = document.getElementById("music-progress"),
        volumeUpElement = document.getElementById("volume-up"),
        volumeDownElement = document.getElementById("volume-down"),
        volumeProgress = document.getElementById("music-sound"),
        fileElement = document.getElementById("file"),
        nextElement = document.getElementById("music-next"),
        preElement = document.getElementById("music-pre"),
        musicTitleElement = document.getElementById("music-title"),
        addMusicElement = document.getElementById("add-music"),
        albumPicElment = document.getElementById("picture"),
        musicPlayer = document.getElementById("music-player"),
        musicUL = document.getElementById("musics"),
        loopElement = document.getElementById("play-style-loop"),
        randomElement = document.getElementById("play-style-random"),
        liElementsCache = [];

    /* music queue to save and get music to play */
    function MusicQueue() {
        var musics = [];
        var index = -1;
        var loop = true;

        this.setLoop = function() {
            loop = true;
        };

        this.setRandom = function() {
            loop = false;
        };

        this.addMusic = function(music) {
            musics.push(music);
        };

        this.addList = function(list) {
            var length = list.length;

            for(var i = 0; i < length; i++) {
                this.addMusic(list[i]);
            }
        };

        this.getMusic = function() {
            if(loop === true) {
                if(index >= musics.length - 1) {
                    index = -1;
                }
                index += 1;
                return musics[index];
            } else {
                index = Math.floor(Math.random() * musics.length);
                return musics[index];
            }
        };

        this.getPreMusic = function() {
            if(loop) {
                if(index === 0) {
                    return musics[0];
                } else {
                    index -= 1;
                    return musics[index];
                }
            } else {
                return this.getMusic();
            }
        };

        this.getMusicByName = function(name) {
            index = this.getIndexByName(name);
            return musics[index];
        };

        this.getIndexByName = function(name) {
            for(var i = 0; i < musics.length; i++) {
                if(musics[i].name === name) {
                    return i;
                }
            }
        }

        this.getAllMusic = function() {
            return musics;
        };

        this.pushMusics = function(ms) {
            musics = ms;
        };
    }
    /* music queue end */

    /* init view */
    var musicQueue = new MusicQueue(),
        index = 0;

    // 这是初始化的时侯,播放的mp3
    (function init() {
        var music = new Music("独家记忆", "music/独家记忆.mp3");
        musicQueue.addMusic(music);
        musicTitleElement.innerHTML = music.name;
        player.src = music.src;
        setTimeout(setDuration, 500);
        appendMusicToDOM("独家记忆");
        setSelected(index);
    })();
    /* end init view */

    /* register event handler */
    loopElement.addEventListener("click", function(event) {
        musicQueue.setRandom();
        randomElement.classList.remove("hidden");
        loopElement.classList.add("hidden");
    },false);

    randomElement.addEventListener("click", function(event) {
        musicQueue.setLoop();
        loopElement.classList.remove("hidden");
        randomElement.classList.add("hidden");
    }, false);

    // next music logic
    nextElement.addEventListener("click", function(event) {
        preparePlay(musicQueue.getMusic());
    }, false);

    // pre music logic
    preElement.addEventListener("click", function(event) {
        preparePlay(musicQueue.getPreMusic());
    },false);

    musicPlayer.addEventListener("dragover", function(e) {
        e.preventDefault();
    });

    
    musicPlayer.addEventListener("drop", readData, false);
    function readData(e) {
        e.preventDefault();
        var filelist = e.dataTransfer.files;
        if (!filelist) { return; }

        if (filelist.length > 0) {
            var file = filelist[0];
            if((file.type).indexOf("audio") !== -1 && file.size > 8094) {
                musicQueue.addMusic(getMusic(file));
                appendMusicToDOM(file.name);
            }
        }
    }

    var timeId;

    musicControl.addEventListener("click", function() {
        if (player.paused) {
            player.play();
            start();
            timeId = setTimeout(change, 500);
        } else {
            player.pause();
            pause();
            clearTimeout(timeId);
        }
    });

    player.addEventListener("ended", function() {
        var music = musicQueue.getMusic();
        removeSelected(index);
        preparePlay(music);
    });

    volumeDownElement.addEventListener("click", function() {
        var volume = player.volume;
        player.volume = (volume - 0.2 >= 0) ? volume - 0.2 : 0;
        volumeProgress.value = player.volume * 10;
    });

    volumeUpElement.addEventListener("click", function() {
        var volume = player.volume;
        player.volume = (volume + 0.2 <= 1) ? volume + 0.2 : 1;
        volumeProgress.value = player.volume * 10;
    });

    volumeProgress.addEventListener("click", function(event) {
        var t = (event.offsetX / 100).toFixed(1);
        player.volume = t;
        volumeProgress.value = t*10;
    },false);

    fileElement.addEventListener("change", function(event) {

        var files = fileElement.files;
        for(var i = 0; i < files.length; i++) {
            if((files[i].type).indexOf("audio") !== -1 && files[i].size > 8094) {
                var music = getMusic(files[i]);
                musicQueue.addMusic(music);
                appendMusicToDOM(music.name);
            }

        }
    });

    addMusicElement.addEventListener("click", function(event) {
        fileElement.click();
    });

    // set current time by progress element in dom
    progressElement.addEventListener("click", function(event) {
        var t = (event.offsetX / 470).toFixed(2);
        var currentTime = player.duration * t;
        player.currentTime = currentTime;
        change();
    },false);

    musics.addEventListener("dblclick", function(event) {
        var name = event.target.innerHTML;
        preparePlay(musicQueue.getMusicByName(name));
    },false);
    /* end register event handler */

    function start() {
        // change icon
        controlIcon.classList.remove("fa-play");
        controlIcon.classList.add("fa-pause");

        setDuration();
    }

    function pause() {
        controlIcon.classList.remove("fa-pause");
        controlIcon.classList.add("fa-play");
    }

    function preparePlay(music) {
        musicTitleElement.innerHTML = music.name;
        player.src = music.src;

        start();
        changeImage();
        setCurrentTime();

        player.play();
        setTimeout(setDuration, 500);
        clearTimeout(timeId);
        timeId = setTimeout(change, 500);

        removeSelected(index);
        index = musicQueue.getIndexByName(music.name);
        setSelected(index);
    }

    // set music total time in dom
    function setDuration() {
        var total = player.duration;
        total = total ? total : 0;
        durationElement.innerHTML = "/ " + timeFormat(total);
    }

    // set the current time of music in dom
    function setCurrentTime() {
        var total = player.currentTime;
        currentTimeElement.innerHTML = timeFormat(total);
    }

    // transform time format to hh:mm
    function timeFormat(total) {
        var minute = parseInt(total / 60),
            second = parseInt(total - minute * 60),
            result;

        second = (second >= 10) ? second : '0' + second;
        result = minute + ":" + second;
        return result;
    }

    // update the progress
    function change() {
        setCurrentTime();
        var currentTime = player.currentTime,
            duration = player.duration;

        var progress = (currentTime / duration).toFixed(2) * 100;
        progress = progress <= 100 ? progress : 100;
        progressElement.value = progress;

        timeId = setTimeout(change, 500);
    }

    function getMusic(file) {
        var url = URL.createObjectURL(file);
        return new Music(file.name, url);
    }

    function Music(name, src) {
        this.name = name;
        this.src = src;
    }

    function changeImage() {
        var num = parseInt(Math.random() * 16),
            src;    

        num = (num > 0) ? num : num + 1;
        src = "img/" + num + ".jpg";
        albumPicElment.src = src;
    }

    function appendMusicToDOM(name) {
        var li = document.createElement("li");
        var text = document.createTextNode(name);
        li.appendChild(text);
        liElementsCache.push(li);
        musicUL.appendChild(li);
    }

    function setSelected(index) {
        liElementsCache[index].classList.add("selected");
        liElementsCache[index].scrollIntoView(false);
    }

    function removeSelected(index) {
        liElementsCache[index].classList.remove("selected");
    }
})();

 

 

参考:https://github.com/hwaphon/HTML5MusicPlayer

 

posted on 2018-12-26 22:37  myworldworld  阅读(729)  评论(0)    收藏  举报

导航