<template>
    <el-dialog id="CommonAudio" :title="title" :close-on-click-modal="false" :before-close="closeDialog" :visible.sync="audioDialogVisible" width="30%" center>
        <div class="main-wrap ptb10">
            <!-- 这里设置了ref属性后，在vue组件中，就可以用this.$refs.audio来访问该dom元素 -->
            <audio ref="audio" class="display-none" :src="url" :preload="audio.preload" @play="onPlay" @error="onError" @waiting="onWaiting" @pause="onPause" @timeupdate="onTimeupdate" @loadedmetadata="onLoadedmetadata" />
            <div class="ta-c">
                <div class="c-606266 mtb15 flex-center con-slider">
                    <span class="curtime">{{ audio.currentTime | formatSecond }}</span>
                    <el-slider v-show="!controlList.noProcess" v-model="sliderTime" :format-tooltip="formatProcessToolTip" class="slider time-range" @change="changeCurrentTime" />
                    <span class="totaltime">{{ audio.maxTime | formatSecond }}</span>
                </div>
                <div class="play-speed ft12 c-606266">
                    <span v-for="(v, i) in speeds" :key="i" :class="v == audio.speed ? 'c-f56c6c' : ''" class="pointer" @click="changeSpeed(v)">{{ v }}X</span>
                </div>
            </div>
            <div class="flex-center play-control">
                <span class="play-control-left"><img src="../../assets/img/f3.png" @click="goBack"></span>
                <span class="play-control-play"><img :src="audioPlayImg" @click="startPlayOrPause"></span>
                <span class="play-control-right"><img src="../../assets/img/f4.png" @click="goNext"></span>
                <a v-if="audio.waiting" :href="url" target="_blank" class="download pointer ft14" download>点击下载</a>
            </div>
        </div>
    </el-dialog>
</template>

<script>
function realFormatSecond(second) {
    var secondType = typeof second;
    if (secondType === 'number' || secondType === 'string') {
        second = parseInt(second);
        var hours = Math.floor(second / 3600);
        second = second - hours * 3600;
        var mimute = Math.floor(second / 60);
        second = second - mimute * 60;
        return ('0' + hours).slice(-2) + ':' + ('0' + mimute).slice(-2) + ':' + ('0' + second).slice(-2);
    }
    return '00:00:00';
}
export default {
    name: 'CustomerAudio',
    filters: {
        formatSecond(second = 0) {
            return realFormatSecond(second);
        }
    },
    props: {
        theUrl: {
            type: String,
            default: ''
        },
        audioDialogVisible: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            title: '提示',
            url: '',
            audio: {
                currentTime: 0,
                maxTime: 0,
                playing: false,
                muted: false,
                speed: 1,
                waiting: true,
                preload: 'meta'
            },
            theControlList: 'onlyOnePlaying',
            sliderTime: 0,
            volume: 100,
            speeds: [1, 1.25, 1.5, 2],
            controlList: {
                // 不显示进度条
                noProcess: false,
                // 只能播放一个
                onlyOnePlaying: false,
                // 不要快进按钮
                noSpeed: false
            },
            audioPlayImg: require('@/assets/img/f1.png')
        };
    },
    watch: {
        theUrl(val) {
            this.url = val;
        },
        'audio.playing'(val) {
            this.audioPlayImg = val ? require('@/assets/img/f2.png') : require('@/assets/img/f1.png');
        }
    },
    created() {
        this.url = this.theUrl;
        this.setControlList();
    },
    methods: {
        setControlList() {
            const controlList = this.theControlList.split(' ');
            controlList.forEach(item => {
                if (this.controlList[item] !== undefined) {
                    this.controlList[item] = true;
                }
            });
        },
        changeSpeed(v) {
            this.audio.speed = v;
            this.$refs.audio.playbackRate = this.audio.speed;
        },
        startMutedOrNot() {
            this.$refs.audio.muted = !this.$refs.audio.muted;
            this.audio.muted = this.$refs.audio.muted;
        },
        // 进度条toolTip
        formatProcessToolTip(index = 0) {
            index = parseInt((this.audio.maxTime / 100) * index);
            return '进度条: ' + realFormatSecond(index);
        },
        // 播放跳转
        changeCurrentTime(index) {
            this.$refs.audio.currentTime = parseInt((index / 100) * this.audio.maxTime);
        },
        startPlayOrPause() {
            return this.audio.playing ? this.pausePlay() : this.startPlay();
        },
        // 开始播放
        startPlay() {
            this.$nextTick(() => {
                this.$refs.audio.src = this.url;
                this.$refs.audio.load();
                this.$refs.audio.play();
            });
        },
        // 暂停
        pausePlay() {
            this.$refs.audio.pause();
        },
        // 当音频暂停
        onPause() {
            this.audio.playing = false;
        },
        // 当发生错误, 就出现loading状态
        onError() {
            this.audio.waiting = true;
            if (this.url) {
                this.$message.warning('录音获取错误，可下载后本地播放');
            }
        },
        // 当音频开始等待
        onWaiting(res) {},
        // 当音频开始播放
        onPlay(res) {
            this.audio.playing = true;
            this.audio.loading = false;
            if (!this.controlList.onlyOnePlaying) {
                return;
            }
            const target = res.target;
            const audios = document.getElementsByTagName('audio');
            [...audios].forEach(item => {
                if (item !== target) {
                    item.pause();
                }
            });
        },
        // 当timeupdate事件大概每秒一次，用来更新音频流的当前播放时间
        onTimeupdate(res) {
            this.audio.currentTime = res.target.currentTime;
            this.sliderTime = parseInt((this.audio.currentTime / this.audio.maxTime) * 100);
        },
        // 当加载语音流元数据完成后，会触发该事件的回调函数
        // 语音元数据主要是语音的长度之类的数据
        onLoadedmetadata(res) {
            this.audio.waiting = false;
            this.audio.maxTime = parseInt(res.target.duration);
        },
        // 回退事件
        goBack() {
            this.$refs.audio.currentTime = this.$refs.audio.currentTime - 3;
        },
        // 快进事件
        goNext() {
            this.$refs.audio.currentTime = this.$refs.audio.currentTime + 3;
        },
        closeDialog() {
            // 关闭语音
            this.$refs.audio.currentTime = 0;
            this.pausePlay();
            this.$emit('closeAudioDialog', false);
        }
    }
};
</script>

<style lang="less" scoped>
#CommonAudio {
	.play-speed {
		width: 50%;
		margin: auto;
		span {
			margin: 0 5px;
			cursor: pointer;
		}
	}
	.play-control {
		span {
			display: inline-block;
			img {
				display: block;
				max-width: 100%;
				height: auto !important;
			}
		}
		.play-control-left,
		.play-control-right {
			width: 30px;
			cursor: pointer;
		}
		.play-control-play {
			width: 60px;
			cursor: pointer;
		}
		.download {
			position: absolute;
			right: 10%;
			color: #d40000;
			text-decoration: underline;
		}
	}
	.time-range {
		width: 50%;
		margin: 0 15px;
	}

	.con-slider {
		.con-slider {
			display: flex;
			align-items: center;
			padding-left: 22px;
			padding-right: 26px;
			box-sizing: border-box;
			width: 288px;
			height: 94px;
			background: #ffffff;
			box-shadow: 0px 9px 28px 8px rgba(0, 0, 0, 0.05), 0px 6px 16px 0px rgba(0, 0, 0, 0.08), 0px 3px 6px -4px rgba(0, 0, 0, 0.12);
		}
	}
}
</style>
