Przeglądaj źródła

🎨 为视频页增加左右声道控制

快乐的梦鱼 2 tygodni temu
rodzic
commit
d6f491ae0f

BIN
src/assets/images/PlayList/Button0.png


BIN
src/assets/images/PlayList/Button3.png


+ 41 - 0
src/components/small/ActiveableButton.vue

@@ -0,0 +1,41 @@
+<template>
+  <div :class="'button ' + (active ? 'active' : '')" @click="emit('click')">
+    {{ text }}
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+
+const emit = defineEmits(['click']);
+defineProps({
+  active: {
+    type: Boolean,
+    default: false
+  },
+  text: {
+    type: String,
+    default: ''
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.button {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  user-select: none;
+  cursor: pointer;
+
+  min-width: 60px;
+  height: 40px;
+  background-size: 100% 100%;
+  background-image: url('@/assets/images/PlayList/Button3.png');
+
+  &.active {
+    background-image: url('@/assets/images/PlayList/Button0.png');
+  }
+}
+</style>

+ 53 - 1
src/views/PlayerView.vue

@@ -2,9 +2,11 @@
 import ProjectsContent from '@/api/inherit/ProjectsContent';
 import SimplePageContentLoader from '@/components/SimplePageContentLoader.vue';
 import SimpleRichHtml from '@/components/SimpleRichHtml.vue';
+import ActiveableButton from '@/components/small/ActiveableButton.vue';
 import Box1 from '@/components/small/Box1.vue';
 import { useSimpleDataLoader } from '@/composeable/SimpleDataLoader';
 import { ScrollRect } from '@imengyu/vue-scroll-rect';
+import { ref } from 'vue';
 import { useRouter, useRoute } from 'vue-router';
 
 const route = useRoute();
@@ -12,6 +14,42 @@ const router = useRouter();
 const data = useSimpleDataLoader(async () => 
   await ProjectsContent.getContentDetail(parseInt(route.query.id as string))
 );
+
+const video = ref<HTMLVideoElement>();
+const leftAudio = ref(true);
+let source: MediaElementAudioSourceNode;
+let leftGain: GainNode, rightGain: GainNode;
+
+function handleLoaded() {
+  if (source)
+    return;
+
+  const audioContext = new AudioContext();
+  source = audioContext.createMediaElementSource(video.value!);
+  const splitter = audioContext.createChannelSplitter(2); // 分离左右声道
+  leftGain = audioContext.createGain();
+  rightGain = audioContext.createGain();
+  const merger = audioContext.createChannelMerger(2); // 合并声道
+
+  // 连接节点
+  source.connect(splitter);
+  splitter.connect(leftGain, 0); // 左声道
+  splitter.connect(rightGain, 1); // 右声道
+  leftGain.connect(merger, 0, 0);
+  rightGain.connect(merger, 0, 1);
+  merger.connect(audioContext.destination);
+}
+function switchAudio(left: boolean) {
+  leftAudio.value = left;
+  if (left) {
+    leftGain.gain.value = 1;
+    rightGain.gain.value = 0;
+  } else {
+    leftGain.gain.value = 0;
+    rightGain.gain.value = 1;
+  }
+}
+
 </script>
 
 <template>
@@ -26,7 +64,17 @@ const data = useSimpleDataLoader(async () =>
       <div class="d-flex flex-row align-stretch flex-six margin-left-ll w-55 h-100">
         <SimplePageContentLoader :loader="data">
           <div class="d-flex flex-col align-stretch flex-six flex-shrink-1">
-            <video :src="data.content.value?.video" class="w-100 h-100" :controls="true" :autoplay="true" />
+            <video 
+              ref="video"
+              crossorigin="anonymous"
+              :src="data.content.value?.video"
+              class="w-100 h-100"
+              :controls="true"
+              :autoplay="true"  
+              webkit-playsinline 
+              playsinline
+              @play="handleLoaded"
+            />
           </div>
           <div class="d-flex flex-col align-stretch flex-four margin-left-base flex-shrink-1 w-30 gap-l">
             <Box1 class="desc h-50">
@@ -37,6 +85,10 @@ const data = useSimpleDataLoader(async () =>
                   img: 'max-width: 100%'
                 }" />
               </ScrollRect>
+              <div class="d-flex flex-row align-center gap-s">
+                <ActiveableButton text="原唱" :active="leftAudio" @click="switchAudio(true)" />
+                <ActiveableButton text="伴奏" :active="!leftAudio" @click="switchAudio(false)" />
+              </div>
             </Box1>
             
             <Box1 class="desc h-45">