mic.vue 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <template>
  2. <Icon
  3. name="mic"
  4. :size="22"
  5. :color="show && rtcConnected ? '#00CED1' : 'rgba(255, 255, 255, 0.5)'"
  6. style="margin-left: 6px;"
  7. @click="change"
  8. />
  9. </template>
  10. <script setup lang='ts'>
  11. import { useNotification } from 'naive-ui'
  12. import {
  13. computed, onMounted, onUnmounted, ref
  14. } from 'vue'
  15. import useStore from '@/store'
  16. const props = withDefaults(defineProps<{ value?: number }>(), { value: 5000 })
  17. const emit = defineEmits<{(evt: 'callBack', value: Blob): void }>()
  18. const notice = useNotification()
  19. const store = useStore()
  20. const rtcConnected = computed(() => store.rtcConnected)
  21. const show = ref(false)
  22. let chunks = [] as Blob[]
  23. let audio = null as null | MediaRecorder
  24. let timer = null as Any
  25. async function initMic() {
  26. try {
  27. const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
  28. audio = new MediaRecorder(stream)
  29. audio.ondataavailable = (e: { data: Blob }) => {
  30. chunks.push(e.data)
  31. }
  32. audio.onstart = () => {
  33. chunks = []
  34. }
  35. audio.onstop = () => {
  36. const blob = new Blob(chunks, { type: 'audio/webm;codecs=opus' })
  37. emit('callBack', blob)
  38. }
  39. } catch (error: any) {
  40. console.log('录音错误', error)
  41. const type = error.toString().includes('getUserMedia')
  42. notice.warning({ title: type ? '不支持webrtc音频' : '未获取到音频设备', duration: 2000 })
  43. }
  44. }
  45. function distory() {
  46. if (audio) audio.stop()
  47. chunks = []
  48. audio = null
  49. }
  50. function change() {
  51. if (!rtcConnected.value) return
  52. show.value = !show.value
  53. if (!audio) return
  54. if (show.value) { audio?.start(); timer = setTimeout(() => { show.value = false; audio?.stop() }, props.value) } else { audio?.stop(); clearTimeout(timer) }
  55. console.log('mic', show.value)
  56. }
  57. onMounted(() => initMic())
  58. onUnmounted(() => distory())
  59. </script>
  60. <style lang="scss" scoped>
  61. svg {
  62. cursor: pointer;
  63. }
  64. </style>