( videoId: string, userId: string, editSpec: VideoEditSpec, reportedMetadata: VideoEditRenderResult["metadata"], )
| 414 | } |
| 415 | |
| 416 | async function verifyRenderedEditOutput( |
| 417 | videoId: string, |
| 418 | userId: string, |
| 419 | editSpec: VideoEditSpec, |
| 420 | reportedMetadata: VideoEditRenderResult["metadata"], |
| 421 | ): Promise<void> { |
| 422 | "use step"; |
| 423 | |
| 424 | const expectedDuration = getEditSpecOutputDuration(editSpec); |
| 425 | if (!isDurationClose(reportedMetadata.duration, expectedDuration)) { |
| 426 | throw new Error( |
| 427 | `Media server reported edited duration ${reportedMetadata.duration.toFixed(3)}s, expected ${expectedDuration.toFixed(3)}s`, |
| 428 | ); |
| 429 | } |
| 430 | |
| 431 | const mediaServerUrl = serverEnv().MEDIA_SERVER_URL; |
| 432 | if (!mediaServerUrl) { |
| 433 | throw new FatalError("MEDIA_SERVER_URL is not configured"); |
| 434 | } |
| 435 | |
| 436 | const [video] = await db() |
| 437 | .select() |
| 438 | .from(videos) |
| 439 | .where(eq(videos.id, Video.VideoId.make(videoId))); |
| 440 | |
| 441 | if (!video) { |
| 442 | throw new FatalError("Video does not exist"); |
| 443 | } |
| 444 | |
| 445 | const [bucket] = await Storage.getAccessForVideo( |
| 446 | decodeStorageVideo(video), |
| 447 | ).pipe(runPromise); |
| 448 | const outputKey = `${userId}/${videoId}/result.mp4`; |
| 449 | const outputUrl = await bucket |
| 450 | .getInternalSignedObjectUrl(outputKey, { |
| 451 | expiresIn: MEDIA_SERVER_PRESIGNED_GET_EXPIRES_SECONDS, |
| 452 | }) |
| 453 | .pipe(runPromise); |
| 454 | |
| 455 | let lastError: Error | undefined; |
| 456 | |
| 457 | for ( |
| 458 | let attempt = 0; |
| 459 | attempt < MEDIA_SERVER_OUTPUT_VERIFICATION_MAX_ATTEMPTS; |
| 460 | attempt++ |
| 461 | ) { |
| 462 | try { |
| 463 | const actualMetadata = await probeVideoOnMediaServer( |
| 464 | mediaServerUrl, |
| 465 | outputUrl, |
| 466 | serverEnv().MEDIA_SERVER_WEBHOOK_SECRET || undefined, |
| 467 | ); |
| 468 | if (isDurationClose(actualMetadata.duration, expectedDuration)) { |
| 469 | return; |
| 470 | } |
| 471 | |
| 472 | lastError = new Error( |
| 473 | `Rendered video duration mismatch: expected ${expectedDuration.toFixed(3)}s, got ${actualMetadata.duration.toFixed(3)}s`, |
no test coverage detected