|
@@ -11,32 +11,60 @@
|
|
|
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="mr10 cursor-pointer"
|
|
|
- size="24px"
|
|
|
+ class="mr5 cursor-pointer"
|
|
|
+ size="36px"
|
|
|
color="var(--el-color-primary)"
|
|
|
/>
|
|
|
- <div class="time-wrap">
|
|
|
- <span class="time">{{ formatDuration(Math.round(audioData.currentTime)) }}/{{ formatDuration(Math.round(audioData.duration)) }}</span>
|
|
|
+ <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" />
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </template>
|
|
|
+ </el-dropdown>
|
|
|
+ <!-- <SvgIcon name="ele-Download" class="cursor-pointer ml5" size="18px" color="var(--el-color-primary)" @click="downLoad" title="下载" />-->
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="slider-wrap ml10 mr10" ref="progressRef">
|
|
|
- <el-slider v-model="audioData.percentage" @input="inputProgress" @change="changeProgress" :format-tooltip="formatTooltip"> </el-slider>
|
|
|
- </div>
|
|
|
-
|
|
|
- <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" />
|
|
|
- </el-dropdown-menu>
|
|
|
- </template>
|
|
|
- </el-dropdown>
|
|
|
-<!-- <SvgIcon name="ele-Download" class="cursor-pointer ml5" size="18px" color="var(--el-color-primary)" @click="downLoad" title="下载" />-->
|
|
|
</div>
|
|
|
<audio :src="audioData.url" preload="auto" @ended="audioEnded" @timeupdate="audioTimeupdate" @loadeddata="audioLoadeddata" ref="audioRef"></audio>
|
|
|
</div>
|
|
@@ -58,6 +86,16 @@ const props = defineProps({
|
|
|
required: false,
|
|
|
default: '测试文件',
|
|
|
},
|
|
|
+ backSecond: {
|
|
|
+ // 快退时间
|
|
|
+ type: Number,
|
|
|
+ default: 3,
|
|
|
+ },
|
|
|
+ forwardSecond: {
|
|
|
+ // 快进时间
|
|
|
+ type: Number,
|
|
|
+ default: 3,
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
// 定义变量内容
|
|
@@ -80,6 +118,28 @@ const playPauseAudio = () => {
|
|
|
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';
|
|
@@ -192,20 +252,24 @@ nextTick(() => {
|
|
|
<style scoped lang="scss">
|
|
|
.gloWe-audio {
|
|
|
.audio {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
.icon-div {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
+ justify-content: center;
|
|
|
border-radius: 100%;
|
|
|
margin-right: 10px;
|
|
|
- }
|
|
|
-
|
|
|
- .slider-wrap {
|
|
|
position: relative;
|
|
|
+ }
|
|
|
+ .voice {
|
|
|
+ position: absolute;
|
|
|
+ top: 9px;
|
|
|
+ right: 0;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+ .slider-wrap {
|
|
|
+ position: relative;
|
|
|
min-width: 200px;
|
|
|
}
|
|
|
}
|