Parcourir la source

feat: 新增音频播放器

xiaohong il y a 9 mois
Parent
commit
806888cce8

+ 2 - 2
src/views/ai/music/components/index.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-  <div class="flex h-1/1">
+  <div class="flex ">
     <!-- 模式 -->
     <!-- 模式 -->
     <Mode class="flex-none" @generate-music="generateMusic"/>
     <Mode class="flex-none" @generate-music="generateMusic"/>
     <!-- 音频列表 -->
     <!-- 音频列表 -->
@@ -13,7 +13,7 @@ import List from './list/index.vue'
 
 
 defineOptions({ name: 'Index' })
 defineOptions({ name: 'Index' })
 
 
-const listRef = ref<{generateMusic: (...args) => void} | null>(null)
+const listRef = ref<Nullable<{generateMusic: (...args) => void}>>(null)
 
 
 function generateMusic (args: {formData: Recordable}) {
 function generateMusic (args: {formData: Recordable}) {
  unref(listRef)?.generateMusic(args.formData)
  unref(listRef)?.generateMusic(args.formData)

+ 60 - 1
src/views/ai/music/components/list/audioBar/index.vue

@@ -1,9 +1,68 @@
 <template>
 <template>
-  <div class="h-72px bg-[var(--el-bg-color-overlay)] b-solid b-1 b-[var(--el-border-color)] b-l-none">播放器</div>
+  <div class="flex items-center justify-between px-2 h-72px bg-[var(--el-bg-color-overlay)] b-solid b-1 b-[var(--el-border-color)] b-l-none">
+    <!-- 歌曲信息 -->
+    <div class="flex gap-[10px]">
+      <el-image src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" class="w-[45px]"/>
+      <div>
+        <div>我很好</div>
+        <div class="text-[12px] text-gray-400">刘大壮</div>
+      </div>
+    </div>
+      
+    <!-- 音频controls -->
+    <div class="flex gap-[12px] items-center">
+      <Icon icon="majesticons:back-circle" :size="20" class="text-gray-300 cursor-pointer"/>
+      <Icon :icon="audioProps.paused ? 'mdi:arrow-right-drop-circle' : 'solar:pause-circle-bold'" :size="30" class=" cursor-pointer" @click="toggleStatus('paused')"/>
+      <Icon icon="majesticons:next-circle" :size="20" class="text-gray-300 cursor-pointer"/>
+      <div class="flex gap-[16px] items-center">
+        <span>{{audioProps.currentTime}}</span>
+        <el-slider v-model="audioProps.duration" color="#409eff" class="w-[160px!important] "/>
+        <span>{{ audioProps.duration }}</span>
+      </div>
+      <!-- 音频 -->
+      <audio v-bind="audioProps" ref="audioRef" controls v-show="!audioProps" @timeupdate="audioTimeUpdate">
+        <source :src="response"/>
+      </audio>
+    </div>
+
+    <!-- 音量控制器 -->
+    <div class="flex gap-[16px] items-center">
+      <Icon :icon="audioProps.muted ? 'tabler:volume-off' : 'tabler:volume'" :size="20" class="cursor-pointer" @click="toggleStatus('muted')"/>
+      <el-slider v-model="audioProps.volume" color="#409eff" class="w-[160px!important] "/>
+    </div>
+  </div>
 </template>
 </template>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
+import { formatPast } from '@/utils/formatTime'
+import response from '@/assets/audio/response.mp3'
 
 
 defineOptions({ name: 'Index' })
 defineOptions({ name: 'Index' })
 
 
+  const audioRef = ref<Nullable<HTMLElement>>(null)
+    // 音频相关属性https://www.runoob.com/tags/ref-av-dom.html
+  const audioProps = reactive({
+    autoplay: true,
+    paused: false,
+    currentTime: '00:00',
+    duration: '00:00',
+    muted:  false,
+    volume: 50,
+  })
+
+  function toggleStatus (type: string) {
+    audioProps[type] = !audioProps[type]
+    if (type === 'paused' && audioRef.value) {
+      if (audioProps[type]) {
+        audioRef.value.pause()
+      } else {
+        audioRef.value.play()
+      }
+    }
+  }
+
+  // 更新播放位置
+  function audioTimeUpdate (args) {
+    audioProps.currentTime = formatPast(new Date(args.timeStamp), 'mm:ss')
+  }
 </script>
 </script>

+ 1 - 1
src/views/ai/music/components/list/index.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-  <div class="flex flex-col h-full">
+  <div class="flex flex-col h-[600px]">
     <div class="flex-auto flex overflow-hidden">
     <div class="flex-auto flex overflow-hidden">
       <el-tabs v-model="currentType" class="flex-auto px-[var(--app-content-padding)]">
       <el-tabs v-model="currentType" class="flex-auto px-[var(--app-content-padding)]">
         <!-- 我的创作 -->
         <!-- 我的创作 -->

+ 2 - 5
src/views/ai/music/components/mode/index.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-  <ContentWrap class="w-300px h-full">
+  <ContentWrap class="w-300px h-full mb-[0!important]">
     <el-radio-group v-model="generateMode" class="mb-15px">
     <el-radio-group v-model="generateMode" class="mb-15px">
       <el-radio-button label="desc">
       <el-radio-button label="desc">
         描述模式
         描述模式
@@ -28,10 +28,7 @@ const emits = defineEmits(['generate-music'])
 
 
 const generateMode = ref('lyric')
 const generateMode = ref('lyric')
 
 
-interface ModeRef {
-  formData: Recordable
-}
-const modeRef = ref<ModeRef | null>(null)
+const modeRef = ref<Nullable<{ formData: Recordable }>>(null)
 
 
 /*
 /*
  *@Description: 根据信息生成音乐
  *@Description: 根据信息生成音乐