• 自定义css样式结合js控制audio做音乐播放器


    最近工作需求需要播放预览一些音乐资源,所以自己写了个控制audio的音乐播放器。

    实现的原理主要是通过js调整audio的对象属性及对象方法来进行控制:

    1.通过play()、pause()来控制音乐的播放与暂停

    2.通过duration、currentTime获取音乐长度及实时播放进度

    3.通过volume、muted对音量大小进行调节

    4.通过ended、error检测音乐的播放状态

    首先来看一下实现效果:当播放点击音乐时该音乐展示播放进度、进度条、音乐条

    本例子实际效果(博客园不允许添加audio,所以只能展示样式):

     
     
    05:18
    老街
    作者: 李荣浩
    上传时间: 2019-01-01 12:25:34
    收藏量: 5426
    04:03
    七友
    作者: 梁汉文
    上传时间: 2019-01-06 14:32:28
    收藏量: 1215

    首先要实现的是音乐的播放与暂停,当点击播放按钮时首先通过对比音乐是否控制当前播放音乐还是更换音乐播放,如果是控制当前音乐则通过play()、paused()进行播放及暂停,如果是更换音乐则先删除原播放进度条及音乐条,然后重新载入进行播放

    function playMusic(obj) {
      var musicPlayUrl = musicPlayer.src
      var thisKey = $(obj).data('key')
      clearInterval(musicPlayerTimer)
      
      $('.music-play').removeClass('current')
      
      if(musicPlayUrl == thisKey){
        //停止播放音乐
        if(musicPlayer.paused){
          $(obj).parent().parent().addClass('current')
          musicPlayer.play()
          musicPlayerTimer = setInterval(musicPlayProgress,1000)
        }else{
          musicPlayer.pause()
        }
      }else{
        //更换音乐播放
        musicPlayer.src = thisKey
        musicPlayer.play()
        $(obj).parent().parent().addClass('current')
        $('#musicplayer-bar-container,#musicplayer-volume-container,#music-play-time').remove()
        var thisCon = $(obj).parent().parent()
        var musicPlayerBarHtml = `<div class="progress" id="musicplayer-bar-container">
                              <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" style=" 0%;" id="music-player-bar">
                              </div>
                          </div>`
        var musicPlayerVolumeHtml = `<div id="musicplayer-volume-container">
                          <div id="musicplayer-volume-bar-container">
                            <div id="musicplayer-volume-bar"></div>
                          </div>
                          <div class="musicplayer-volume-icon">
                            <a href="javascript:;" onclick="muteSetting(this)"><i class="iconfont">�</i></a>
                          </div>
                        </div>`                      
        thisCon.append(musicPlayerBarHtml,musicPlayerVolumeHtml)
        $(obj).parent().parent().find('.music-length').append('<span id="music-play-time"></span>')
      }
    }
    

      

    在播放途中通过duration、currentTime计算当前播放进度并用定时器实时加载进度条,同时通过ended、error检测音乐播放是否出现错误,或者播放完成

    // 检测播放进度
    function musicPlayProgress(){
        var musicTotalLength = musicPlayer.duration
        var musicCurrentLength = musicPlayer.currentTime
        var musicProgress = (musicCurrentLength / musicTotalLength) * 100 + '%'
        $('#music-play-time').html(timeConversion(musicCurrentLength) + ' / ' + timeConversion(musicTotalLength))
        $('#music-player-bar').css('width',musicProgress)
        if(musicPlayer.ended){
          // 检测是否暂停状态
          $('.music-play').removeClass('current')
        }
        if(musicPlayer.error != null){
          // 检测是否播放错误
          clearInterval(musicPlayerTimer)
          $('.music-play').removeClass('current')
          alert('音乐播放错误!')
        }
    }
    

      

    因为duration、currentTime获取到的单位是秒,所以需要对其进行时间格式的转换

    // 时间格式转换
    function timeConversion(time){
      var seconds = parseInt(time)   // 秒
      var minutes = 0                // 分
      var hours = 0                  // 小时
      if(seconds > 60) {
          minutes = parseInt(seconds/60);
          seconds = parseInt(seconds%60);
          if(minutes > 60) {
              hours = parseInt(minutes/60);
              minutes = parseInt(minutes%60);
          }
      }
      var result = ''
      if(seconds < 10)
        seconds = '0' + seconds
      if(minutes < 10)
        minutes = '0' + minutes
      if(hours > 0) {
        if(hours < 10)
          hours = '0' + hours
        result = hours + ':' + minutes + ":" + seconds
      }else{
        result = minutes + ":" + seconds
      }
      return result
    }
    

      

    当点击静音按钮时通过muted、volume来设置当前播放的音乐静音状态

    // 静音设置
    function muteSetting(obj){
      var isHasMute = $(obj).parent().hasClass('mute')
      if(isHasMute){
        // 开启声音
        musicPlayer.muted = false
        musicPlayer.volume = 1
        $(obj).find('i').html('�')
        $(obj).parent().removeClass('mute')
        $('#musicplayer-volume-bar').css('height','0%')
      }else{
        // 设置静音
        musicPlayer.muted = true
        $(obj).find('i').html('�')
        $(obj).parent().addClass('mute')
        $('#musicplayer-volume-bar').css('height','100%')
      }
    }
    

      

    当用户点击进度条时通过offsetX、offsetY获取到点击到的百分比值,然后对其设置currentTime、volume来进行操作

    // 控制进度条
      $('#musicplayer-bar-container').bind('click',function(e){
        var leftDistance = e.offsetX
        var clickProgress = (leftDistance / $(this).width())
        musicPlayer.currentTime = musicPlayer.duration * clickProgress
        $('#music-player-bar').css('width',clickProgress * 100 + '%')
      })
    
      // 控制音量
      $('#musicplayer-volume-bar-container').bind('click',function(e){
        var topDistance = e.offsetY
        var clickProgress = (topDistance / $(this).height())
        musicVolume = 1 - clickProgress
        musicPlayer.volume = musicVolume
        $('#musicplayer-volume-bar').css('height', clickProgress * 100 + '%')
        if(musicVolume > 0){
          musicPlayer.muted = false
          $('.musicplayer-volume-icon').find('i').html('�')
          $('.musicplayer-volume-icon').removeClass('mute')
        }
      })
    

      

    完成上面的操作就做好了~

    布局样式就不多说了~直接上代码,项目中我用了bootstrap,例子就大体实现布局就可以了,具体样式自己去调整~以下是完整的html、css、js代码:

    <style>
    .music-head-wrap{display: flex;align-items: center;overflow: hidden;}
    .music-head{ 5rem;height: 5rem;-webkit-border-radius: 2.5rem;-moz-border-radius: 2.5rem;-ms-border-radius: 2.5rem;border-radius: 2.5rem;overflow: hidden;position: relative;margin: 1.8rem 1rem 0 1rem;}
      .music-head-img{position: relative; 100%;height: 100%;-webkit-border-radius: 2.5rem;-moz-border-radius: 2.5rem;-ms-border-radius: 2.5rem;border-radius: 2.5rem;overflow: hidden;}
      .music-head .music-head-img img{ 100%;height: auto;min-height: 5rem;}
      .music-head a{display: flex; 100%;height: 100%;align-items:center;justify-content: center;position: absolute;left: 0;top: 0;background: rgba(0, 0, 0, .5);color: rgba(255, 255, 255, .6);font-size: 2.5rem;-webkit-border-radius: 2.5rem;-moz-border-radius: 2.5rem;-ms-border-radius: 2.5rem;border-radius: 2.5rem;overflow: hidden;}
      .music-play.current .music-head-img{-webkit-animation: musicplay 10s infinite linear;-moz-animation: musicplay 10s infinite linear;-ms-animation: musicplay 10s infinite linear;-o-animation: musicplay 10s infinite linear;animation: musicplay 10s infinite linear;}
      .music-head .icon-play{display: none;}
      .music-play.current .icon-stop{display: none;}
      .music-play.current .icon-play{display: block;}
      .music-length{font-size: .8rem;line-height: 2rem;text-align: center;}
      #music-play-time{display: none;}
      .music-play.current .music-length span{display: none;}
      .music-play.current .music-length span#music-play-time{display: block;}
    
    .music-list{ 100%;height: auto;overflow: hidden;}
    .musiclist-wrap{ 31.33%;height: 10rem;background: #fff;float: left;-webkit-border-radius: 5px;-moz-border-radius: 5px;-ms-border-radius: 5px;border-radius: 5px;box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);display: flex;box-sizing: border-box;margin: 0 1% 1.5rem 1%;position: relative;}
      .music-info{max- 70%;}
      .music-info-name{font-size: 1.5rem;white-space: nowrap;padding: .8rem 0 .2rem 0;text-overflow: ellipsis;overflow: hidden;}
      .music-info-author,.music-info-uploadtime,.music-info-collection,.music-info-operation{font-size: .8rem;white-space: nowrap;}
    
    #musicplayer-bar-container{position: absolute;bottom: 0;left: 0; 100%;height: .5rem;background: #eee;}
      #musicplayer-bar-container:hover{cursor: pointer;}
      #musicplayer-bar-container .progress-bar{transition-duration:.3s;background: #00bcd4;position: absolute;left: 0;top: 0;height: 100%;}
    #musicplayer-volume-container{ 1.2rem;height: 8rem;position: absolute;right: .2rem;bottom: .6rem;}
      #musicplayer-volume-bar-container{ 30%;height: 6.5rem;position: relative;background: #00bcd4;border-radius: 3px;overflow: hidden;margin: 0 auto;cursor: pointer;display: none;}
      #musicplayer-volume-bar{background: #eee;position: absolute;left: 0;top: 0; 100%;-webkit-transition: .3s;-moz-transition: .3s;-ms-transition: .3s;transition: .3s;height: 0%;}
      #musicplayer-volume-container:hover #musicplayer-volume-bar-container{display: block;}
      .musicplayer-volume-icon{position: absolute;left: 0;bottom: 0; 100%;}
      .musicplayer-volume-icon a{color: #666;}
    
    @media screen and (max-1500px){
      .music-list .musiclist-wrap{ 48%;}
    }
    
    @media screen and (max-830px){
      .music-list .musiclist-wrap{ 100%;margin: 0 0 1.5rem 0;}
    }
    
    @media screen and (max-575.98px){
      .music-list .musiclist-wrap{align-items: center;justify-content: center;height: auto;padding-bottom: .5rem;flex-direction: column;}
      .music-info{max- 90%;}
      .music-head{margin: 1rem 1rem 0 1rem;}
    }
    
    @-webkit-keyframes musicplay{
      100%{-webkit-transform: rotate(360deg)}
    }
    @-moz-keyframes musicplay{
      100%{-moz-transform: rotate(360deg)}
    }
    @-ms-keyframes musicplay{
      100%{-ms-transform: rotate(360deg)}
    }
    @keyframes musicplay{
      100%{transform: rotate(360deg)}
    }
    </style>
    
    <div class="music-list">
    	<div class="musiclist-wrap">
          <div class="music-play">
            <div class="music-head">
              <div class="music-head-img">
                <img src="https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=3226503153,2830890507&fm=58&bpow=406&bpoh=547" alt="李荣浩">
              </div>
              <a href="javascript:;" data-key="http://fs.w.kugou.com/201901051629/59234ca6f07a9269c2d092b00a8d9d5e/G002/M00/0C/00/Qg0DAFS9_KSAf3uhAE3fmiiZ_Zw419.mp3" onclick="playMusic(this)" class="music-head-mask">
                <i class="iconfont icon-play">�</i>
                <i class="iconfont icon-stop">�</i>
              </a>
            </div>
            <div class="music-length text-center">
              <span id="music-play-time"></span>
              <span>05:18</span>
            </div>
          </div>
          <div class="music-info">
            <div class="music-info-name" title=" 老街 ">
               老街 
            </div>
            <div class="music-info-author">
              <i class="iconfont">�</i> 作者:  李荣浩
            </div>
            <div class="music-info-uploadtime">
              <i class="iconfont">�</i> 上传时间:  2019-01-01 12:25:34
            </div>
            <div class="music-info-collection">
              <i class="iconfont">�</i> 收藏量:  5426
            </div>
            <div class="music-info-operation">
              <button type="button" rel="tooltip" class="btn btn-info btn-sm" title="推荐"><i class="iconfont">�</i> 推荐</button>
              <button type="button" rel="tooltip" class="btn btn-danger btn-sm" title="删除"><i class="iconfont">�</i> 删除</button>
            </div>
          </div>
      </div>
    
      <div class="musiclist-wrap">
          <div class="music-play">
            <div class="music-head">
              <div class="music-head-img">
                <img src="https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=3002163596,2541880871&fm=58&bpow=591&bpoh=533" alt="梁汉文">
              </div>
              <a href="javascript:;" data-key="http://fs.w.kugou.com/201901101638/33cc235a3fa9bb700282204c1c756767/G009/M04/09/19/SQ0DAFUEYFGAKkx6AD7Zs5WkFBw579.mp3" onclick="playMusic(this)" class="music-head-mask">
                <i class="iconfont icon-play">�</i>
                <i class="iconfont icon-stop">�</i>
              </a>
            </div>
            <div class="music-length text-center">
              <span id="music-play-time"></span>
              <span>04:03</span>
            </div>
          </div>
          <div class="music-info">
            <div class="music-info-name" title=" 七友 ">
               七友 
            </div>
            <div class="music-info-author">
              <i class="iconfont">�</i> 作者:  梁汉文
            </div>
            <div class="music-info-uploadtime">
              <i class="iconfont">�</i> 上传时间:  2019-01-06 14:32:28
            </div>
            <div class="music-info-collection">
              <i class="iconfont">�</i> 收藏量:  1215
            </div>
            <div class="music-info-operation">
              <button type="button" rel="tooltip" class="btn btn-info btn-sm" title="推荐"><i class="iconfont">�</i> 推荐</button>
              <button type="button" rel="tooltip" class="btn btn-danger btn-sm" title="删除"><i class="iconfont">�</i> 删除</button>
            </div>
          </div>
      </div>
    </div>
    
    <audio controls="controls" style="display: none" id="music-player">
      Your browser does not support the audio element.
    </audio>
    
    <script src="http://127.0.0.1:8080/assets/js/core/jquery.min.js"></script>
    
    <script>
    var musicPlayer = document.getElementById('music-player')
    var musicPlayerTimer
    
    function playMusic(obj) {
      var musicPlayUrl = musicPlayer.src
      var thisKey = $(obj).data('key')
      clearInterval(musicPlayerTimer)
      
      $('.music-play').removeClass('current')
      
      if(musicPlayUrl == thisKey){
        //停止播放音乐
        if(musicPlayer.paused){
          $(obj).parent().parent().addClass('current')
          musicPlayer.play()
          musicPlayerTimer = setInterval(musicPlayProgress,1000)
        }else{
          musicPlayer.pause()
        }
      }else{
        //更换音乐播放
        musicPlayer.src = thisKey
        musicPlayer.play()
        $(obj).parent().parent().addClass('current')
        $('#musicplayer-bar-container,#musicplayer-volume-container,#music-play-time').remove()
        var thisCon = $(obj).parent().parent()
        var musicPlayerBarHtml = `<div class="progress" id="musicplayer-bar-container">
                              <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" style=" 0%;" id="music-player-bar">
                              </div>
                          </div>`
        var musicPlayerVolumeHtml = `<div id="musicplayer-volume-container">
                          <div id="musicplayer-volume-bar-container">
                            <div id="musicplayer-volume-bar"></div>
                          </div>
                          <div class="musicplayer-volume-icon">
                            <a href="javascript:;" onclick="muteSetting(this)"><i class="iconfont">�</i></a>
                          </div>
                        </div>`                      
        thisCon.append(musicPlayerBarHtml,musicPlayerVolumeHtml)
        $(obj).parent().parent().find('.music-length').append('<span id="music-play-time"></span>')
        musicPlayerTimer = setInterval(musicPlayProgress,1000)
      }
    
      // 控制进度条
      $('#musicplayer-bar-container').bind('click',function(e){
        var leftDistance = e.offsetX
        var clickProgress = (leftDistance / $(this).width())
        musicPlayer.currentTime = musicPlayer.duration * clickProgress
        $('#music-player-bar').css('width',clickProgress * 100 + '%')
      })
    
      // 控制音量
      $('#musicplayer-volume-bar-container').bind('click',function(e){
        var topDistance = e.offsetY
        var clickProgress = (topDistance / $(this).height())
        musicVolume = 1 - clickProgress
        musicPlayer.volume = musicVolume
        $('#musicplayer-volume-bar').css('height', clickProgress * 100 + '%')
        if(musicVolume > 0){
          musicPlayer.muted = false
          $('.musicplayer-volume-icon').find('i').html('�')
          $('.musicplayer-volume-icon').removeClass('mute')
        }
      })
    }
    
    // 检测播放进度
    function musicPlayProgress(){
        var musicTotalLength = musicPlayer.duration
        var musicCurrentLength = musicPlayer.currentTime
        var musicProgress = (musicCurrentLength / musicTotalLength) * 100 + '%'
        $('#music-play-time').html(timeConversion(musicCurrentLength) + ' / ' + timeConversion(musicTotalLength))
        $('#music-player-bar').css('width',musicProgress)
        if(musicPlayer.ended){
          // 检测是否暂停状态
          $('.music-play').removeClass('current')
        }
        if(musicPlayer.error != null){
          // 检测是否播放错误
          clearInterval(musicPlayerTimer)
          $('.music-play').removeClass('current')
          alert('音乐播放错误!')
        }
    }
    
    // 静音设置
    function muteSetting(obj){
      var isHasMute = $(obj).parent().hasClass('mute')
      if(isHasMute){
        // 开启声音
        musicPlayer.muted = false
        musicPlayer.volume = 1
        $(obj).find('i').html('�')
        $(obj).parent().removeClass('mute')
        $('#musicplayer-volume-bar').css('height','0%')
      }else{
        // 设置静音
        musicPlayer.muted = true
        $(obj).find('i').html('�')
        $(obj).parent().addClass('mute')
        $('#musicplayer-volume-bar').css('height','100%')
      }
    }
    
    // 时间格式转换
    function timeConversion(time){
      var seconds = parseInt(time)   // 秒
      var minutes = 0                // 分
      var hours = 0                  // 小时
      if(seconds > 60) {
          minutes = parseInt(seconds/60);
          seconds = parseInt(seconds%60);
          if(minutes > 60) {
              hours = parseInt(minutes/60);
              minutes = parseInt(minutes%60);
          }
      }
      var result = ''
      if(seconds < 10)
        seconds = '0' + seconds
      if(minutes < 10)
        minutes = '0' + minutes
      if(hours > 0) {
        if(hours < 10)
          hours = '0' + hours
        result = hours + ':' + minutes + ":" + seconds
      }else{
        result = minutes + ":" + seconds
      }
      return result
    }
    </script>
    

      

  • 相关阅读:
    linux安装java环境
    前端JS-websocket与后端通信
    windows安装NodeJS/修改全局路径/配置镜像站
    vue基础---13vue-router
    uni-app项目
    vue基础---12脚手架
    vue基础---11组件
    vue基础---10生命周期
    vue基础---09表单输入绑定
    vue基础---08事件
  • 原文地址:https://www.cnblogs.com/gxsyj/p/10256578.html
Copyright © 2020-2023  润新知