简单利用vue2和elementUI自界说audio支持拖拽进度

种地  金牌会员 | 2024-6-21 13:20:28 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 697|帖子 697|积分 2091

  1. <template>
  2.   <div class="music-player">
  3.     <audio ref="audio" :src="src" @timeupdate="updateTime" @loadedmetadata="loadedmetadata" @ended="onAudioEnded"></audio>
  4.     <!-- 播放暂停按钮 -->
  5.     <div class="cm-btn-left" @click="togglePlay">
  6.       <img src="../../../../public/img/icon/play.png" v-show="!isPlaying">
  7.       <img src="../../../../public/img/icon/pause.png" v-show="isPlaying">
  8.     </div>
  9.     <!-- 时间 -->
  10.     <div class="cm-time">
  11.       <span>{{ currentTimeShow }}</span> / <span>{{ durationShow }}</span>
  12.     </div>
  13.     <!-- 播放进度条 -->
  14.     <div class="cm-progress" @mousedown="handleMouseDown">
  15.       <el-slider v-model="progress" :max="duration" :format-tooltip="formatTime" @change="progressChange"></el-slider>
  16.     </div>
  17.     <!-- 倍速控制 -->
  18.     <div class="playback-rate-wrapper">
  19.       <el-select v-model="playbackRate" @change="changePlaybackRate">
  20.         <el-option
  21.           v-for="item in speed"
  22.           :key="item.value"
  23.           :label="item.label"
  24.           :value="item.value">
  25.         </el-option>
  26.       </el-select>
  27.     </div>
  28.     <!-- 音量控制 -->
  29.     <div class="volumn-wrapper">
  30.      <el-popover
  31.         popper-class="volumn-popover"
  32.         placement="right"
  33.         width="30px"
  34.         trigger="click">
  35.         <el-slider
  36.           v-model="volumnValue"
  37.           vertical
  38.           tooltip-class="volumn-tooltip"
  39.           height="80px"
  40.           @change="volumnChange">
  41.         </el-slider>
  42.         <el-button slot="reference" type="text"><img src="../../../../public/img/icon/volumn.png"></el-button>
  43.       </el-popover>
  44.     </div>
  45.   </div>
  46. </template>
  47. <script>
  48. export default {
  49.   props: {
  50.     src: String,
  51.   },
  52.   data() {
  53.     return {
  54.       isPlaying: false,
  55.       currentTime: 0,
  56.       progress: 0,
  57.       duration: 0,
  58.       playbackRate: 1,
  59.       speed: [
  60.         {
  61.           label: '0.5x',
  62.           value: 0.5
  63.         },
  64.         {
  65.           label: '0.75x',
  66.           value: 0.75
  67.         },
  68.         {
  69.           label: '1x',
  70.           value: 1
  71.         },
  72.         {
  73.           label: '1.5x',
  74.           value: 1.5
  75.         },
  76.         {
  77.           label: '2x',
  78.           value: 2
  79.         }
  80.       ],
  81.       volumnValue: 50,
  82.       lastTimeUpdate: null
  83.     };
  84.   },
  85.   computed: {
  86.     currentTimeShow: function () {
  87.       return this.formatTime(this.currentTime);
  88.     },
  89.     durationShow: function () {
  90.       return this.formatTime(this.duration);
  91.     }
  92.   },
  93.   mounted() {
  94.   },
  95.   beforeDestroy() {
  96.    
  97.   },
  98.   methods: {
  99.     // 外部点击暂停播放
  100.     resetAudio() {
  101.       this.$refs.audio.pause();
  102.       this.isPlaying = false;
  103.       this.playbackRate = 1;
  104.       this.volumnValue = 50;
  105.       this.duration = 0;
  106.       setTimeout(() => {
  107.         this.currentTime = 0;
  108.       }, 50);
  109.     },
  110.     // 播放暂停按钮点击事件
  111.     togglePlay() {
  112.       if (!this.src || this.src.length === 0) {
  113.         return
  114.       }
  115.       if (this.isPlaying) {
  116.         this.$refs.audio.pause();
  117.         this.isPlaying = false;
  118.       } else {
  119.         this.$refs.audio.play();
  120.         this.$refs.audio.volume = this.volumnValue / 100;
  121.         this.isPlaying = true;
  122.       }
  123.     },
  124.     // 格式化播放时间
  125.     formatTime(seconds) {
  126.       const minutes = Math.floor(seconds / 60);
  127.       const secondsRemainder = Math.round(seconds % 60);
  128.       return `${minutes}:${secondsRemainder < 10 ? '0' : ''}${secondsRemainder}`;
  129.     },
  130.     // 倍速控制
  131.     changePlaybackRate() {
  132.       this.$refs.audio.playbackRate = this.playbackRate;
  133.     },
  134.     // 更新播放时间
  135.     updateTime() {
  136.       this.currentTime = this.$refs.audio.currentTime;
  137.       this.progress = this.currentTime;
  138.     },
  139.     // 获取播放总时长
  140.     loadedmetadata() {
  141.       this.duration = this.$refs.audio.duration;
  142.     },
  143.     // 播放结束
  144.     onAudioEnded() {
  145.       this.isPlaying = false;
  146.     },
  147.     // 进度条鼠标按下事件
  148.     handleMouseDown() {
  149.       this.$refs.audio.pause();
  150.     },
  151.     // 设置进度
  152.     progressChange(e) {
  153.       this.$refs.audio.currentTime = e;
  154.       this.progress = e;
  155.       this.$refs.audio.play();
  156.       this.isPlaying = true;
  157.     },
  158.     // 设置音量
  159.     volumnChange(e) {
  160.       this.$refs.audio.volume = e / 100;
  161.     },
  162.   },
  163. };
  164. </script>
  165. <style lang="scss" scoped>
  166.   .music-player {
  167.     display: flex;
  168.     align-items: center;
  169.     justify-content: space-between;
  170.     padding: 0px 20px;
  171.     background-color: #f5f5f5;
  172.     border-radius: 27px;
  173.     height: 54px;
  174.     width: 100%;
  175.     .cm-btn-left {
  176.       cursor: pointer;
  177.       width: 22px;
  178.       height: 22px;
  179.       img {
  180.         width: 22px;
  181.         height: 22px;
  182.       }
  183.     }
  184.     .volumn-wrapper {
  185.       img {
  186.         width: 20px;
  187.         height: 18px;
  188.       }
  189.     }
  190.     .cm-time {
  191.       font-size: 14px;
  192.       color: #404040;
  193.       margin: 0 10px;
  194.     }
  195.     .cm-progress {
  196.       flex: 1;
  197.       margin: 0 15px 0 10px;
  198.       ::v-deep .el-slider__button {
  199.         border-color: #404040 !important;
  200.       }
  201.       ::v-deep .el-slider__bar {
  202.         background-color: #404040 !important;
  203.       }
  204.     }
  205.     .playback-rate-wrapper {
  206.       margin-right: 10px;
  207.       ::v-deep .el-input__suffix {
  208.         display: none;
  209.       }
  210.       ::v-deep .el-input__inner {
  211.         height: 28px;
  212.         width: 45px;
  213.         text-align: center;
  214.         padding: 0px !important;
  215.         font-size: 12px;
  216.       }
  217.     }
  218.   }
  219.   ::v-deep .el-slider__button {
  220.     width: 12px;
  221.     height: 12px;
  222.   }
  223.   ::v-deep .el-popover {
  224.     min-width: auto !important;
  225.   }
  226. </style>
复制代码
app.vue中或者其他全局变量中修改下样式
.volumn-popover {
  min-width: auto !important;
}
.volumn-tooltip {
  z-index: 99999 !important;
}


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表