|
@@ -11,7 +11,7 @@ import styles from './audio.module.less';
|
|
|
import iconplay from '../image/icon-pause.png';
|
|
|
import iconpause from '../image/icon-play.png';
|
|
|
import iconReplay from '../image/icon-replay.png';
|
|
|
-import { NSlider } from 'naive-ui';
|
|
|
+import { NSlider, useMessage } from 'naive-ui';
|
|
|
import Vudio from 'vudio.js';
|
|
|
import tickMp3 from '../image/tick.mp3';
|
|
|
|
|
@@ -43,6 +43,7 @@ export default defineComponent({
|
|
|
},
|
|
|
emits: ['loadedmetadata', 'togglePlay', 'ended', 'reset'],
|
|
|
setup(props, { emit, expose }) {
|
|
|
+ const message = useMessage()
|
|
|
const audioForms = reactive({
|
|
|
paused: true,
|
|
|
speedInKbps: '',
|
|
@@ -56,7 +57,10 @@ export default defineComponent({
|
|
|
afterMa3: true,
|
|
|
count: 0,
|
|
|
previousBytesLoaded: 0,
|
|
|
- previousTime: Date.now()
|
|
|
+ previousTime: Date.now(),
|
|
|
+ // 添加缓冲状态标识
|
|
|
+ isBuffering: false,
|
|
|
+ bufferTimeout: null as any
|
|
|
});
|
|
|
const canvas: any = ref();
|
|
|
const audio: any = ref();
|
|
@@ -155,6 +159,7 @@ export default defineComponent({
|
|
|
onToggleAudio();
|
|
|
} else {
|
|
|
audio.value.pause();
|
|
|
+ audioForms.paused = audio.value?.paused;
|
|
|
}
|
|
|
}
|
|
|
);
|
|
@@ -423,8 +428,14 @@ export default defineComponent({
|
|
|
const currentTime = audio.value.currentTime;
|
|
|
audio.value.load();
|
|
|
audio.value.currentTime = currentTime;
|
|
|
+ audio.value.pause();
|
|
|
+ audioForms.paused = audio.value?.paused;
|
|
|
} else if (val.type === 'offline') {
|
|
|
audioForms.isOnline = false;
|
|
|
+
|
|
|
+ // 去掉检测加载缓存
|
|
|
+ audioForms.isBuffering = false;
|
|
|
+ audioForms.bufferTimeout && clearTimeout(audioForms.bufferTimeout);
|
|
|
}
|
|
|
};
|
|
|
onMounted(() => {
|
|
@@ -499,6 +510,36 @@ export default defineComponent({
|
|
|
}
|
|
|
emit('loadedmetadata', audio.value);
|
|
|
}}
|
|
|
+ onWaiting={() => {
|
|
|
+ audioForms.isBuffering = true;
|
|
|
+
|
|
|
+ audioForms.bufferTimeout &&
|
|
|
+ clearTimeout(audioForms.bufferTimeout);
|
|
|
+
|
|
|
+ // 设置缓冲超时检测(5秒)
|
|
|
+ audioForms.bufferTimeout = setTimeout(() => {
|
|
|
+ if (audioForms.isBuffering) {
|
|
|
+ console.log('缓冲超时,暂停播放');
|
|
|
+ audio.value?.pause();
|
|
|
+ audioForms.paused = true;
|
|
|
+ message.info('网络连接不稳定,请检查网络后继续播放', {
|
|
|
+ showIcon: false,
|
|
|
+ render: (props: any) => {
|
|
|
+ return (
|
|
|
+ <div style="background: rgba(0,0,0,.6); color: #fff; border-radius: 8px; padding: 6px 16px;">
|
|
|
+ {props.content}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ audio.value.currentTime = audio.value.currentTime + 0.01;
|
|
|
+ }
|
|
|
+ }, 15000);
|
|
|
+ }}
|
|
|
+ onCanplay={() => {
|
|
|
+ audioForms.isBuffering = false;
|
|
|
+ audioForms.bufferTimeout && clearTimeout(audioForms.bufferTimeout); // 清除超时检测
|
|
|
+ }}
|
|
|
onError={() => {
|
|
|
audio.value?.pause();
|
|
|
audioForms.paused = audio.value?.paused;
|
|
@@ -524,19 +565,21 @@ export default defineComponent({
|
|
|
emit('reset');
|
|
|
}}>
|
|
|
<div class={styles.slider}>
|
|
|
- {props.imagePos !== 'right' && <div class={styles.time}>
|
|
|
- <div
|
|
|
- class="plyr__time plyr__time--current"
|
|
|
- aria-label="Current time">
|
|
|
- {audioForms.currentTime}
|
|
|
- </div>
|
|
|
- <span class={styles.line}>/</span>
|
|
|
- <div
|
|
|
- class="plyr__time plyr__time--duration"
|
|
|
- aria-label="Duration">
|
|
|
- {audioForms.duration}
|
|
|
+ {props.imagePos !== 'right' && (
|
|
|
+ <div class={styles.time}>
|
|
|
+ <div
|
|
|
+ class="plyr__time plyr__time--current"
|
|
|
+ aria-label="Current time">
|
|
|
+ {audioForms.currentTime}
|
|
|
+ </div>
|
|
|
+ <span class={styles.line}>/</span>
|
|
|
+ <div
|
|
|
+ class="plyr__time plyr__time--duration"
|
|
|
+ aria-label="Duration">
|
|
|
+ {audioForms.duration}
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>}
|
|
|
+ )}
|
|
|
|
|
|
<NSlider
|
|
|
value={audioForms.currentTimeNum}
|
|
@@ -549,19 +592,21 @@ export default defineComponent({
|
|
|
audioForms.currentTime = timeFormat(Math.round(val || 0));
|
|
|
}}
|
|
|
/>
|
|
|
- {props.imagePos === 'right' && <div class={[styles.time, styles.rightTime]}>
|
|
|
- <div
|
|
|
- class="plyr__time plyr__time--current"
|
|
|
- aria-label="Current time">
|
|
|
- {audioForms.currentTime}
|
|
|
- </div>
|
|
|
- <span class={styles.line}>/</span>
|
|
|
- <div
|
|
|
- class="plyr__time plyr__time--duration"
|
|
|
- aria-label="Duration">
|
|
|
- {audioForms.duration}
|
|
|
+ {props.imagePos === 'right' && (
|
|
|
+ <div class={[styles.time, styles.rightTime]}>
|
|
|
+ <div
|
|
|
+ class="plyr__time plyr__time--current"
|
|
|
+ aria-label="Current time">
|
|
|
+ {audioForms.currentTime}
|
|
|
+ </div>
|
|
|
+ <span class={styles.line}>/</span>
|
|
|
+ <div
|
|
|
+ class="plyr__time plyr__time--duration"
|
|
|
+ aria-label="Duration">
|
|
|
+ {audioForms.duration}
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>}
|
|
|
+ )}
|
|
|
</div>
|
|
|
<div class={styles.tools}>
|
|
|
{props.imagePos === 'right' ? (
|