feat: add video playback progress reporting

This commit is contained in:
Codex
2026-06-29 20:38:12 +08:00
parent 38db867d58
commit f6710ace8b
9 changed files with 223 additions and 3 deletions

View File

@@ -295,6 +295,8 @@ export interface MediaAnalyticsSummary {
svipPlays?: number;
quotaPlays?: number;
consumedQuota?: number;
watchedSeconds?: number;
avgCompletionRate?: number;
uniqueUsers?: number;
watermarkEvents?: number;
};
@@ -338,6 +340,7 @@ export interface MediaVideoPlayEvent {
status?: string;
accessMode?: string;
consumedQuota?: number;
playback?: Record<string, unknown> | null;
signedUrlExpiresAt?: string | null;
ipAddress?: string | null;
userAgent?: string | null;

View File

@@ -26,6 +26,28 @@ export interface VideoPlayback {
access?: Record<string, unknown>;
}
export interface VideoProgressReport {
item?: {
id?: string;
videoId?: string;
questionId?: string | null;
status?: 'issued' | 'started' | 'completed' | 'expired' | 'revoked';
accessMode?: string;
consumedQuota?: number;
playback?: {
startedAt?: string;
completedAt?: string | null;
lastEventType?: 'start' | 'heartbeat' | 'complete';
lastProgressSeconds?: number;
durationSeconds?: number | null;
watchedSeconds?: number;
completionRate?: number | null;
updatedAt?: string;
};
updatedAt?: string;
};
}
export async function loadQuestionVideos(questionId: string) {
return apiRequest<{ videos?: QuestionVideoItem[]; total?: number }>('/api/questions/videos', {
query: { questionId },
@@ -38,3 +60,16 @@ export async function playVideo(input: { videoId: string; questionId?: string })
body: input,
});
}
export async function reportVideoProgress(input: {
playToken: string;
eventType: 'start' | 'heartbeat' | 'complete';
progressSeconds?: number;
watchedSeconds?: number;
durationSeconds?: number;
}) {
return apiRequest<VideoProgressReport>('/api/videos/progress', {
method: 'POST',
body: input,
});
}