File size: 3,089 Bytes
f56a29b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | import type { Action, SpeechAction } from '@/lib/types/action';
import type { ManifestAction } from './classroom-zip-types';
import { db } from '@/lib/utils/database';
import type { AudioFileRecord, MediaFileRecord } from '@/lib/utils/database';
import type { Scene } from '@/lib/types/stage';
// βββ Export: Collect Media βββββββββββββββββββββββββββββββββββββ
export interface CollectedAudio {
zipPath: string;
record: AudioFileRecord;
}
export interface CollectedMedia {
zipPath: string;
record: MediaFileRecord;
elementId: string;
}
export async function collectAudioFiles(scenes: Scene[]): Promise<CollectedAudio[]> {
const audioIds = new Set<string>();
for (const scene of scenes) {
for (const action of scene.actions ?? []) {
if (action.type === 'speech' && (action as SpeechAction).audioId) {
audioIds.add((action as SpeechAction).audioId!);
}
}
}
const collected: CollectedAudio[] = [];
for (const audioId of audioIds) {
const record = await db.audioFiles.get(audioId);
if (record) {
const ext = record.format || 'mp3';
collected.push({ zipPath: `audio/${audioId}.${ext}`, record });
}
}
return collected;
}
export async function collectMediaFiles(stageId: string): Promise<CollectedMedia[]> {
const records = await db.mediaFiles.where('stageId').equals(stageId).toArray();
const collected: CollectedMedia[] = [];
for (const record of records) {
const elementId = record.id.includes(':') ? record.id.split(':').slice(1).join(':') : record.id;
const ext = record.mimeType?.split('/')[1] || 'jpg';
collected.push({ zipPath: `media/${elementId}.${ext}`, record, elementId });
}
return collected;
}
// βββ Export: Action Serialization ββββββββββββββββββββββββββββββ
export function actionsToManifest(
actions: Action[],
audioIdToPath: Map<string, string>,
): ManifestAction[] {
return actions.map((action) => {
if (action.type === 'speech') {
const speech = action as SpeechAction;
const { audioId, ...rest } = speech;
const audioRef = audioId ? audioIdToPath.get(audioId) : undefined;
return {
...rest,
...(audioRef ? { audioRef } : {}),
...(speech.audioUrl ? { audioUrl: speech.audioUrl } : {}),
} as ManifestAction;
}
return action as ManifestAction;
});
}
// βββ Import: Reference Rewriting βββββββββββββββββββββββββββββββ
export function rewriteAudioRefsToIds(
actions: ManifestAction[],
audioRefMap: Record<string, string>,
): Action[] {
return actions.map((action) => {
if (action.type === 'speech' && 'audioRef' in action) {
const { audioRef, ...rest } = action;
const audioId = audioRef ? audioRefMap[audioRef] : undefined;
return {
...rest,
...(audioId ? { audioId } : {}),
} as Action;
}
return action as Action;
});
}
|