Skip to content

Commit a0d1c18

Browse files
chatman-mediaclaude
andcommitted
fix(ai-director): исправлено отображение анализаторов в истории
Проблема: при загрузке завершенных анализов из storage показывалось "Всего анализаторов: 0" и "Завершено: 0", хотя анализ был выполнен полностью. Решение: - Добавлена функция extractAnalyzersFromResult() для извлечения списка выполненных анализаторов из ComprehensiveAnalysisResult - Добавлена функция createFileProgressFromResult() для создания FileAnalysisProgress с правильно заполненной статистикой - Обновлен use-timeline-analysis.ts для использования маппера при загрузке сохраненных анализов Функция анализирует все поля результата: - audio_analysis → audio_quality, speech_recognition - scene_analysis → scene_detection (с количеством сцен) - vision_analysis → object_detection, face_detection (с количеством) - vision_language_model_analysis → vlm_analysis - moment_analysis → moment_detection (с ключевыми моментами) - content_analysis → content_classification, mood_analysis, quality_assessment Теперь корректно отображается: ✅ Всего анализаторов: N ✅ Завершено: N ✅ Детали по каждому анализатору 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 751b984 commit a0d1c18

File tree

3 files changed

+169
-20
lines changed

3 files changed

+169
-20
lines changed

src/features/ai-director/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ export {
6262
ANALYZER_METADATA,
6363
calculateBatchProgress,
6464
calculateFileProgress,
65+
createFileProgressFromResult,
6566
createInitialFileProgress,
67+
extractAnalyzersFromResult,
6668
getAnalyzerMetadata,
6769
getAnalyzersByCategory,
6870
updateAnalyzerProgress,

src/features/ai-director/types/analysis-progress.ts

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,3 +553,167 @@ export function updateAnalyzerProgress(
553553
stats,
554554
}
555555
}
556+
557+
/**
558+
* Извлечь список анализаторов из ComprehensiveAnalysisResult
559+
* Определяет какие анализаторы были выполнены на основе заполненных полей
560+
*/
561+
export function extractAnalyzersFromResult(
562+
result: any, // ComprehensiveAnalysisResult from Rust
563+
): AnalyzerProgress[] {
564+
const analyzers: AnalyzerProgress[] = []
565+
566+
// Audio analyzers
567+
if (result.audio_analysis) {
568+
analyzers.push({
569+
type: "audio_quality",
570+
status: "completed",
571+
progress: 100,
572+
})
573+
574+
// Если есть транскрипция
575+
if (result.audio_analysis.transcription) {
576+
analyzers.push({
577+
type: "speech_recognition",
578+
status: "completed",
579+
progress: 100,
580+
})
581+
}
582+
}
583+
584+
// Scene detection
585+
if (result.scene_analysis && result.scene_analysis.scenes && result.scene_analysis.scenes.length > 0) {
586+
analyzers.push({
587+
type: "scene_detection",
588+
status: "completed",
589+
progress: 100,
590+
result: {
591+
type: "scene_detection",
592+
success: true,
593+
metadata: {
594+
itemsFound: result.scene_analysis.scenes.length,
595+
processingTime: 0,
596+
},
597+
},
598+
})
599+
}
600+
601+
// Vision analysis (objects, faces)
602+
if (result.vision_analysis) {
603+
if (result.vision_analysis.objects_detected && result.vision_analysis.objects_detected.length > 0) {
604+
analyzers.push({
605+
type: "object_detection",
606+
status: "completed",
607+
progress: 100,
608+
result: {
609+
type: "object_detection",
610+
success: true,
611+
metadata: {
612+
itemsFound: result.vision_analysis.objects_detected.length,
613+
processingTime: 0,
614+
},
615+
},
616+
})
617+
}
618+
619+
if (result.vision_analysis.faces_count > 0) {
620+
analyzers.push({
621+
type: "face_detection",
622+
status: "completed",
623+
progress: 100,
624+
result: {
625+
type: "face_detection",
626+
success: true,
627+
metadata: {
628+
itemsFound: result.vision_analysis.faces_count,
629+
processingTime: 0,
630+
},
631+
},
632+
})
633+
}
634+
}
635+
636+
// Vision Language Model analysis
637+
if (result.vision_language_model_analysis) {
638+
analyzers.push({
639+
type: "vlm_analysis",
640+
status: "completed",
641+
progress: 100,
642+
})
643+
}
644+
645+
// Moment detection
646+
if (result.moment_analysis && result.moment_analysis.key_moments && result.moment_analysis.key_moments.length > 0) {
647+
analyzers.push({
648+
type: "moment_detection",
649+
status: "completed",
650+
progress: 100,
651+
result: {
652+
type: "moment_detection",
653+
success: true,
654+
metadata: {
655+
itemsFound: result.moment_analysis.key_moments.length,
656+
processingTime: 0,
657+
},
658+
},
659+
})
660+
}
661+
662+
// Content analysis
663+
if (result.content_analysis) {
664+
analyzers.push({
665+
type: "content_classification",
666+
status: "completed",
667+
progress: 100,
668+
})
669+
670+
if (result.content_analysis.mood) {
671+
analyzers.push({
672+
type: "mood_analysis",
673+
status: "completed",
674+
progress: 100,
675+
})
676+
}
677+
678+
if (result.content_analysis.quality) {
679+
analyzers.push({
680+
type: "quality_assessment",
681+
status: "completed",
682+
progress: 100,
683+
})
684+
}
685+
}
686+
687+
return analyzers
688+
}
689+
690+
/**
691+
* Создать FileAnalysisProgress из ComprehensiveAnalysisResult
692+
* Используется при загрузке сохраненных анализов из storage
693+
*/
694+
export function createFileProgressFromResult(
695+
result: any, // ComprehensiveAnalysisResult from Rust
696+
filePath: string,
697+
): FileAnalysisProgress {
698+
const fileName = filePath.split("/").pop() || filePath.split("\\").pop() || filePath
699+
const analyzers = extractAnalyzersFromResult(result)
700+
701+
return {
702+
id: result.analysis_id,
703+
fileId: result.analysis_id,
704+
fileName,
705+
filePath,
706+
status: result.status === "Completed" ? "completed" : "error",
707+
progress: 100,
708+
analyzers,
709+
stats: {
710+
totalAnalyzers: analyzers.length,
711+
completedAnalyzers: analyzers.filter((a) => a.status === "completed").length,
712+
failedAnalyzers: analyzers.filter((a) => a.status === "error").length,
713+
skippedAnalyzers: analyzers.filter((a) => a.status === "skipped").length,
714+
},
715+
startTime: result.started_at,
716+
endTime: result.completed_at,
717+
duration: result.total_duration_ms,
718+
}
719+
}

src/features/timeline/hooks/state/use-timeline-analysis.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useCallback, useEffect, useMemo, useState } from "react"
1212

1313
import { analysisStorageService } from "@/domains/ai-services/services/analysis-storage-service"
1414
import { useMediaFiles } from "@/domains/project-management/hooks"
15+
import { createFileProgressFromResult } from "@/features/ai-director"
1516
import { useAIDirectorAnalysisV2 } from "@/features/ai-director/hooks/use-ai-director-analysis-v2"
1617
import type {
1718
AnalyzerType,
@@ -85,27 +86,9 @@ export function useTimelineAnalysis(): UseTimelineAnalysisReturn {
8586
const result = await analysisStorageService.loadComprehensiveAnalysis(videoPath)
8687

8788
if (result.success && result.data) {
88-
const fileName = videoPath.split("/").pop() || videoPath.split("\\").pop() || videoPath
89-
9089
// Создаем FileAnalysisProgress из сохраненного анализа
91-
const fileProgress: FileAnalysisProgress = {
92-
id: result.data.analysis_id,
93-
fileId: result.data.analysis_id,
94-
fileName,
95-
filePath: videoPath,
96-
status: "completed" as FileAnalysisStatus,
97-
progress: 100,
98-
analyzers: [],
99-
stats: {
100-
totalAnalyzers: 0,
101-
completedAnalyzers: 0,
102-
failedAnalyzers: 0,
103-
skippedAnalyzers: 0,
104-
},
105-
startTime: result.data.started_at,
106-
endTime: result.data.completed_at,
107-
}
108-
90+
// Используем маппер для извлечения анализаторов из результата
91+
const fileProgress = createFileProgressFromResult(result.data, videoPath)
10992
analyses.push(fileProgress)
11093
}
11194
}

0 commit comments

Comments
 (0)