← back to browse
goat command

animate

Animate a picture into a short video using a prompt

0
views
0
likes
0
installs
raw source
const axios = require("axios");
const { createCanvas, loadImage } = require("canvas");
const fs = require("fs");
const path = require("path");
const FormData = require("form-data");

// === API utils ===
async function getStreamFromURL(url) {
  const res = await axios.get(url, { responseType: "stream" });
  return res.data;
}

function generateRandomId(len = 16) {
  const chars = "abcdef0123456789";
  return Array.from({ length: len }, () => chars[Math.floor(Math.random() * chars.length)]).join("");
}

async function getBalance() {
  const pack = generateRandomId();
  await axios.post("https://api.getglam.app/rewards/claim/hdnu30r7auc4kve", null, {
    headers: {
      "User-Agent": "Glam/1.58.4 Android/32 (Samsung SM-A156E)",
      "glam-user-id": pack,
      "user_id": pack,
      "glam-local-date": new Date().toISOString(),
    },
  });
  return pack;
}

async function uploadFile(pack, stream, prompt, duration = 5) {
  const form = new FormData();
  form.append("package_id", pack);
  form.append("media_file", stream);
  form.append("media_type", "image");
  form.append("template_id", "community_img2vid");
  form.append("template_category", "20_coins_dur");
  form.append("frames", JSON.stringify([{
    prompt,
    custom_prompt: prompt,
    start: 0,
    end: 0,
    timings_units: "frames",
    media_type: "image",
    style_id: "chained_falai_img2video",
    rate_modifiers: { duration: duration.toString() + "s" },
  }]));

  const res = await axios.post("https://android.getglam.app/v2/magic_video", form, {
    headers: { ...form.getHeaders(), "User-Agent": "Glam/1.58.4 Android/32 (Samsung SM-A156E)" },
  });

  return res.data.event_id;
}

async function getStatus(taskID, pack) {
  while (true) {
    const res = await axios.get("https://android.getglam.app/v2/magic_video", {
      params: { package_id: pack, event_id: taskID },
      headers: { "User-Agent": "Glam/1.58.4 Android/32 (Samsung SM-A156E)" },
    });
    if (res.data.status === "READY") return [res.data];
    await new Promise(r => setTimeout(r, 2000));
  }
}

async function imgToVideo(prompt, filePath, duration = 5) {
  const pack = await getBalance();
  const task = await uploadFile(pack, fs.createReadStream(filePath), prompt, duration);
  return await getStatus(task, pack);
}

// === Command ===
module.exports = {
  config: {
    name: "animate",
    version: "1.0",
    author: "SHIFAT",
    role: 3,
    description: "Animate a picture into a short video using a prompt",
    category: "anime",
    guide: "Reply to a picture and type: animate <your prompt>"
  },

  onStart: async function ({ event, message, usersData, media }) {
    if (!event.messageReply && !media) {
      return message.reply("๐Ÿฆ‹ You must reply to an image to animate it!");
    }

    const promptText = event.body.replace(/^animate\s+/i, "").trim();
    if (!promptText) {
      return message.reply("๐Ÿคฆ Please provide a prompt after the command.");
    }

    // Get the image stream
    let filePath;
    try {
      if (media) {
        filePath = media.filePath;
      } else {
        const url = event.messageReply.attachments[0].url;
        filePath = path.join(__dirname, "cache", `animate_${Date.now()}.png`);
        const writer = fs.createWriteStream(filePath);
        const response = await axios.get(url, { responseType: "stream" });
        response.data.pipe(writer);
        await new Promise((resolve) => writer.on("finish", resolve));
      }
    } catch (err) {
      console.error(err);
      return message.reply("โ˜ ๏ธ Failed to download the image.");
    }

    const waitMsg = await message.reply("โณ Generating animated video...");

    try {
      const result = await imgToVideo(promptText, filePath, 5);
      await message.reply({
        body: `๐ŸŽฌ Animation complete! Prompt: ${promptText}`,
        attachment: await getStreamFromURL(result[0].video_url)
      });

      fs.unlinkSync(filePath);
    } catch (err) {
      console.error("animate command error:", err);
      message.reply("โ„๏ธ Error while generating animation.");
    }
  }
};

View raw file