|
@@ -1,431 +0,0 @@
|
|
-<template>
|
|
|
|
- <div class="Audio">
|
|
|
|
- <div class="audioLine" v-if="!hideSlider">
|
|
|
|
- <div
|
|
|
|
- class="play"
|
|
|
|
- :class="audio.playing ? 'playBtn' : 'pauseBtn'"
|
|
|
|
- @click="PlayAudio"
|
|
|
|
- />
|
|
|
|
- <template v-if="!isRepeat">
|
|
|
|
- <el-slider
|
|
|
|
- v-model="playValue"
|
|
|
|
- :style="{ width: sliderWidth + 'px', height: '2px' }"
|
|
|
|
- :format-tooltip="formatProcessToolTip"
|
|
|
|
- @change="changeCurrentTime"
|
|
|
|
- />
|
|
|
|
- <span
|
|
|
|
- ><template v-if="audio.playing">-</template
|
|
|
|
- >{{
|
|
|
|
- audio.maxTime
|
|
|
|
- ? realFormatSecond(audio.maxTime - audio.currentTime)
|
|
|
|
- : ""
|
|
|
|
- }}</span
|
|
|
|
- >
|
|
|
|
- </template>
|
|
|
|
- <audio
|
|
|
|
- ref="audio"
|
|
|
|
- :src="mp3"
|
|
|
|
- @loadedmetadata="onLoadedmetadata"
|
|
|
|
- @timeupdate="onTimeupdate"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- <div class="audioLine2" v-else>
|
|
|
|
- <div
|
|
|
|
- class="play-icon"
|
|
|
|
- :class="audio.playing ? 'playBtn-icon' : 'pauseBtn-icon'"
|
|
|
|
- @click="PlayAudio"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- <audio
|
|
|
|
- :ref="audioId"
|
|
|
|
- :src="mp3"
|
|
|
|
- @loadedmetadata="onLoadedmetadata"
|
|
|
|
- @timeupdate="onTimeupdate"
|
|
|
|
- @canplay="oncanplay"
|
|
|
|
- :id="audioId"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
-</template>
|
|
|
|
-
|
|
|
|
-<script>
|
|
|
|
-// 这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
|
|
|
|
-// 例如:import 《组件名称》from ‘《组件路径》';
|
|
|
|
-export default {
|
|
|
|
- // import引入的组件需要注入到对象中才能使用
|
|
|
|
- components: {},
|
|
|
|
- props: [
|
|
|
|
- "mp3",
|
|
|
|
- "getCurTime",
|
|
|
|
- "stopAudio",
|
|
|
|
- "width",
|
|
|
|
- "isRepeat",
|
|
|
|
- "themeColor",
|
|
|
|
- "hideSlider",
|
|
|
|
- "ed",
|
|
|
|
- "bg",
|
|
|
|
- "audioId",
|
|
|
|
- ],
|
|
|
|
- data() {
|
|
|
|
- // 这里存放数据
|
|
|
|
- return {
|
|
|
|
- playValue: 0,
|
|
|
|
- audio: {
|
|
|
|
- // 该字段是音频是否处于播放状态的属性
|
|
|
|
- playing: false,
|
|
|
|
- // 音频当前播放时长
|
|
|
|
- currentTime: 0,
|
|
|
|
- // 音频最大播放时长
|
|
|
|
- maxTime: 0,
|
|
|
|
- isPlaying: false,
|
|
|
|
- loading: false,
|
|
|
|
- },
|
|
|
|
- audioAllTime: null, // 展示总时间
|
|
|
|
- duioCurrentTime: null, // 剩余时间
|
|
|
|
- };
|
|
|
|
- },
|
|
|
|
- // 计算属性 类似于data概念
|
|
|
|
- computed: {
|
|
|
|
- sliderWidth() {
|
|
|
|
- let width = 0;
|
|
|
|
- if (this.width) {
|
|
|
|
- width = this.width;
|
|
|
|
- } else {
|
|
|
|
- width = 662;
|
|
|
|
- }
|
|
|
|
- return width;
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- // 监控data中数据变化
|
|
|
|
- watch: {
|
|
|
|
- stopAudio: {
|
|
|
|
- handler(val, oldVal) {
|
|
|
|
- const _this = this;
|
|
|
|
- if (val) {
|
|
|
|
- _this.$refs[_this.audioId].pause();
|
|
|
|
- _this.audio.playing = false;
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- // 深度观察监听
|
|
|
|
- deep: true,
|
|
|
|
- },
|
|
|
|
- "audio.playing": {
|
|
|
|
- handler(val) {
|
|
|
|
- this.$emit("playChange", val);
|
|
|
|
- if (val) this.$emit("handleChangeStopAudio");
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- // 生命周期 - 创建完成(可以访问当前this实例)
|
|
|
|
- created() {},
|
|
|
|
- // 生命周期 - 挂载完成(可以访问DOM元素)
|
|
|
|
- mounted() {
|
|
|
|
- let _this = this;
|
|
|
|
- let audioId = _this.audioId;
|
|
|
|
- _this.$refs[audioId].addEventListener("play", function () {
|
|
|
|
- _this.audio.playing = true;
|
|
|
|
- _this.audio.isPlaying = true;
|
|
|
|
- });
|
|
|
|
- _this.$refs[audioId].addEventListener("pause", function () {
|
|
|
|
- _this.audio.playing = false;
|
|
|
|
- });
|
|
|
|
- _this.$refs[audioId].addEventListener("ended", function () {
|
|
|
|
- _this.audio.playing = false;
|
|
|
|
- _this.audio.isPlaying = false;
|
|
|
|
- });
|
|
|
|
- this.$nextTick(() => {
|
|
|
|
- document
|
|
|
|
- .getElementsByClassName("el-slider__button-wrapper")[0]
|
|
|
|
- .addEventListener("mousedown", function () {
|
|
|
|
- _this.$refs[audioId].pause();
|
|
|
|
- _this.audio.playing = false;
|
|
|
|
- });
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- // 生命周期-挂载之前
|
|
|
|
- beforeMount() {},
|
|
|
|
- // 生命周期-更新之后
|
|
|
|
- updated() {},
|
|
|
|
- // 如果页面有keep-alive缓存功能,这个函数会触发
|
|
|
|
- activated() {},
|
|
|
|
- // 方法集合
|
|
|
|
- methods: {
|
|
|
|
- PlayAudio() {
|
|
|
|
- let audioId = this.audioId;
|
|
|
|
- let audio = document.getElementsByTagName("audio");
|
|
|
|
- audio.forEach((item) => {
|
|
|
|
- if (item.src == this.mp3) {
|
|
|
|
- if (item.id !== audioId) {
|
|
|
|
- item.pause();
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- item.pause();
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- if (this.audio.playing) {
|
|
|
|
- this.$refs[audioId].pause();
|
|
|
|
- this.audio.playing = false;
|
|
|
|
- this.$emit("handleListenRead", false);
|
|
|
|
- } else {
|
|
|
|
- if (this.hideSlider) {
|
|
|
|
- this.$refs[audioId].play();
|
|
|
|
- this.onTimeupdateTime(this.bg / 1000);
|
|
|
|
- } else {
|
|
|
|
- this.$refs[audioId].play();
|
|
|
|
- }
|
|
|
|
- this.audio.playing = true;
|
|
|
|
- this.$emit("handleChangeStopAudio");
|
|
|
|
- this.$emit("handleListenRead", true);
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- oncanplay() {},
|
|
|
|
- // 点击 拖拽播放音频
|
|
|
|
- changeCurrentTime(value) {
|
|
|
|
- let audioId = this.audioId;
|
|
|
|
- this.$refs[audioId].play();
|
|
|
|
- this.audio.playing = true;
|
|
|
|
- this.$refs[audioId].currentTime = parseInt(
|
|
|
|
- (value / 100) * this.audio.maxTime
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- mousedown() {
|
|
|
|
- let audioId = this.audioId;
|
|
|
|
- this.$refs[audioId].pause();
|
|
|
|
- this.audio.playing = false;
|
|
|
|
- },
|
|
|
|
- // 进度条格式化toolTip
|
|
|
|
- formatProcessToolTip(index) {
|
|
|
|
- index = parseInt((this.audio.maxTime / 100) * index);
|
|
|
|
- return this.realFormatSecond(index);
|
|
|
|
- },
|
|
|
|
- // 音频加载完之后
|
|
|
|
- onLoadedmetadata(res) {
|
|
|
|
- this.audio.maxTime = parseInt(res.target.duration);
|
|
|
|
- this.audioAllTime = this.realFormatSecond(this.audio.maxTime);
|
|
|
|
- },
|
|
|
|
- // 当音频当前时间改变后,进度条也要改变
|
|
|
|
- onTimeupdate(res) {
|
|
|
|
- let audioId = this.audioId;
|
|
|
|
- this.audio.currentTime = res.target.currentTime;
|
|
|
|
- this.getCurTime(res.target.currentTime);
|
|
|
|
- this.playValue = (this.audio.currentTime / this.audio.maxTime) * 100;
|
|
|
|
- if (this.audio.currentTime * 1000 > this.ed) {
|
|
|
|
- this.$refs[audioId].pause();
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- onTimeupdateTime(res, playFlag) {
|
|
|
|
- let audioId = this.audioId;
|
|
|
|
- this.$refs[audioId].currentTime = res;
|
|
|
|
- this.playValue = (res / this.audio.maxTime) * 100;
|
|
|
|
- if (playFlag) {
|
|
|
|
- let audio = document.getElementsByTagName("audio");
|
|
|
|
- audio.forEach((item) => {
|
|
|
|
- if (item.id !== audioId) {
|
|
|
|
- item.pause();
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- this.$refs[audioId].play();
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- // 将整数转换成 时:分:秒的格式
|
|
|
|
- realFormatSecond(value) {
|
|
|
|
- let theTime = parseInt(value); // 秒
|
|
|
|
- let theTime1 = 0; // 分
|
|
|
|
- let theTime2 = 0; // 小时
|
|
|
|
- if (theTime > 60) {
|
|
|
|
- theTime1 = parseInt(theTime / 60);
|
|
|
|
- theTime = parseInt(theTime % 60);
|
|
|
|
- if (theTime1 > 60) {
|
|
|
|
- theTime2 = parseInt(theTime1 / 60);
|
|
|
|
- theTime1 = parseInt(theTime1 % 60);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- let result = String(parseInt(theTime));
|
|
|
|
- if (result < 10) {
|
|
|
|
- result = "0" + result;
|
|
|
|
- }
|
|
|
|
- if (theTime1 > 0) {
|
|
|
|
- result = String(parseInt(theTime1)) + ":" + result;
|
|
|
|
- if (theTime1 < 10) {
|
|
|
|
- result = "0" + result;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- result = "00:" + result;
|
|
|
|
- }
|
|
|
|
- if (theTime2 > 0) {
|
|
|
|
- result = String(parseInt(theTime2)) + ":" + result;
|
|
|
|
- if (theTime2 < 10) {
|
|
|
|
- result = "0" + result;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- // result = "00:" + result;
|
|
|
|
- }
|
|
|
|
- return result;
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- // 生命周期-创建之前
|
|
|
|
- beforeCreated() {},
|
|
|
|
- // 生命周期-更新之前
|
|
|
|
- beforUpdate() {},
|
|
|
|
- // 生命周期-销毁之前
|
|
|
|
- beforeDestory() {},
|
|
|
|
- // 生命周期-销毁完成
|
|
|
|
- destoryed() {},
|
|
|
|
-};
|
|
|
|
-</script>
|
|
|
|
-<style lang="scss" scoped>
|
|
|
|
-/* @import url(); 引入css类 */
|
|
|
|
-.Audio {
|
|
|
|
- width: 100%;
|
|
|
|
- .audioLine {
|
|
|
|
- display: flex;
|
|
|
|
- align-items: center;
|
|
|
|
- width: 100%;
|
|
|
|
- height: 40px;
|
|
|
|
- background: #ffffff;
|
|
|
|
- // border: 1px solid rgba(0, 0, 0, 0.1);
|
|
|
|
- // box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
|
|
|
|
- box-sizing: border-box;
|
|
|
|
- border-radius: 4px;
|
|
|
|
- .play {
|
|
|
|
- margin-right: 12px;
|
|
|
|
- margin-left: 8px;
|
|
|
|
- width: 16px;
|
|
|
|
- height: 16px;
|
|
|
|
- cursor: pointer;
|
|
|
|
- display: block;
|
|
|
|
- // &.playBtn {
|
|
|
|
- // background: url("../../../assets/pause.png") no-repeat left top;
|
|
|
|
- // background-size: 100% 100%;
|
|
|
|
- // }
|
|
|
|
- // &.pauseBtn {
|
|
|
|
- // background: url("../../../assets/play.png") no-repeat left top;
|
|
|
|
- // background-size: 100% 100%;
|
|
|
|
- // }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- span {
|
|
|
|
- font-size: 16px;
|
|
|
|
- line-height: 19px;
|
|
|
|
- color: #000;
|
|
|
|
- margin-left: 8px;
|
|
|
|
- margin-right: 12px;
|
|
|
|
- min-width: 56px;
|
|
|
|
- text-align: right;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- > .audioLine2 {
|
|
|
|
- .play-icon {
|
|
|
|
- width: 16px;
|
|
|
|
- height: 16px;
|
|
|
|
- cursor: pointer;
|
|
|
|
- &.playBtn-icon {
|
|
|
|
- background: url("../../../assets/NPC/icon-voice-play-red.png") no-repeat
|
|
|
|
- left top;
|
|
|
|
- background-size: 100% 100%;
|
|
|
|
- }
|
|
|
|
- &.pauseBtn-icon {
|
|
|
|
- background: url("../../../assets/NPC/play-red.png") no-repeat left top;
|
|
|
|
- background-size: 100% 100%;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-.NPC-Big-Book-preview-green {
|
|
|
|
- .playBtn-icon {
|
|
|
|
- background: url("../../../assets/NPC/icon-voice-play-green.png") no-repeat
|
|
|
|
- left top;
|
|
|
|
- background-size: 100% 100%;
|
|
|
|
- }
|
|
|
|
- .pauseBtn-icon {
|
|
|
|
- background: url("../../../assets/NPC/play-green.png") no-repeat left top;
|
|
|
|
- background-size: 100% 100%;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-.NPC-Big-Book-preview-red {
|
|
|
|
- .playBtn-icon {
|
|
|
|
- background: url("../../../assets/NPC/icon-voice-play-red.png") no-repeat
|
|
|
|
- left top;
|
|
|
|
- background-size: 100% 100%;
|
|
|
|
- }
|
|
|
|
- .pauseBtn-icon {
|
|
|
|
- background: url("../../../assets/NPC/play-red.png") no-repeat left top;
|
|
|
|
- background-size: 100% 100%;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-.NPC-Big-Book-preview-brown {
|
|
|
|
- .playBtn-icon {
|
|
|
|
- background: url("../../../assets/NPC/icon-voice-play-brown.png") no-repeat
|
|
|
|
- left top;
|
|
|
|
- background-size: 100% 100%;
|
|
|
|
- }
|
|
|
|
- .pauseBtn-icon {
|
|
|
|
- background: url("../../../assets/NPC/play-brown.png") no-repeat left top;
|
|
|
|
- background-size: 100% 100%;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-</style>
|
|
|
|
-<style lang="scss">
|
|
|
|
-.Audio {
|
|
|
|
- .el-slider__button-wrapper {
|
|
|
|
- position: relative;
|
|
|
|
- z-index: 0;
|
|
|
|
- }
|
|
|
|
- .el-slider__button {
|
|
|
|
- width: 8px;
|
|
|
|
- height: 8px;
|
|
|
|
- top: 12px;
|
|
|
|
- position: absolute;
|
|
|
|
- }
|
|
|
|
- .el-slider__runway {
|
|
|
|
- margin: 0;
|
|
|
|
- padding: 0;
|
|
|
|
- background: #e5e5e5;
|
|
|
|
- border-radius: 0px;
|
|
|
|
- height: 2px;
|
|
|
|
- }
|
|
|
|
- .el-slider {
|
|
|
|
- position: relative;
|
|
|
|
- }
|
|
|
|
- .el-slider__bar {
|
|
|
|
- height: 2px;
|
|
|
|
- background: rgba(118, 99, 236, 1);
|
|
|
|
- }
|
|
|
|
- .el-slider__button {
|
|
|
|
- background: rgba(118, 99, 236, 1);
|
|
|
|
- border: none;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-.NPC-Book-Sty {
|
|
|
|
- .Audio {
|
|
|
|
- .el-slider__bar {
|
|
|
|
- height: 2px;
|
|
|
|
- background: #de4444;
|
|
|
|
- }
|
|
|
|
- .el-slider__button {
|
|
|
|
- background: #de4444;
|
|
|
|
- border: none;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-.NPC-Big-Book-preview-green {
|
|
|
|
- .Audio {
|
|
|
|
- .el-slider__bar {
|
|
|
|
- background: #24b99e !important;
|
|
|
|
- }
|
|
|
|
- .el-slider__button {
|
|
|
|
- background: #24b99e !important;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-.NPC-Big-Book-preview-brown {
|
|
|
|
- .Audio {
|
|
|
|
- .el-slider__bar {
|
|
|
|
- background: #bd8865 !important;
|
|
|
|
- }
|
|
|
|
- .el-slider__button {
|
|
|
|
- background: #bd8865 !important;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-</style>
|
|
|