bill 1 anno fa
parent
commit
78af9420bb
4 ha cambiato i file con 988 aggiunte e 1243 eliminazioni
  1. 1 1
      package.json
  2. 821 1101
      pnpm-lock.yaml
  3. 1 1
      src/views/guide/sign.vue
  4. 165 140
      src/views/record/shot.vue

+ 1 - 1
package.json

@@ -9,7 +9,7 @@
     "preview": "vite preview"
   },
   "dependencies": {
-    "@simaq/core": "1.1.8",
+    "simaqcore": "1.2.0",
     "@vueup/vue-quill": "^1.2.0",
     "ant-design-vue": "^3.3.0-beta.3",
     "axios": "^0.27.2",

File diff suppressed because it is too large
+ 821 - 1101
pnpm-lock.yaml


+ 1 - 1
src/views/guide/sign.vue

@@ -76,7 +76,7 @@ import { diffArrayChange, getFileUrl, saveAs } from "@/utils";
 import { getResource } from "@/env";
 import { computed, watchEffect, nextTick, ref } from "vue";
 import { playSceneGuide, isScenePlayIng, pauseSceneGuide, ScenePlayIngEnum } from "@/sdk";
-import { VideoRecorder } from "@simaq/core";
+import { VideoRecorder } from "simaqcore";
 
 const props = withDefaults(defineProps<{ guide: Guide; edit?: boolean }>(), {
   edit: true,

+ 165 - 140
src/views/record/shot.vue

@@ -7,29 +7,42 @@
 
     <ui-editor-toolbar :toolbar="custom.showBottomBar" class="shot-ctrl">
       <ui-button type="submit" class="btn" @click="close">取消</ui-button>
-      <ui-button type="primary" class="btn" @click="complete" :class="{disabled: blobs.length === 0}">合并视频</ui-button>
-      <div class="other" :style="{bottom: barHeight}">
-        <ui-icon class="icon" type="video1" ctrl @click="start" tip="继续录制" tipV="top" />
+      <ui-button
+        type="primary"
+        class="btn"
+        @click="complete"
+        :class="{ disabled: blobs.length === 0 }"
+        >合并视频</ui-button
+      >
+      <div class="other" :style="{ bottom: barHeight }">
+        <ui-icon
+          class="icon"
+          type="video1"
+          ctrl
+          @click="start"
+          tip="继续录制"
+          tipV="top"
+        />
       </div>
       <div class="video-list" v-if="videoList.length">
-        <div class="layout" :style="{width: `${videoList.length * 130}px`}">
+        <div class="layout" :style="{ width: `${videoList.length * 130}px` }">
           <div v-for="video in videoList" :key="video.cover" class="cover">
-            <img :src="video.cover">
-            <ui-icon 
-              type="preview" 
-              ctrl 
-              class="preview" 
-              @click="palyUrl = video.origin"  
+            <img :src="video.cover" />
+            <ui-icon
+              type="preview"
+              ctrl
+              class="preview"
+              @click="palyUrl = video.origin"
             />
           </div>
         </div>
       </div>
     </ui-editor-toolbar>
 
-    <Preview 
-      v-if="palyUrl" 
+    <Preview
+      v-if="palyUrl"
       :items="[{ type: MediaType.video, url: palyUrl }]"
-      @close="palyUrl = null" 
+      @close="palyUrl = null"
     />
 
     <ShotImiate v-if="!custom.showBottomBar && !countdown" />
@@ -37,78 +50,86 @@
 </template>
 
 <script lang="ts">
-import { ref, defineComponent, onUnmounted, watch, shallowReactive, PropType, computed, watchEffect } from 'vue'
-import { VideoRecorder } from '@simaq/core';
-import { sdk } from '@/sdk'
-import { getVideoCover, togetherCallback } from '@/utils'
-import { MediaType, Preview } from '@/components/static-preview/index.vue'
-import { Record, getRecordFragmentBlobs } from '@/store'
-import ShotImiate from './shot-imitate.vue'
-import { 
-  getResource, 
-  showRightCtrlPanoStack, 
-  showRightPanoStack, 
-  showBottomBarStack, 
-  custom, 
+import {
+  ref,
+  defineComponent,
+  onUnmounted,
+  watch,
+  shallowReactive,
+  PropType,
+  computed,
+  watchEffect,
+} from "vue";
+import { VideoRecorder } from "simaqcore";
+import { sdk } from "@/sdk";
+import { getVideoCover, togetherCallback } from "@/utils";
+import { MediaType, Preview } from "@/components/static-preview/index.vue";
+import { Record, getRecordFragmentBlobs } from "@/store";
+import ShotImiate from "./shot-imitate.vue";
+import {
+  getResource,
+  showRightCtrlPanoStack,
+  showRightPanoStack,
+  showBottomBarStack,
+  custom,
   bottomBarHeightStack,
   showHeadBarStack,
-  showLeftPanoStack
-} from '@/env'
-import { appEl } from '@/store';
-import { useViewStack } from '@/hook';
-import { currentModel } from '@/model';
-import { Message } from 'bill/expose-common';
-
+  showLeftPanoStack,
+} from "@/env";
+import { appEl } from "@/store";
+import { useViewStack } from "@/hook";
+import { currentModel } from "@/model";
+import { Message } from "bill/expose-common";
 
 export default defineComponent({
   props: {
     record: {
       type: Object as PropType<Record>,
-      required: true
-    }
+      required: true,
+    },
   },
   emits: {
-    'append': (blobs: Blob[]) => true,
-    'updateCover': (cover: string) => true,
-    'close': () => true,
-    'preview': () => true,
-    'deleteRecord': () => true
+    append: (blobs: Blob[]) => true,
+    updateCover: (cover: string) => true,
+    close: () => true,
+    preview: () => true,
+    deleteRecord: () => true,
   },
   setup(props, { emit }) {
     const config: any = {
-      uploadUrl: '',
-      resolution: '4k',
+      uploadUrl: "",
+      resolution: "4k",
       debug: false,
-    }
-  
+    };
+
     const videoRecorder = new VideoRecorder(config);
-    const showLeftPano = ref(false)
-    const showBottomBar = ref(false)
-    const MAX_SIZE = 2 * 1024 * 1024 * 1024
-    const MAX_TIME = 30 * 60 * 1000
+    const showLeftPano = ref(false);
+    const showBottomBar = ref(false);
+    const MAX_SIZE = 2 * 1024 * 1024 * 1024;
+    const MAX_TIME = 30 * 60 * 1000;
 
-    type VideoItem = { origin: Blob | string, cover: string }
+    type VideoItem = { origin: Blob | string; cover: string };
 
-    const countdown = ref(0)
-    let interval: NodeJS.Timer
-    let recordIng = ref(false)
+    const countdown = ref(0);
+    let interval: NodeJS.Timer;
+    let recordIng = ref(false);
     const start = () => {
       if (size.value > MAX_SIZE || pauseTime.value < 2000) {
-        return Message.warning('已超出限制大小无法继续录制,可保存后继续录制!')
+        return Message.warning("已超出限制大小无法继续录制,可保存后继续录制!");
       }
 
-      showBottomBar.value = false
-      countdown.value = 2
+      showBottomBar.value = false;
+      countdown.value = 2;
       const timeiffe = () => {
         if (--countdown.value <= 0) {
-          clearInterval(interval)
-          videoRecorder.startRecord()
-          recordIng.value = true
+          clearInterval(interval);
+          videoRecorder.startRecord();
+          recordIng.value = true;
         } else {
-          interval = setTimeout(timeiffe, 300)
+          interval = setTimeout(timeiffe, 300);
         }
-      }
-      timeiffe()
+      };
+      timeiffe();
       // interval = setInterval(() => {
       //   if (--countdown.value === 0) {
       //     clearInterval(interval)
@@ -116,98 +137,104 @@ export default defineComponent({
       //     recordIng = true
       //   }
       // }, 1000)
-    }
+    };
 
     const pause = () => {
       if (countdown.value === 0 && recordIng.value) {
-        videoRecorder.endRecord()
-        recordIng.value = false
+        videoRecorder.endRecord();
+        recordIng.value = false;
       }
-      countdown.value = 0
-      showBottomBar.value = true
-      clearInterval(interval)
-    }
+      countdown.value = 0;
+      showBottomBar.value = true;
+      clearInterval(interval);
+    };
 
     watch(recordIng, (_n, _o, onCleanup) => {
       if (recordIng.value) {
-        const timeout = setTimeout(() => videoRecorder.endRecord(), pauseTime.value)
-        onCleanup(() => clearTimeout(timeout))
+        const timeout = setTimeout(() => videoRecorder.endRecord(), pauseTime.value);
+        onCleanup(() => clearTimeout(timeout));
       }
-    })
+    });
 
-    const blobs: File[] = shallowReactive([])
+    const blobs: File[] = shallowReactive([]);
     const size = computed(() => {
-      console.log(videoList)
-      return videoList.reduce((t, f) => typeof f.origin === 'string' ? t : t + f.origin.size, 0)
-    })
-    const pauseTime = computed(() => (MAX_TIME / MAX_SIZE) * (MAX_SIZE - size.value))
-    videoRecorder.off('*')
-    videoRecorder.on('record', blob => {
+      console.log(videoList);
+      return videoList.reduce(
+        (t, f) => (typeof f.origin === "string" ? t : t + f.origin.size),
+        0
+      );
+    });
+    const pauseTime = computed(() => (MAX_TIME / MAX_SIZE) * (MAX_SIZE - size.value));
+    videoRecorder.off("*");
+    videoRecorder.on("record", (blob) => {
       if (recordIng.value) {
-        blobs.push(new File([blob], '录屏.mp4', { type: 'video/mp4; codecs=h264' }))
+        blobs.push(new File([blob], "录屏.mp4", { type: "video/mp4; codecs=h264" }));
       }
-    })
-    videoRecorder.on('cancelRecord', pause)
-    videoRecorder.on('endRecord', pause)
-
-    const palyUrl = ref<string | Blob | null>(null)
-    const videoList: VideoItem[] = shallowReactive([])
-    let initial = false
-    watch([blobs, props], async () => {
-      const existsVideos = []
-
-      if (props.record.url) {
-        existsVideos.push(getResource(props.record.url))
-      }
-      const fragmentBlobs = getRecordFragmentBlobs(props.record)
-      existsVideos.push(...fragmentBlobs, ...blobs)
-      for (const blob of existsVideos) {
-        if (videoList.some(item => item.origin === blob)) {
-          continue
+    });
+    videoRecorder.on("cancelRecord", pause);
+    videoRecorder.on("endRecord", pause);
+
+    const palyUrl = ref<string | Blob | null>(null);
+    const videoList: VideoItem[] = shallowReactive([]);
+    let initial = false;
+    watch(
+      [blobs, props],
+      async () => {
+        const existsVideos = [];
+
+        if (props.record.url) {
+          existsVideos.push(getResource(props.record.url));
         }
-        const cover = await getVideoCover(blob, 3, 120, 80)
-        videoList.push({ origin: blob, cover })
-      }
-      for (let i = 0; i < videoList.length; i++) {
-        if (!existsVideos.some(blob => videoList[i].origin === blob)) {
-          videoList.splice(i--, 1)
+        const fragmentBlobs = getRecordFragmentBlobs(props.record);
+        existsVideos.push(...fragmentBlobs, ...blobs);
+        for (const blob of existsVideos) {
+          if (videoList.some((item) => item.origin === blob)) {
+            continue;
+          }
+          const cover = await getVideoCover(blob, 3, 120, 80);
+          videoList.push({ origin: blob, cover });
         }
-      }
-      if (!props.record.cover && videoList.length) {
-        emit('updateCover', videoList[0].cover)
-      }
-      if (!initial) {
-        initial = true
-        start()
-      }
-      
-    }, { immediate: true })
+        for (let i = 0; i < videoList.length; i++) {
+          if (!existsVideos.some((blob) => videoList[i].origin === blob)) {
+            videoList.splice(i--, 1);
+          }
+        }
+        if (!props.record.cover && videoList.length) {
+          emit("updateCover", videoList[0].cover);
+        }
+        if (!initial) {
+          initial = true;
+          start();
+        }
+      },
+      { immediate: true }
+    );
 
-    const upHandler = (ev: KeyboardEvent) => ev.code === `Escape` && videoRecorder.endRecord()
-    document.body.addEventListener('keyup', upHandler, { capture: true })
+    const upHandler = (ev: KeyboardEvent) =>
+      ev.code === `Escape` && videoRecorder.endRecord();
+    document.body.addEventListener("keyup", upHandler, { capture: true });
 
     const complete = () => {
-      emit('append', blobs)
-      close()
-    }
+      emit("append", blobs);
+      close();
+    };
 
     const close = () => {
-      pause()
-      emit('close')
-    }
+      pause();
+      emit("close");
+    };
 
-    const barHeight = computed(() => videoList.length ? '180px' : '60px')
-    
-    onUnmounted(() => {
-      document.body.removeEventListener('keyup', upHandler, { capture: true })
-    })
+    const barHeight = computed(() => (videoList.length ? "180px" : "60px"));
 
+    onUnmounted(() => {
+      document.body.removeEventListener("keyup", upHandler, { capture: true });
+    });
 
     watch(currentModel, () => {
       if (currentModel.value) {
-        showLeftPano.value = false
+        showLeftPano.value = false;
       }
-    })
+    });
     useViewStack(() => {
       return togetherCallback([
         showHeadBarStack.push(ref(false)),
@@ -218,10 +245,10 @@ export default defineComponent({
         showLeftPanoStack.push(showLeftPano),
         close,
         () => {
-          console.log('pop', showBottomBarStack.current)
-        }
-      ])
-    })
+          console.log("pop", showBottomBarStack.current);
+        },
+      ]);
+    });
 
     return {
       MediaType,
@@ -236,16 +263,14 @@ export default defineComponent({
       custom,
       videoList,
       palyUrl,
-      appEl
-    }
+      appEl,
+    };
   },
   components: {
     Preview,
-    ShotImiate
-  }
-})
-
+    ShotImiate,
+  },
+});
 </script>
 
-<style lang="scss" src="./style.scss" scoped>
-</style>
+<style lang="scss" src="./style.scss" scoped></style>