( apiKey: string, model: string, prompt: string, duration: number, aspectRatio: string, resolution: string, cameraControl: any | undefined, requestId: string, logger: ReturnType<typeof createLogger> )
| 610 | } |
| 611 | |
| 612 | async function generateWithLuma( |
| 613 | apiKey: string, |
| 614 | model: string, |
| 615 | prompt: string, |
| 616 | duration: number, |
| 617 | aspectRatio: string, |
| 618 | resolution: string, |
| 619 | cameraControl: any | undefined, |
| 620 | requestId: string, |
| 621 | logger: ReturnType<typeof createLogger> |
| 622 | ): Promise<{ buffer: Buffer; width: number; height: number; jobId: string; duration: number }> { |
| 623 | logger.info(`[${requestId}] Starting Luma Dream Machine generation`) |
| 624 | |
| 625 | const dimensions = getVideoDimensions(aspectRatio, resolution) |
| 626 | |
| 627 | const createPayload: any = { |
| 628 | prompt, |
| 629 | model: model || 'ray-2', |
| 630 | aspect_ratio: aspectRatio, |
| 631 | loop: false, |
| 632 | } |
| 633 | |
| 634 | if (duration) { |
| 635 | createPayload.duration = `${duration}s` |
| 636 | } |
| 637 | |
| 638 | if (resolution) { |
| 639 | createPayload.resolution = resolution |
| 640 | } |
| 641 | |
| 642 | if (cameraControl) { |
| 643 | createPayload.concepts = Array.isArray(cameraControl) ? cameraControl : [{ key: cameraControl }] |
| 644 | } |
| 645 | |
| 646 | const createResponse = await fetch('https://api.lumalabs.ai/dream-machine/v1/generations', { |
| 647 | method: 'POST', |
| 648 | headers: { |
| 649 | Authorization: `Bearer ${apiKey}`, |
| 650 | 'Content-Type': 'application/json', |
| 651 | }, |
| 652 | body: JSON.stringify(createPayload), |
| 653 | }) |
| 654 | |
| 655 | if (!createResponse.ok) { |
| 656 | const error = await readVideoErrorText(createResponse, 'Luma create error response') |
| 657 | throw new Error(`Luma API error: ${createResponse.status} - ${error}`) |
| 658 | } |
| 659 | |
| 660 | const createData = await readVideoJson<{ id: string }>(createResponse, 'Luma create response') |
| 661 | const generationId = createData.id |
| 662 | |
| 663 | logger.info(`[${requestId}] Luma generation created: ${generationId}`) |
| 664 | |
| 665 | const pollIntervalMs = 5000 |
| 666 | const maxAttempts = Math.ceil(getMaxExecutionTimeout() / pollIntervalMs) |
| 667 | let attempts = 0 |
| 668 | |
| 669 | while (attempts < maxAttempts) { |
no test coverage detected