| async function videoGenerator(prompt) { | |
| if (!prompt) return { error: "Prompt tidak boleh kosong" }; | |
| const videoId = `video_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`; | |
| const apiUrl = "https://veo31.ai/api"; | |
| try { | |
| const res = await fetch(`${apiUrl}/generate/stream`, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| prompt, | |
| aspectRatio: "9:16", | |
| videoId, | |
| }), | |
| }); | |
| const data = await res.json(); | |
| if (!data.success) return { status: "failed", error: "Error generating video", detail: data }; | |
| await new Promise((r) => setTimeout(r, 120000)); | |
| while (true) { | |
| const check = await fetch(`${apiUrl}/webhook?videoId=${videoId}`); | |
| const status = await check.json(); | |
| if (status.status === "completed") { | |
| return { | |
| status: "completed", | |
| videoUrl: status.videoUrl, | |
| videoId, | |
| }; | |
| } else if (status.status === "failed") { | |
| return { | |
| status: "failed", | |
| error: status.error || "unknown", | |
| }; | |
| } else { | |
| await new Promise((r) => setTimeout(r, 60000)); | |
| } | |
| } | |
| } catch (err) { | |
| return { status: "error", error: err.message }; | |
| } | |
| } | |
| const handler = async (req, res) => { | |
| const startTime = Date.now(); | |
| try { | |
| const { prompt, key } = req.query; | |
| if (!prompt) { | |
| return res.status(400).json({ | |
| author: 'Herza', | |
| success: false, | |
| msg: 'Missing required parameter: prompt', | |
| usage: '/api/AI/sora2nowm?prompt=your_prompt&key=your_key' | |
| }); | |
| } | |
| if (!key) { | |
| return res.status(400).json({ | |
| author: 'Herza', | |
| success: false, | |
| msg: 'Missing required parameter: key' | |
| }); | |
| } | |
| console.log(`\n${'='.repeat(60)}`); | |
| console.log('NEW REQUEST RECEIVED'); | |
| console.log(`Prompt: ${prompt}`); | |
| console.log(`${'='.repeat(60)}\n`); | |
| const result = await videoGenerator(prompt); | |
| const duration = ((Date.now() - startTime) / 1000).toFixed(2); | |
| if (result.status === "completed") { | |
| console.log(`\n${'='.repeat(60)}`); | |
| console.log('REQUEST COMPLETED'); | |
| console.log(`Duration: ${duration}s`); | |
| console.log(`${'='.repeat(60)}\n`); | |
| res.json({ | |
| author: 'Herza', | |
| success: true, | |
| data: { | |
| model: 'veo31-sora2', | |
| prompt: prompt, | |
| videoUrl: result.videoUrl, | |
| videoId: result.videoId, | |
| processingTime: `${duration}s` | |
| } | |
| }); | |
| } else { | |
| throw new Error(result.error || 'Video generation failed'); | |
| } | |
| } catch (error) { | |
| console.error('\n❌ ERROR:', error.message); | |
| console.error('Stack:', error.stack); | |
| const duration = ((Date.now() - startTime) / 1000).toFixed(2); | |
| res.status(500).json({ | |
| author: 'Herza', | |
| success: false, | |
| msg: error.message || 'Terjadi kesalahan saat generate video.', | |
| processingTime: `${duration}s`, | |
| error: { | |
| code: error.code || 'UNKNOWN', | |
| details: error.response?.data || null | |
| } | |
| }); | |
| } | |
| } | |
| module.exports = { | |
| name: 'Sora2 Video Generator No Watermark', | |
| description: 'Generate videos using Sora2 AI model without watermark', | |
| type: 'GET', | |
| routes: ['api/AI/sora2nowm'], | |
| tags: ['AI', 'Sora', 'Video', 'NoWatermark'], | |
| parameters: ['prompt', 'key'], | |
| enabled: true, | |
| main: ['AI'], | |
| limit: 15, | |
| handler | |
| }; |