vue3+ts项目封装音频播放与使用

AudioPlayer.vue

<template>
    <!-- 这个组件是一个逻辑组件,不需要渲染任何UI -->
    <span></span>
  </template>
  
  <script lang="ts">
  import { defineComponent, watch, onUnmounted, ref } from 'vue'
  
  export default defineComponent({
    name: 'AudioPlayer',
    props: {
      // 音频源,可以是URL或base64数据
      src: {
        type: String,
        required: true
      },
      // 控制播放状态:'play' 开始播放,'stop' 停止播放
      command: {
        type: String as () => 'play' | 'stop',
        default: 'stop',
        validator: (value: string) => ['play', 'stop'].includes(value)
      },
      // 是否循环播放
      loop: {
        type: Boolean,
        default: false
      },
      // 音量 0-1
      volume: {
        type: Number,
        default: 1,
        validator: (value: number) => value >= 0 && value <= 1
      }
    },
    emits: ['play-start', 'play-end', 'play-error'],
    setup(props, { emit }) {
      const audioRef = ref<HTMLAudioElement | null>(null)
      let audio: HTMLAudioElement | null = null
  
      // 初始化音频
      const initAudio = () => {
        if (audio) {
          destroyAudio()
        }
        audio = new Audio(props.src)
        audio.loop = props.loop
        audio.volume = props.volume
        
        audio.addEventListener('ended', handlePlayEnd)
        audio.addEventListener('error', handlePlayError)
      }
  
      // 销毁音频
      const destroyAudio = () => {
        if (audio) {
          stop()
          audio.removeEventListener('ended', handlePlayEnd)
          audio.removeEventListener('error', handlePlayError)
          audio = null
        }
      }
  
      // 播放音频
      const play = async () => {
        if (!audio) {
          initAudio()
        }
        
        try {
          if (audio) {
            await audio.play()
            emit('play-start')
          }
        } catch (error) {
          emit('play-error', error)
        }
      }
  
      // 停止播放
      const stop = () => {
        if (audio && !audio.paused) {
          audio.pause()
          audio.currentTime = 0
          emit('play-end')
        }
      }
  
      const handlePlayEnd = () => {
        if (!props.loop) {
          emit('play-end')
        }
      }
  
      const handlePlayError = (error: Event) => {
        emit('play-error', error)
      }
  
      // 监听命令变化
      watch(() => props.command, (newCommand) => {
        if (newCommand === 'play') {
          play()
        } else if (newCommand === 'stop') {
          stop()
        }
      })
  
      // 监听src变化
      watch(() => props.src, () => {
        initAudio()
      })
  
      // 监听音量变化
      watch(() => props.volume, (newVolume) => {
        if (audio) {
          audio.volume = newVolume
        }
      })
  
      // 监听循环设置变化
      watch(() => props.loop, (newLoop) => {
        if (audio) {
          audio.loop = newLoop
        }
      })
  
      // 组件卸载时清理
      onUnmounted(() => {
        destroyAudio()
      })
  
      return {
        audioRef
      }
    }
  })
  </script>

使用AudioPlayer.vue
(该组件有个bug时好时坏,详情描述:需播放4个音频文件,点击播放按钮播放完第一个音频后,在音频播放完成方法onPlayEnd中继续写播放第二个音频,其次第三个,依此类推,会出现只播放完第一个音频后其余的几个都不播放,或者播放完前3个第四个不播放的情况,但在控制台打印都正常,所以有了第二个音频组件。q_q)

<template>
<button class='btn' @click='playAudio'>点击播放音频</button>
<AudioPlayer 
            :src="audioSrc" 
            :command="playCommand" 
            @play-start="onPlayStart"
            @play-end="onPlayEnd"
            @play-error="onPlayError"
            v-if="audioSrc"
        />
</temp
late>
<script lang="ts" steup>
import { ref  } from 'vue'
import AudioPlayer from '@/components/AudioPlayer.vue'
import audio1 from '@/assets/audio/1.MP3'

const audioSrc = ref<any>(audio1);
const playCommand = ref<'play' | 'stop'>('stop')

// 开始播放音频
const startPlay = (src : any) => {
    stopPlay();
    audioSrc.value = src;
    setTimeout(() => {
        playCommand.value = 'play'
    }, 100);
}
// 停止播放音频
const stopPlay = () => {
    console.log('停止播放音频')
    playCommand.value = 'stop'
}
// 音频播放开始
const onPlayStart = () => {
    console.log('音频开始播放')
}
// 音频播放结束
const onPlayEnd = () => {
    // console.log('音频播放结束')
    playCommand.value = 'stop'; // 重置状态 
    
}
// 音频播放出错
const onPlayError = (error: Event) => {
    console.error('播放错误:', error)
    playCommand.value = 'stop' // 出错时也重置状态
}


AudioPlayerV2.vue (解决上一个组件连续播放多个音频无声bug)

<template>
    <audio controls ref="audioPlayer"></audio>
</template>
<script lang="ts" setup>
import { ref, defineEmits, defineProps, defineExpose } from 'vue'

//组件参数获取
const props = defineProps({ 
    // 是否显示弹框
    audioList: {
        type: Array,
        default: [] as any[]
    // 当前播放的音频索引
    },
});

const audioPlayer = ref<HTMLAudioElement | null>(null);
let currentIndex = 0;

const playAudioSequence = () => {
  currentIndex = 0
  playNextAudio()
}

const playNextAudio = () => {
  if (!audioPlayer.value || currentIndex >= props.audioList.length) return
  
  // 设置音频源
  audioPlayer.value.src = String(props.audioList[currentIndex]);
  
  // 播放当前音频
  audioPlayer.value.play().catch(error => {
    console.error('播放失败:', error)
  })
  
  // 监听播放结束事件
  audioPlayer.value.onended = () => {
    currentIndex++
    if (currentIndex < props.audioList.length) {
      // 延迟500毫秒播放下一个音频
      setTimeout(playNextAudio, 500)
    }
  }
}

defineExpose({
  playAudioSequence,
})

</script>

使用方法

<template>
<button class='btn' @click='playAudioSequence'>点击播放音频</button>
<AudioPlayerV2 ref="audioPlayer" :audio-list="audioList"/>
</temp
late>
<script lang="ts" steup>
import { ref  } from 'vue'
import AudioPlayerV2 from '@/components/m/AudioPlayerV2.vue';
import audio1 from '@/assets/audio/1.MP3'
import audio2 from '@/assets/audio/2.MP3'
import audio3 from '@/assets/audio/3.MP3'
import audio4 from '@/assets/audio/4.MP3'

const audioPlayer = ref<InstanceType<typeof AudioPlayerV2> | null>(null);
const audioList = ref([audio1, audio2, audio3, audio4]);

const playAudioSequence = () => {
    audioPlayer.value?.playAudioSequence();
}

### 集成科大讯飞 IAT 到 Vue3 项目中的方法 为了在基于 Vite 和 TypeScript 的 Vue3 项目中集成科大讯飞的 IAT (语音转文字),需要完成几个关键步骤来确保一切正常工作。 #### 安装必要的依赖库 首先,需安装科大讯飞提供的 JavaScript SDK 或者对应的 NPM 包。通常情况下,可以通过 npm 来安装: ```bash npm install web-speech-api --save ``` 注意:`web-speech-api` 是一个假设的例子;实际应按照官方文档指引找到适合的包名称并替换上述命令[^1]。 #### 修改 `vite.config.ts` 为了让 Webpack 能够处理新的模块,在项目的根目录下的 `vite.config.ts` 文件里添加相应的配置项以便支持新加入的服务端口或资源加载方式。如果涉及到音频流或者其他特殊类型的文件,则可能还需要调整构建工具的相关设置以适应这些需求。 ```typescript import { defineConfig } from &#39;vite&#39; import vue from &#39;@vitejs/plugin-vue&#39; export default defineConfig({ plugins: [ vue() ], server: { port: 3000, open: true // 自动启动浏览器窗口访问应用 }, optimizeDeps: { include: [&#39;web-speech-api&#39;] // 假设这里是要优化的第三方库列表 } }) ``` #### 创建服务接口组件 创建一个新的 Vue 组件用于封装科大讯飞 API 进行交互的功能逻辑。这一步骤涉及到了解 RESTful API 设计模式以及如何通过 Axios 等 HTTP 请求库发送请求给服务器获取数据[^2]。 ```html <template> <!-- UI Elements --> </template> <script lang="ts"> import { ref, onMounted } from &#39;vue&#39;; // 导入科大讯飞SDK或其他相关类库 declare const IFlytekIatAPI: any; export default ({ name: &#39;SpeechToTextComponent&#39;, setup() { let result = ref<string>(&#39;&#39;); async function initRecognition(): Promise<void> { try { await IFlytekIatAPI.initialize(); console.log(&#39;Initialization successful&#39;); IFlytekIatAPI.startListening((text:string) => { result.value += text; }); } catch(error){ console.error(`Error initializing speech recognition ${error}`); } }; onMounted(() => { initRecognition(); }); return { result }; }, }); </script> ``` 此代码片段展示了如何初始化和监听来自用户的语音输入,并将其转换为文本字符串存储于响应式的变量之中。请注意这里的 `IFlytekIatAPI` 只是一个占位符,具体实现应当参照所使用的 SDK 文档来进行适当修改。 #### 更新 tsconfig.json 最后不要忘记更新你的 `tsconfig.json` 文件,使其能够识别新增加的类型定义和其他自定义声明。这样可以保证编译过程顺利无误地进行下去[^3]。 ```json { "compilerOptions": { ... }, "include": [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue" ] } ``` 以上就是在一个典型的 Vue3 + Vite + TypeScript 开发环境中集成了科大讯飞 IAT 功能的大致流程概述。当然实际情况可能会更加复杂一些,建议仔细阅读各个部分的具体指南和技术手册来获得最准确的信息和支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值