diff --git a/src/lib/services/annotation-service.ts b/src/lib/services/annotation-service.ts index 97f38f7..196c132 100644 --- a/src/lib/services/annotation-service.ts +++ b/src/lib/services/annotation-service.ts @@ -6,6 +6,8 @@ import type { CreateAnnotationInput, UpdateAnnotationInput } from "@/lib/validat import { createFeedbackFromAnnotation } from "@/lib/services/feedback-service"; import { extractThumbnail, isFFmpegAvailable } from "@/lib/services/video-service"; +const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH ?? ""; + const VIDEO_UPLOADS_DIR = process.env.VIDEO_UPLOADS_DIR || (process.env.NODE_ENV === "production" @@ -140,7 +142,7 @@ async function extractAnnotationFrameThumbnail( const created = await extractThumbnail(videoPath, thumbPath, timestampSeconds); if (created) { - const thumbUrl = `/api/uploads/revisions/${revisionId}/annotation_frames/${thumbFilename}`; + const thumbUrl = `${BASE_PATH}/api/uploads/revisions/${revisionId}/annotation_frames/${thumbFilename}`; await prisma.annotation.update({ where: { id: annotationId }, data: { frameThumbnailUrl: thumbUrl }, diff --git a/src/lib/services/upload-service.ts b/src/lib/services/upload-service.ts index 36cb200..4b3fd3a 100644 --- a/src/lib/services/upload-service.ts +++ b/src/lib/services/upload-service.ts @@ -11,6 +11,9 @@ import { transcodeToHLS, } from "@/lib/services/video-service"; +/** Base path prefix so stored URLs work when the app is mounted at a sub-path */ +const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH ?? ""; + /** Images stored alongside videos in the mounted volume, served via /api/uploads */ const UPLOADS_DIR = process.env.VIDEO_UPLOADS_DIR @@ -92,7 +95,7 @@ export async function processAndStoreImage( const ext = file.type === "image/tiff" ? "tiff" : "png"; const filename = `${imageType}_${timestamp}.${ext}`; const filePath = path.join(revisionDir, filename); - const url = `/api/uploads/revisions/${revisionId}/${filename}`; + const url = `${BASE_PATH}/api/uploads/revisions/${revisionId}/${filename}`; let originalUrl: string | undefined; @@ -102,7 +105,7 @@ export async function processAndStoreImage( const originalFilename = `${imageType}_${timestamp}_original.png`; const originalPath = path.join(revisionDir, originalFilename); await writeFile(originalPath, buffer); - originalUrl = `/api/uploads/revisions/${revisionId}/${originalFilename}`; + originalUrl = `${BASE_PATH}/api/uploads/revisions/${revisionId}/${originalFilename}`; // Flatten onto white background const flattened = await sharp(buffer) @@ -115,7 +118,7 @@ export async function processAndStoreImage( const originalFilename = `${imageType}_${timestamp}_original.tiff`; const originalPath = path.join(revisionDir, originalFilename); await writeFile(originalPath, buffer); - originalUrl = `/api/uploads/revisions/${revisionId}/${originalFilename}`; + originalUrl = `${BASE_PATH}/api/uploads/revisions/${revisionId}/${originalFilename}`; const converted = await sharp(buffer).png().toBuffer(); const pngFilename = `${imageType}_${timestamp}.png`; @@ -225,7 +228,7 @@ export async function processAndStoreVideo( const timestamp = Date.now(); const videoFilename = `${videoType}_${timestamp}.mp4`; const videoPath = path.join(revisionDir, videoFilename); - const videoUrl = `/api/uploads/revisions/${revisionId}/${videoFilename}`; + const videoUrl = `${BASE_PATH}/api/uploads/revisions/${revisionId}/${videoFilename}`; // Stream-write the file to disk const arrayBuffer = await file.arrayBuffer(); @@ -241,12 +244,12 @@ export async function processAndStoreVideo( const thumbTime = Math.min(1, metadata.duration * 0.1 || 1); const thumbCreated = await extractThumbnail(videoPath, thumbPath, thumbTime); const thumbnailUrl = thumbCreated - ? `/api/uploads/revisions/${revisionId}/${thumbFilename}` + ? `${BASE_PATH}/api/uploads/revisions/${revisionId}/${thumbFilename}` : null; // HLS output paths const hlsDir = path.join(revisionDir, `${videoType}_${timestamp}_hls`); - const hlsUrl = `/api/uploads/revisions/${revisionId}/${videoType}_${timestamp}_hls/index.m3u8`; + const hlsUrl = `${BASE_PATH}/api/uploads/revisions/${revisionId}/${videoType}_${timestamp}_hls/index.m3u8`; const uploaded: UploadedVideo = { url: videoUrl,