feat: enforce 100% frame-based positioning (no time)
Core Principle: Frame is the ONLY standard Changes: - VideoPlayer: Remove startTime/endTime props - VideoPlayer: Add mandatory startFrame/endFrame check - VideoPlayer: UI shows F123 (51.2s) format - All Views: Only set startFrame/endFrame - All Views: Only pass :start-frame/:end-frame - Remove all startTime/endTime from currentVideo refs Time is only used for display (auxiliary). Frame is the source of truth for all positioning.
This commit is contained in:
@@ -274,7 +274,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<VideoPlayer v-if="playing" :file-uuid="currentVideo.fileUuid" :start-time="currentVideo.startTime" :end-time="currentVideo.endTime" :all-traces="clusterVideoTraces" :merged-segments="clusterVideoSegments" :title="currentVideo.title" @close="playing = false; clusterVideoTraces = []; clusterVideoSegments = []" />
|
||||
<VideoPlayer v-if="playing" :file-uuid="currentVideo.fileUuid" :start-frame="currentVideo.startFrame" :end-frame="currentVideo.endFrame" :all-traces="clusterVideoTraces" :merged-segments="clusterVideoSegments" :title="currentVideo.title" @close="playing = false; clusterVideoTraces = []; clusterVideoSegments = []" />
|
||||
|
||||
<!-- Merge Target Selection Modal -->
|
||||
<div v-if="showMergeTargetModal" class="ms-modal-overlay show" @click.self="showMergeTargetModal = false">
|
||||
@@ -488,7 +488,7 @@ const loading = computed(() => refreshing.value)
|
||||
const faces = ref<any[]>([])
|
||||
const traces = ref<any[]>([])
|
||||
const playing = ref(false)
|
||||
const currentVideo = ref({ fileUuid: '', startTime: 0, endTime: 0, title: '' })
|
||||
const currentVideo = ref({ fileUuid: '', startFrame: 0, endFrame: 0, title: '' })
|
||||
const candidateThumbs = faceThumbsCache
|
||||
const activeFrameCard = ref('')
|
||||
const activeFrameMode = ref('')
|
||||
@@ -1118,7 +1118,12 @@ async function assignClusterTrace(trace: any) {
|
||||
}
|
||||
|
||||
function playTrace(t: any) {
|
||||
currentVideo.value = { fileUuid: t.file_uuid, startTime: t.first_sec, endTime: t.last_sec, title: `Trace F${t.trace_id} - ${formatTime(t.first_sec)}-${formatTime(t.last_sec)}` }
|
||||
currentVideo.value = {
|
||||
fileUuid: t.file_uuid,
|
||||
startFrame: t.first_frame || 0,
|
||||
endFrame: t.last_frame || (t.first_frame || 0) + 30,
|
||||
title: `F${t.first_frame || 0}-F${t.last_frame || 0} (Trace ${t.trace_id})`
|
||||
}
|
||||
playing.value = true
|
||||
}
|
||||
|
||||
@@ -1354,21 +1359,20 @@ async function playFaceDetailVideo() {
|
||||
const frameTime = frame / fps
|
||||
const startTime = Math.max(0, frameTime - 5)
|
||||
const endTime = frameTime + 5
|
||||
currentVideo.value = {
|
||||
currentVideo.value = {
|
||||
fileUuid: c.file_uuid,
|
||||
startTime,
|
||||
endTime,
|
||||
title: `Face #${frame} (${Math.round(frameTime)}s)`
|
||||
startFrame: startTime * fps,
|
||||
endFrame: endTime * fps,
|
||||
title: `F${Math.round(startTime * fps)}-F${Math.round(endTime * fps)} (${c.name})`
|
||||
}
|
||||
playing.value = true
|
||||
} catch (e) {
|
||||
console.error('Failed to get file info:', e)
|
||||
const frameTime = frame / 30
|
||||
currentVideo.value = {
|
||||
fileUuid: c.file_uuid,
|
||||
startTime: Math.max(0, frameTime - 5),
|
||||
endTime: frameTime + 5,
|
||||
title: `Face #${frame}`
|
||||
startFrame: Math.round(Math.max(0, frameTime - 5) * 30),
|
||||
endFrame: Math.round((frameTime + 5) * 30),
|
||||
title: `F${Math.round(Math.max(0, frameTime - 5) * 30)}-F${Math.round((frameTime + 5) * 30)}`
|
||||
}
|
||||
playing.value = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user