Browse Source

fix: video/audio save-load roundtrip (3 compounding bugs)

- Use API response imageId instead of locally generated ID in
  saveVideoAndGetRef/saveAudioAndGetRef (filename mismatch)
- Read result.video/result.audio instead of result.data in
  loadMediaById (response field mismatch)
- Add audio extensions and MIME types to load-generation route
  so audio files can be found and served

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 4 months ago
parent
commit
e9e9d56b4e
  1. 15
      src/app/api/load-generation/route.ts
  2. 14
      src/utils/mediaStorage.ts

15
src/app/api/load-generation/route.ts

@ -4,11 +4,14 @@ import * as path from "path";
import { logger } from "@/utils/logger";
// Supported file extensions
const SUPPORTED_EXTENSIONS = ['png', 'jpg', 'jpeg', 'webp', 'gif', 'mp4', 'webm', 'mov'];
const SUPPORTED_EXTENSIONS = ['png', 'jpg', 'jpeg', 'webp', 'gif', 'mp4', 'webm', 'mov', 'mp3', 'wav', 'ogg', 'flac', 'aac'];
// Video extensions
const VIDEO_EXTENSIONS = ['mp4', 'webm', 'mov'];
// Audio extensions
const AUDIO_EXTENSIONS = ['mp3', 'wav', 'ogg', 'flac', 'aac'];
// Extension to MIME type mapping
const EXT_TO_MIME: Record<string, string> = {
png: 'image/png',
@ -19,6 +22,11 @@ const EXT_TO_MIME: Record<string, string> = {
mp4: 'video/mp4',
webm: 'video/webm',
mov: 'video/quicktime',
mp3: 'audio/mpeg',
wav: 'audio/wav',
ogg: 'audio/ogg',
flac: 'audio/flac',
aac: 'audio/aac',
};
// POST: Load a generated image or video from the generations folder by ID
@ -108,7 +116,8 @@ export async function POST(request: NextRequest) {
// Determine content type
const isVideo = VIDEO_EXTENSIONS.includes(foundExtension);
const contentType = isVideo ? 'video' : 'image';
const isAudio = AUDIO_EXTENSIONS.includes(foundExtension);
const contentType = isVideo ? 'video' : isAudio ? 'audio' : 'image';
logger.info('file.load', 'Generation loaded successfully', {
filePath,
@ -125,6 +134,8 @@ export async function POST(request: NextRequest) {
if (isVideo) {
response.video = dataUrl;
} else if (isAudio) {
response.audio = dataUrl;
} else {
response.image = dataUrl;
}

14
src/utils/mediaStorage.ts

@ -627,8 +627,9 @@ async function saveVideoAndGetRef(
throw new Error(`Failed to save video: ${result.error}`);
}
savedMediaIds.set(hash, videoId);
return videoId;
const actualId = result.imageId || videoId;
savedMediaIds.set(hash, actualId);
return actualId;
})();
if (!existingId) {
@ -693,8 +694,9 @@ async function saveAudioAndGetRef(
throw new Error(`Failed to save audio: ${result.error}`);
}
savedMediaIds.set(hash, audioId);
return audioId;
const actualId = result.imageId || audioId;
savedMediaIds.set(hash, actualId);
return actualId;
})();
if (!existingId) {
@ -1054,7 +1056,9 @@ async function loadMediaById(
return ""; // Return empty string to avoid breaking the workflow
}
const mediaData = mediaType === "image" ? result.image : result.data;
const mediaData = mediaType === "image" ? result.image
: mediaType === "video" ? result.video
: result.audio;
loadedMedia.set(mediaId, mediaData);
return mediaData;
}

Loading…
Cancel
Save