1313 * IPC ai_video_analyze path; this function only serves PWA/browser File upload.
1414 * Includes Douyin link detection to guide "save to album then import" (plan A).
1515 */
16- import { supabase } from '@/lib/auth/supabaseClient' ;
17- import { requireGatewayUrl } from '@/lib/ai/config' ;
16+ import { aiClient } from '@/lib/http/apiClient' ;
1817import { classroomNoteStore } from '@/lib/storage/classroomNoteStore' ;
1918import type { AnalyzeResult } from '@/lib/ai/sessionAnalyzer' ;
2019
@@ -40,61 +39,39 @@ export async function analyzeVideoFile(
4039 file : File ,
4140 options ?: { duration ?: number ; language ?: string } ,
4241) : Promise < AnalyzeResult > {
43- const { data : { session } } = await supabase . auth . getSession ( ) ;
44- const token = session ?. access_token ;
45- const baseUrl = requireGatewayUrl ( ) ;
46-
4742 const formData = new FormData ( ) ;
4843 formData . append ( 'video_file' , file , file . name ) ;
4944 if ( options ?. duration !== undefined ) formData . append ( 'duration' , String ( options . duration ) ) ;
5045 if ( options ?. language ) formData . append ( 'language' , options . language ) ;
5146
52- const headers = new Headers ( ) ;
53- if ( token ) headers . set ( 'Authorization' , `Bearer ${ token } ` ) ;
54- headers . set ( 'X-Request-ID' , crypto . randomUUID ( ) ) ;
55- // 不显式设置 Content-Type:由浏览器为 FormData 自动生成 multipart boundary
47+ // 复用 aiClient.post:自动注入 Authorization + 401 刷新 + 429 配额提示(TD-006)
48+ const data = await aiClient . post < {
49+ content : string ;
50+ keyframes_analyzed : number ;
51+ model_used : string ;
52+ } > ( '/api/v1/multimodal/analyze-video' , formData , { timeout : 300000 } ) ;
5653
57- const controller = new AbortController ( ) ;
58- const timeoutId = setTimeout ( ( ) => controller . abort ( ) , 300000 ) ; // 与网关 300s 超时对齐
54+ const analyzeResult : AnalyzeResult = {
55+ content : data . content ,
56+ keyframesAnalyzed : data . keyframes_analyzed ,
57+ modelUsed : data . model_used ,
58+ source : 'remote' ,
59+ } ;
5960
61+ // 自动持久化(Dexie,PWA/Electron 通用)
6062 try {
61- const resp = await fetch ( `${ baseUrl } /api/v1/multimodal/analyze-video` , {
62- method : 'POST' ,
63- headers,
64- body : formData ,
65- signal : controller . signal ,
63+ await classroomNoteStore . create ( {
64+ sessionId : crypto . randomUUID ( ) ,
65+ title : `视频笔记 ${ new Date ( ) . toLocaleString ( 'zh-CN' ) } ` ,
66+ content : analyzeResult . content ,
67+ keyframesAnalyzed : analyzeResult . keyframesAnalyzed ,
68+ modelUsed : analyzeResult . modelUsed ,
69+ sourceType : 'video' ,
70+ duration : options ?. duration ?? 0 ,
6671 } ) ;
67- if ( ! resp . ok ) throw new Error ( `HTTP ${ resp . status } ` ) ;
68- const data = await resp . json ( ) as {
69- content : string ;
70- keyframes_analyzed : number ;
71- model_used : string ;
72- } ;
73-
74- const analyzeResult : AnalyzeResult = {
75- content : data . content ,
76- keyframesAnalyzed : data . keyframes_analyzed ,
77- modelUsed : data . model_used ,
78- source : 'remote' ,
79- } ;
80-
81- // 自动持久化(Dexie,PWA/Electron 通用)
82- try {
83- await classroomNoteStore . create ( {
84- sessionId : crypto . randomUUID ( ) ,
85- title : `视频笔记 ${ new Date ( ) . toLocaleString ( 'zh-CN' ) } ` ,
86- content : analyzeResult . content ,
87- keyframesAnalyzed : analyzeResult . keyframesAnalyzed ,
88- modelUsed : analyzeResult . modelUsed ,
89- sourceType : 'video' ,
90- duration : options ?. duration ?? 0 ,
91- } ) ;
92- } catch ( e ) {
93- console . warn ( '[uploadVideoAnalysis] 视频笔记持久化失败:' , e ) ;
94- }
95-
96- return analyzeResult ;
97- } finally {
98- clearTimeout ( timeoutId ) ;
72+ } catch ( e ) {
73+ console . warn ( '[uploadVideoAnalysis] 视频笔记持久化失败:' , e ) ;
9974 }
75+
76+ return analyzeResult ;
10077}
0 commit comments