<template>
	<div class="gloWe-audio">
		<!--		<audio
			:src="audioData.url"
			controls
			preload="auto"
			@ended="audioEnded"
			@timeupdate="audioTimeupdate"
			@loadeddata="audioLoadeddata"
			ref="audioRef"
			class="w100"
		></audio>-->
		<div class="audio">
			<div class="slider-wrap ml10 mr10" ref="progressRef">
				<el-slider v-model="audioData.percentage" @input="inputProgress" @change="changeProgress" :format-tooltip="formatTooltip"> </el-slider>
				<div class="flex-center-between">
					<el-text>
						{{ formatDuration(Math.round(audioData.currentTime)) }}
					</el-text>
					<el-text>
						{{ formatDuration(Math.round(audioData.duration)) }}
					</el-text>
				</div>
			</div>
			<div class="icon-div">
				<div class="flex-center-center">
					<SvgIcon @click="handleBack" name="ele-DArrowLeft" title="快退" class="mr5 cursor-pointer" size="24px" color="var(--el-color-primary)" />
					<el-text class="mr20" size="small" type="info">-{{ props.backSecond }}S</el-text>
				</div>
				<SvgIcon
					@click="playPauseAudio"
					:name="audioData.playing ? 'ele-VideoPause' : 'ele-VideoPlay'"
					:title="audioData.playing ? '暂停' : '播放'"
					class="mr5 cursor-pointer"
					size="36px"
					color="var(--el-color-primary)"
				/>
				<div class="flex-center-center">
					<el-text class="ml20" size="small" type="info">+{{ props.forwardSecond }}S</el-text>
					<SvgIcon
						@click="handleForward"
						name="ele-DArrowRight"
						title="快进"
						class="ml5 cursor-pointer"
						size="24px"
						color="var(--el-color-primary)"
					/>
				</div>
				<div class="voice">
					<el-dropdown trigger="hover">
						<SvgIcon :name="icon" class="mr5 ml5 cursor-pointer" size="18px" color="var(--el-color-primary)" @click="mute" />
						<template #dropdown>
							<el-dropdown-menu>
								<el-slider v-model="audioData.voice" vertical height="100px" @change="changeSound" style="padding:10px 0 "/>
							</el-dropdown-menu>
						</template>
					</el-dropdown>
					<el-dropdown @command="changeSpeed" trigger="hover">
						<el-button type="primary" link>{{speed}}倍速</el-button>
									<template #dropdown>
										<el-dropdown-menu>
											<el-dropdown-item command="0.5">0.5</el-dropdown-item>
											<el-dropdown-item command="1">1</el-dropdown-item>
											<el-dropdown-item command="1.5">1.5</el-dropdown-item>
											<el-dropdown-item command="2">2</el-dropdown-item>
											<el-dropdown-item command="2.5">2.5</el-dropdown-item>
											<el-dropdown-item command="3">3</el-dropdown-item>
										</el-dropdown-menu>
									</template>
								</el-dropdown>
				</div>
			</div>
		</div>
		<audio :src="audioData.url" preload="auto" @ended="audioEnded" @timeupdate="audioTimeupdate" @loadeddata="audioLoadeddata" ref="audioRef"></audio>
	</div>
</template>
<script lang="ts" name="GloWeAudio" setup>
import { reactive, ref, computed, watch, nextTick } from 'vue';
import { formatDuration } from '@/utils/formatTime';
import { ElMessage } from 'element-plus';

// 定义父组件传过来的值
const props = defineProps({
	url: {
		type: String,
		required: true,
	},
	backSecond: {
		// 快退时间
		type: Number,
		default: 3,
	},
	forwardSecond: {
		// 快进时间
		type: Number,
		default: 3,
	},
});

// 定义变量内容
const audioData = reactive<any>({
	url: props.url,
	playing: false,
	duration: 0, // 音频总时长
	currentTime: 0, // 当前播放的时间
	percentage: 0, //进度条百分比
	voice: 100, //音量
	muteState: false, //是否静音
});

const audioRef = ref<RefType>();
// 播放或暂停音频
const playPauseAudio = () => {
	if (audioData.playing) {
		audioPause();
	} else {
		audioPlay();
	}
};
// 快退
const handleBack = () => {
	if (audioData.currentTime - props.backSecond < 0) {
		audioData.currentTime = 0;
		progressBarByCurrentTime();
		return;
	}
	audioRef.value.currentTime = audioData.currentTime - props.backSecond;
	audioData.currentTime = audioRef.value.currentTime;
	progressBarByCurrentTime();
};
// 快进
const handleForward = () => {
	if (audioData.currentTime + props.forwardSecond > audioData.duration) {
		audioData.currentTime = audioData.duration;
		progressBarByCurrentTime();
		return;
	}
	audioRef.value.currentTime = audioData.currentTime + props.forwardSecond;
	audioData.currentTime = audioRef.value.currentTime;
	progressBarByCurrentTime();
};
const icon = computed(() => {
	if (audioData.muteState) {
		return 'iconfont icon-guanbiyinliang';
	} else {
		return 'iconfont icon-jiadayinliang';
	}
});
// 计算百分比的分子
function getPercentage(num: number | string, den: number | string): number {
	const numerator = typeof num === 'number' ? num : parseFloat(num);
	const denominator = typeof den === 'number' ? den : parseFloat(den);
	return Math.round((numerator / denominator) * 10000) / 100;
}
/**
 * 更新进度条
 * @param percentage 百分比
 */
function updateProgressBar(percentage: number) {
	audioData.percentage = percentage;
}

/**
 * 以下是对音频的操作
 */

// 音频播放结束
const audioEnded = () => {
	audioData.playing = false;
};
// 播放进度：表示audio正在播放，currentTime在更新
const audioTimeupdate = (e: any) => {
	audioData.currentTime = e.target.currentTime;
	progressBarByCurrentTime();
};
// 当媒体音频第一帧加载完成时
const audioLoadeddata = (e: any) => {
	audioData.duration = e.target.duration;
};

// 播放
function audioPlay() {
	audioRef.value.play();
	audioData.playing = true;
}

// 暂停播放
function audioPause() {
	audioRef.value.pause();
	audioData.playing = false;
}

// 进度条和音频播放进度进行关联
function progressBarByCurrentTime() {
	const progress = getPercentage(audioData.currentTime, audioData.duration);
	updateProgressBar(progress);
}

//  改变进度 暂停 使用鼠标拖曳时，活动过程实时触发
const inputProgress = (val: number) => {
	audioData.percentage = val;
	audioData.currentTime = audioData.duration * (val / 100);
	audioRef.value.currentTime = audioData.duration * (val / 100);
	audioRef.value.pause();
};
// 使用鼠标拖曳时，只在松开鼠标后触发 继续播放
const changeProgress = () => {
	if (audioData.playing) audioPlay();
};
// 格式化提示
const formatTooltip = (val: number) => {
	return formatDuration(Math.round(audioData.duration * (val / 100)));
};
// 改变音量
const changeSound = (val: number) => {
	audioData.muteState = val <= 0;
	audioRef.value.volume = val / 100;
	audioData.voice = val;
};
// 监听声音大小
watch(
	() => audioData.muteState,
	(val) => {
		if (val) {
			audioRef.value.volume = audioData.voice = 0;
		} else {
			audioRef.value.volume = 1;
			audioData.voice = 100;
		}
	},
	{
		deep: true,
	}
);
// 静音
const mute = () => {
	audioData.muteState = !audioData.muteState;
};
// 改变倍速
const speed = ref(1);
const changeSpeed = (val: number) => {
	audioRef.value.playbackRate = val;
	speed.value = val;
};
nextTick(() => {
	audioRef.value.onerror = () => {
		ElMessage.error('音频加载失败');
	};
});
defineExpose({
	playPauseAudio,
	handleBack,
	handleForward,
	inputProgress,
	changeProgress,
	formatTooltip,
	changeSound,
	mute,
})
</script>
<style scoped lang="scss">
.gloWe-audio {
	.audio {
		.icon-div {
			display: flex;
			align-items: center;
			justify-content: center;
			border-radius: 100%;
			margin-right: 10px;
			position: relative;
		}
		.voice {
			position: absolute;
			top: 9px;
			right: 0;
			display: flex;
			align-items: center;
			justify-content: center;
		}
		.slider-wrap {
			position: relative;
			min-width: 200px;
		}
	}
}
</style>
