|
@@ -3,12 +3,12 @@
|
|
|
<div class="info">
|
|
|
<div class="guide-cover">
|
|
|
<img :src="getResource(getFileUrl(guide.cover))" />
|
|
|
- <ui-icon
|
|
|
- type="preview"
|
|
|
- class="icon"
|
|
|
- ctrl
|
|
|
- @click="playSceneGuide(paths, undefined, true)"
|
|
|
- v-if="paths.length"
|
|
|
+ <ui-icon
|
|
|
+ type="preview"
|
|
|
+ class="icon"
|
|
|
+ ctrl
|
|
|
+ @click="playSceneGuide(paths, undefined, true)"
|
|
|
+ v-if="paths.length"
|
|
|
/>
|
|
|
</div>
|
|
|
<div>
|
|
@@ -16,42 +16,41 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="actions" v-if="edit">
|
|
|
- <ui-more
|
|
|
- :options="menus"
|
|
|
- style="margin-left: 20px"
|
|
|
- @click="(action: keyof typeof actions) => actions[action]()"
|
|
|
+ <ui-more
|
|
|
+ :options="menus"
|
|
|
+ style="margin-left: 20px"
|
|
|
+ @click="(action: keyof typeof actions) => actions[action]()"
|
|
|
/>
|
|
|
</div>
|
|
|
</ui-group-option>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { Guide, getGuidePaths } from '@/store'
|
|
|
-import { getFileUrl, saveAs } from '@/utils'
|
|
|
-import { getResource } from '@/env'
|
|
|
-import { computed, watchEffect, nextTick } from 'vue';
|
|
|
-import { playSceneGuide, isScenePlayIng, pauseSceneGuide } from '@/sdk'
|
|
|
-import { VideoRecorder } from '@simaq/core';
|
|
|
-
|
|
|
-const props = withDefaults(
|
|
|
- defineProps<{ guide: Guide, edit?: boolean }>(),
|
|
|
- { edit: true }
|
|
|
-)
|
|
|
-
|
|
|
-const emit = defineEmits<{
|
|
|
- (e: 'delete'): void
|
|
|
- (e: 'play'): void
|
|
|
- (e: 'edit'): void
|
|
|
-}>()
|
|
|
+import { Guide, getGuidePaths } from "@/store";
|
|
|
+import { getFileUrl, saveAs } from "@/utils";
|
|
|
+import { getResource } from "@/env";
|
|
|
+import { computed, watchEffect, nextTick } from "vue";
|
|
|
+import { playSceneGuide, isScenePlayIng, pauseSceneGuide } from "@/sdk";
|
|
|
+import { VideoRecorder } from "@simaq/core";
|
|
|
+
|
|
|
+const props = withDefaults(defineProps<{ guide: Guide; edit?: boolean }>(), {
|
|
|
+ edit: true,
|
|
|
+});
|
|
|
+
|
|
|
+const emit = defineEmits<{
|
|
|
+ (e: "delete"): void;
|
|
|
+ (e: "play"): void;
|
|
|
+ (e: "edit"): void;
|
|
|
+}>();
|
|
|
|
|
|
const menus = [
|
|
|
- { label: '编辑', value: 'edit' },
|
|
|
- { label: '下载', value: 'download' },
|
|
|
- { label: '删除', value: 'delete' },
|
|
|
-]
|
|
|
+ { label: "编辑", value: "edit" },
|
|
|
+ // { label: '下载', value: 'download' },
|
|
|
+ { label: "删除", value: "delete" },
|
|
|
+];
|
|
|
const actions = {
|
|
|
- edit: () => emit('edit'),
|
|
|
- delete: () => emit('delete'),
|
|
|
+ edit: () => emit("edit"),
|
|
|
+ delete: () => emit("delete"),
|
|
|
download: () => {
|
|
|
const config: any = {
|
|
|
// uploadUrl: '',
|
|
@@ -59,10 +58,10 @@ const actions = {
|
|
|
// autoDownload: false,
|
|
|
// systemAudio: true,
|
|
|
// debug: true,
|
|
|
- resolution: '4k',
|
|
|
+ resolution: "4k",
|
|
|
autoDownload: false,
|
|
|
- platform: 'canvas',
|
|
|
-
|
|
|
+ platform: "canvas",
|
|
|
+
|
|
|
config: {
|
|
|
frameRate: 60,
|
|
|
canvasId: ".scene-canvas > canvas",
|
|
@@ -70,37 +69,39 @@ const actions = {
|
|
|
disbaledAudio: false,
|
|
|
systemAudio: false,
|
|
|
debug: false,
|
|
|
- }
|
|
|
-
|
|
|
+ };
|
|
|
+
|
|
|
const videoRecorder = new VideoRecorder(config);
|
|
|
- videoRecorder.startRecord()
|
|
|
+ videoRecorder.startRecord();
|
|
|
|
|
|
- let stopWatch: () => void
|
|
|
+ let stopWatch: () => void;
|
|
|
const stopRecord = () => {
|
|
|
- stopWatch && stopWatch()
|
|
|
- pauseSceneGuide()
|
|
|
- }
|
|
|
-
|
|
|
- videoRecorder.on('record', blob => {
|
|
|
- saveAs(new File([blob], '录屏.mp4', { type: 'video/mp4; codecs=h264' }), props.guide.title + ".mp4")
|
|
|
- })
|
|
|
-
|
|
|
- videoRecorder.off('*')
|
|
|
- videoRecorder.on('startRecord', () => {
|
|
|
- playSceneGuide(paths.value, undefined, true)
|
|
|
+ stopWatch && stopWatch();
|
|
|
+ pauseSceneGuide();
|
|
|
+ };
|
|
|
+
|
|
|
+ videoRecorder.on("record", (blob) => {
|
|
|
+ saveAs(
|
|
|
+ new File([blob], "录屏.mp4", { type: "video/mp4; codecs=h264" }),
|
|
|
+ props.guide.title + ".mp4"
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ videoRecorder.off("*");
|
|
|
+ videoRecorder.on("startRecord", () => {
|
|
|
+ playSceneGuide(paths.value, undefined, true);
|
|
|
stopWatch = watchEffect(() => {
|
|
|
- if (!isScenePlayIng.value) {
|
|
|
- videoRecorder.endRecord()
|
|
|
- nextTick(stopWatch)
|
|
|
- }
|
|
|
- })
|
|
|
- })
|
|
|
- videoRecorder.on('cancelRecord', stopRecord)
|
|
|
- videoRecorder.on('endRecord', stopRecord)
|
|
|
- }
|
|
|
-}
|
|
|
-const paths = computed(() => getGuidePaths(props.guide))
|
|
|
-
|
|
|
+ if (!isScenePlayIng.value) {
|
|
|
+ videoRecorder.endRecord();
|
|
|
+ nextTick(stopWatch);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ videoRecorder.on("cancelRecord", stopRecord);
|
|
|
+ videoRecorder.on("endRecord", stopRecord);
|
|
|
+ },
|
|
|
+};
|
|
|
+const paths = computed(() => getGuidePaths(props.guide));
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -123,10 +124,10 @@ const paths = computed(() => getGuidePaths(props.guide))
|
|
|
.guide-cover {
|
|
|
position: relative;
|
|
|
&::after {
|
|
|
- content: '';
|
|
|
+ content: "";
|
|
|
position: absolute;
|
|
|
inset: 0;
|
|
|
- background: rgba(0,0,0,.2)
|
|
|
+ background: rgba(0, 0, 0, 0.2);
|
|
|
}
|
|
|
|
|
|
.icon {
|
|
@@ -144,7 +145,7 @@ const paths = computed(() => getGuidePaths(props.guide))
|
|
|
object-fit: cover;
|
|
|
border-radius: 4px;
|
|
|
overflow: hidden;
|
|
|
- background-color: rgba(255,255,255,.6);
|
|
|
+ background-color: rgba(255, 255, 255, 0.6);
|
|
|
display: block;
|
|
|
}
|
|
|
}
|
|
@@ -159,11 +160,9 @@ const paths = computed(() => getGuidePaths(props.guide))
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
.actions {
|
|
|
flex: none;
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-</style>
|
|
|
+</style>
|