feat: 在播放控制器中添加场景切换逻辑和时间同步处理,优化播放体验

This commit is contained in:
xudan 2025-10-09 18:07:43 +08:00
parent c5410bb3f5
commit b49d662e72
2 changed files with 31 additions and 3 deletions

View File

@ -13,6 +13,11 @@ type PlaybackMessage = {
data: any;
};
type PlaybackSceneData = {
json: string;
totalDuration: number;
};
// Hook's return type definition
export interface UsePlaybackWebSocketReturn {
// Connection status
@ -75,8 +80,9 @@ export function usePlaybackWebSocket(editorService: ShallowRef<EditorService | u
}
if (msg.type === 'SCENE') {
// For seamless scene switching, we only update the scene JSON.
// Time and playback state should continue uninterrupted.
sceneJson.value = msg.data;
latestRobotData.clear();
} else if (msg.type === 'AMR') {
(msg.data as RobotRealtimeInfo[]).forEach(robot => {
latestRobotData.set(robot.id, robot);
@ -119,6 +125,9 @@ export function usePlaybackWebSocket(editorService: ShallowRef<EditorService | u
};
const play = () => {
// 双重保险在播放前强制发送一次SEEK指令确保后端从正确的时间点开始。
// 这可以防止因后端状态不同步或时序问题导致的播放位置错乱。
sendCommand(`SEEK:${currentTime.value}`);
sendCommand('PLAY');
isPlaying.value = true;
};

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { LockState } from '@meta2d/core';
import { message } from 'ant-design-vue';
import type { Dayjs } from 'dayjs';
import dayjs, { type Dayjs } from 'dayjs';
import { isNil } from 'lodash-es';
import { computed, onMounted, onUnmounted, provide, ref, type ShallowRef, shallowRef, watch } from 'vue';
import { useRoute } from 'vue-router';
@ -97,6 +97,25 @@ const handleDateChange = (date: Dayjs) => {
}
};
const handleSeek = (relativeTime: number) => {
if (selectedDate.value) {
const absoluteTimestamp = relativeTime + selectedDate.value.startOf('day').valueOf();
//
playback.currentTime.value = absoluteTimestamp;
playback.seek(absoluteTimestamp);
}
};
// UI
watch(playback.currentTime, (newTimestamp) => {
if (newTimestamp > 0 && selectedDate.value) {
const newDate = dayjs(newTimestamp);
if (!newDate.isSame(selectedDate.value, 'day')) {
selectedDate.value = newDate;
}
}
});
watch(playback.sceneJson, async (newJson) => {
if (newJson) {
await editor.value?.load(newJson);
@ -662,7 +681,7 @@ const handleGlobalKeydown = (event: KeyboardEvent) => {
:total-duration="playback.totalDuration.value"
@play="playback.play"
@pause="playback.pause"
@seek="(time) => playback.seek(time + (selectedDate?.startOf('day').valueOf() ?? 0))"
@seek="handleSeek"
/>
</template>
</template>