123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- import { defineComponent, onMounted, toRefs, reactive } from 'vue';
- import styles from './audio.module.less';
- import WaveSurfer from 'wavesurfer.js';
- import iconplay from '../image/icon-pause.svg';
- import iconpause from '../image/icon-play.svg';
- import { NSlider } from 'naive-ui';
- export default defineComponent({
- name: 'audio-play',
- props: {
- item: {
- type: Object,
- default: () => {
- return {};
- }
- },
- isEmtry: {
- type: Boolean,
- default: false
- }
- },
- setup(props) {
- const { item } = toRefs(props);
- const audioId = 'a' + +Date.now() + Math.floor(Math.random() * 100);
- const audioForms = reactive({
- paused: true,
- currentTimeNum: 0,
- currentTime: '00:00',
- duration: '00:00'
- });
- const audioDom = new Audio();
- audioDom.controls = true;
- audioDom.style.width = '100%';
- audioDom.className = styles.audio;
- document.querySelector(`#${audioId}`)?.appendChild(audioDom);
- onMounted(() => {
- const wavesurfer = WaveSurfer.create({
- container: document.querySelector(`#${audioId}`) as HTMLElement,
- waveColor: '#C5C5C5',
- progressColor: '#02baff',
- url: item.value.content + '?t=' + +new Date(),
- cursorWidth: 0,
- height: 160,
- normalize: true,
- // Set a bar width
- barWidth: 6,
- // Optionally, specify the spacing between bars
- barGap: 12,
- // And the bar radius
- barRadius: 12,
- autoScroll: true,
- /** If autoScroll is enabled, keep the cursor in the center of the waveform during playback */
- autoCenter: true,
- hideScrollbar: false,
- media: audioDom
- });
- wavesurfer.once('interaction', () => {
- // wavesurfer.play();
- });
- wavesurfer.once('ready', () => {
- audioForms.paused = audioDom.paused;
- audioForms.duration = timeFormat(Math.round(audioDom.duration));
- });
- wavesurfer.on('finish', () => {
- audioForms.paused = true;
- });
- });
- // 切换音频播放
- const onToggleAudio = (e: MouseEvent) => {
- e.stopPropagation();
- if (audioDom.paused) {
- audioDom.play();
- } else {
- audioDom.pause();
- }
- audioForms.paused = audioDom.paused;
- };
- // 播放时监听
- audioDom.addEventListener('timeupdate', () => {
- audioForms.currentTime = timeFormat(Math.round(audioDom.currentTime));
- audioForms.currentTimeNum = audioDom.currentTime;
- });
- // 播放结束时
- // 对时间进行格式化
- const timeFormat = (num: number) => {
- if (num > 0) {
- const m = Math.floor(num / 60);
- const s = num % 60;
- return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
- } else {
- return '00:00';
- }
- };
- return () => (
- <div class={styles.audioWrap}>
- <div class={styles.audioContainer}>
- <div
- id={audioId}
- onClick={(e: MouseEvent) => {
- e.stopPropagation();
- }}></div>
- </div>
- <div
- class={styles.controls}
- onClick={(e: MouseEvent) => {
- e.stopPropagation();
- }}>
- <div class={styles.actions}>
- <div class={styles.actionWrap}>
- <button class={styles.actionBtn} onClick={onToggleAudio}>
- {audioForms.paused ? (
- <img class={styles.playIcon} src={iconplay} />
- ) : (
- <img class={styles.playIcon} src={iconpause} />
- )}
- </button>
- </div>
- <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>
- <div class={styles.slider}>
- <NSlider
- v-model:value={audioForms.currentTimeNum}
- step={0.01}
- max={audioDom.duration}
- tooltip={false}
- />
- </div>
- </div>
- </div>
- );
- }
- });
|