Pārlūkot izejas kodu

feat: 完善AI音频播放

xiaohong 10 mēneši atpakaļ
vecāks
revīzija
7f7c508bb2

BIN
src/assets/audio/response.mp3


+ 2 - 1
src/layout/components/AppView.vue

@@ -57,7 +57,8 @@ provide('reload', reload)
 
         '!min-h-[calc(100%-var(--top-tool-height)-var(--app-content-padding)-var(--app-content-padding)-var(--tags-view-height))]':
           !fixedHeader && layout === 'cutMenu' && footer
-      }
+      },
+      'h-0'
     ]"
   >
     <router-view v-if="routerAlive">

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

@@ -1,5 +1,5 @@
 <template>
-  <div class="flex ">
+<div class="flex h-full items-stretch">
     <!-- 模式 -->
     <Mode class="flex-none" @generate-music="generateMusic"/>
     <!-- 音频列表 -->
@@ -15,6 +15,11 @@ defineOptions({ name: 'Index' })
 
 const listRef = ref<Nullable<{generateMusic: (...args) => void}>>(null)
 
+/*
+ *@Description: 拿到左侧配置信息调用右侧音乐生成的方法
+ *@MethodAuthor: xiaohong
+ *@Date: 2024-07-19 11:13:38
+*/
 function generateMusic (args: {formData: Recordable}) {
  unref(listRef)?.generateMusic(args.formData)
 }

+ 28 - 26
src/views/ai/music/components/list/audioBar/index.vue

@@ -4,8 +4,8 @@
     <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>{{currentSong.name}}</div>
+        <div class="text-[12px] text-gray-400">{{currentSong.singer}}</div>
       </div>
     </div>
       
@@ -21,7 +21,7 @@
       </div>
       <!-- 音频 -->
       <audio v-bind="audioProps" ref="audioRef" controls v-show="!audioProps" @timeupdate="audioTimeUpdate">
-        <source :src="response"/>
+        <source :src="audioUrl"/>
       </audio>
     </div>
 
@@ -35,34 +35,36 @@
 
 <script lang="ts" setup>
 import { formatPast } from '@/utils/formatTime'
-import response from '@/assets/audio/response.mp3'
+import audioUrl from '@/assets/audio/response.mp3'
 
 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,
-  })
+const currentSong = inject('currentSong', {})
 
-  function toggleStatus (type: string) {
-    audioProps[type] = !audioProps[type]
-    if (type === 'paused' && audioRef.value) {
-      if (audioProps[type]) {
-        audioRef.value.pause()
-      } else {
-        audioRef.value.play()
-      }
+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')
-  }
+// 更新播放位置
+function audioTimeUpdate (args) {
+  audioProps.currentTime = formatPast(new Date(args.timeStamp), 'mm:ss')
+}
 </script>

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

@@ -1,29 +1,29 @@
 <template>
-  <div class="flex flex-col h-[600px]">
+  <div class="flex flex-col">
     <div class="flex-auto flex overflow-hidden">
       <el-tabs v-model="currentType" class="flex-auto px-[var(--app-content-padding)]">
         <!-- 我的创作 -->
-        <el-tab-pane label="我的创作" v-loading="loading" name="mine">
+        <el-tab-pane v-loading="loading" label="我的创作" name="mine">
           <el-row v-if="mySongList.length" :gutter="12">
             <el-col v-for="song in mySongList" :key="song.id" :span="24">
-              <songCard v-bind="song"/>
+              <songCard :songInfo="song" @click="setCurrentSong(song)"/>
             </el-col>
           </el-row>
           <el-empty v-else description="暂无音乐"/>
         </el-tab-pane>
 
         <!-- 试听广场 -->
-        <el-tab-pane label="试听广场" v-loading="loading" name="square">
+        <el-tab-pane v-loading="loading" label="试听广场" name="square">
           <el-row v-if="squareSongList.length" v-loading="loading" :gutter="12">
             <el-col v-for="song in squareSongList" :key="song.id" :span="24">
-              <songCard v-bind="song"/>
+              <songCard :songInfo="song" @click="setCurrentSong(song)"/>
             </el-col>
           </el-row>
           <el-empty v-else description="暂无音乐"/>
         </el-tab-pane>
       </el-tabs>
       <!-- songInfo -->
-      <songInfo v-bind="squareSongList[0]" class="flex-none"/>
+      <songInfo class="flex-none"/>
     </div>
     <audioBar class="flex-none"/>
   </div>
@@ -36,13 +36,18 @@ import audioBar from './audioBar/index.vue'
 
 defineOptions({ name: 'Index' })
 
+
 const currentType = ref('mine')
 // loading 状态
 const loading = ref(false)
+// 当前音乐
+const currentSong = ref({})
 
 const mySongList = ref<Recordable[]>([])
 const squareSongList = ref<Recordable[]>([])
 
+provide('currentSong', currentSong)
+
 /*
  *@Description: 调接口生成音乐列表
  *@MethodAuthor: xiaohong
@@ -57,7 +62,7 @@ function generateMusic (formData: Recordable) {
         id: index,
         audioUrl: '',
         videoUrl: '',
-        title: '我走后',
+        title: '我走后' + index,
         imageUrl: 'https://www.carsmp3.com/data/attachment/forum/201909/19/091020q5kgre20fidreqyt.jpg',
         desc: 'Metal, symphony, film soundtrack, grand, majesticMetal, dtrack, grand, majestic',
         date: '2024年04月30日 14:02:57',
@@ -76,6 +81,15 @@ function generateMusic (formData: Recordable) {
   }, 3000)
 }
 
+/*
+ *@Description: 设置当前播放的音乐
+ *@MethodAuthor: xiaohong
+ *@Date: 2024-07-19 11:22:33
+*/
+function setCurrentSong (music: Recordable) {
+  currentSong.value = music
+}
+
 defineExpose({
   generateMusic
 })
@@ -86,9 +100,9 @@ defineExpose({
 :deep(.el-tabs) {
   display: flex;
   flex-direction: column;
-  .el-tabs__content{
-  padding: 0 7px;
-  overflow: auto;
- }
+  .el-tabs__content {
+    padding: 0 7px;
+    overflow: auto;
+  }
 }
 </style>

+ 6 - 12
src/views/ai/music/components/list/songCard/index.vue

@@ -1,10 +1,10 @@
 <template>
   <div class="flex bg-[var(--el-bg-color-overlay)] p-12px mb-12px rounded-1">
-    <el-image :src="imageUrl" class="flex-none w-80px"/>
+    <el-image :src="songInfo.imageUrl" class="flex-none w-80px"/>
     <div class="ml-8px">
-      <div>{{ title }}</div>
+      <div>{{ songInfo.title }}</div>
       <div class="mt-8px text-12px text-[var(--el-text-color-secondary)] line-clamp-2">
-        {{ desc }}
+        {{ songInfo.desc }}
       </div>
     </div>
   </div>
@@ -15,15 +15,9 @@
 defineOptions({ name: 'Index' })
 
 defineProps({
-  imageUrl: {
-    type: String
-  },
-  title: {
-    type: String
-  },
-  desc: {
-    type: String
+  songInfo: {
+    type: Object,
+    default: () => ({})
   }
 })
-
 </script>

+ 11 - 22
src/views/ai/music/components/list/songInfo/index.vue

@@ -1,11 +1,15 @@
 <template>
   <ContentWrap class="w-300px mb-[0!important] line-height-24px">
-    <el-image :src="imageUrl"/>
-    <div class="">{{ title }}</div>
-    <div class="text-[var(--el-text-color-secondary)] text-12px line-clamp-1">{{ desc }}</div>
-    <div class="text-[var(--el-text-color-secondary)] text-12px">{{ date }}</div>
+    <el-image :src="currentSong.imageUrl"/>
+    <div class="">{{ currentSong.title }}</div>
+    <div class="text-[var(--el-text-color-secondary)] text-12px line-clamp-1">
+      {{ currentSong.desc }}
+    </div>
+    <div class="text-[var(--el-text-color-secondary)] text-12px">
+      {{ currentSong.date }}
+    </div>
     <el-button size="small" round class="my-6px">信息复用</el-button>
-    <div class="text-[var(--el-text-color-secondary)] text-12px" v-html="lyric"></div>
+    <div class="text-[var(--el-text-color-secondary)] text-12px" v-html="currentSong.lyric"></div>
   </ContentWrap>
 </template>
 
@@ -13,21 +17,6 @@
 
 defineOptions({ name: 'Index' })
 
-defineProps({
-  imageUrl: {
-    type: String
-  },
-  title: {
-    type: String
-  },
-  desc: {
-    type: String
-  },
-  date: {
-    type: String
-  },
-  lyric: {
-    type: String
-  }
-})
+const currentSong = inject('currentSong', {})
+
 </script>

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

@@ -36,6 +36,6 @@ const modeRef = ref<Nullable<{ formData: Recordable }>>(null)
  *@Date: 2024-06-27 16:40:16
 */
 function generateMusic () {
-  emits('generate-music', {formData: unref(modeRef)?.formData.value})
+  emits('generate-music', {formData: unref(modeRef)?.formData})
 }
 </script>