Motion Controls

Motion Controls

  • Motion Controls 是一套 AI 视频效果系统,可以动态制作静态图片动画,或通过缩放、旋转、抖动、弹跳和自定义摄像机路径等运动变换增强已有视频。

Features(功能)

  • Motion Controls 使用 AI 生成的运动层和关键帧模拟摄像机移动与物体动态,从而实现流畅的动画效果。

Key Features(主要功能)

  • 动态运动效果:通过提示词或预设控制应用缩放、旋转、抖动、平移、转动和弹跳。
  • 静态图转动态视频:让静态图片变成具有逼真摄像机运动和动画流程的动态视觉内容。
  • 平滑过渡:生成插值帧,保证动画连贯且不闪烁。
  • 提示词或预设驱动:同时支持自然语言提示词(例如“向左旋转并放大”)和预定义效果类型。
  • 面向短片优化:针对 5–10 秒的片段优化,以获得更高质量。
  • 快速推理流程:根据时长和分辨率,大多数片段可在 2 分钟内完成渲染。

Limitations(限制)

  • 不是现实动作捕捉:不会跟踪或模仿真实物体运动,而是创建基于摄像机或路径的合成运动。
  • 针对短片优化:未经分段不适合处理超过 10 秒的片段。
  • 提示词歧义:缺乏具体描述的提示词(例如“让它动起来”)可能产生意外结果。
  • 单主体效果最佳:在只有一个主要主体或焦点的图片/视频上效果最好。

Out-of-Scope Use(禁止用途)

  • Motion Controls 不得用于违反道德准则或法律标准的场景,包括:

    1. 生成冒充真实世界影像的误导性内容。
    2. 对敏感、暴力或有害图像应用运动效果。
    3. 增强或制作 NSFW 内容动画。
    4. 通过被操纵的视频运动效果进行骚扰或滥用。
    5. 将 AI 生成的动画用于政治或虚假信息宣传活动。

Authentication(身份验证)

API Endpoints(API 端点)

Submit Task & Query Result(提交任务与查询结果)

  • cURL

    # Submit Task
    curl --location --request POST 'https://api.muapi.ai/api/v1/generate_wan_ai_effects' \
      --header "Content-Type: application/json" \
      --header "x-api-key: {MUAPIAPP_API_KEY}" \
      --data-raw '{
        "prompt": "a blueberry person",
        "image_url": "https://example.com/blueberry.jpg",
        "name": "360 Orbit",
        "aspect_ratio": "16:9",
        "resolution": "480p",
        "quality": "medium",
        "duration": 5
      }'
    
    # Poll for results
    curl --location --request GET "https://api.muapi.ai/api/v1/predictions/${request_id}/result" \
      --header "x-api-key: {MUAPIAPP_API_KEY}"
    
  • Python

    import os
    import requests
    import json
    import time
    
    from dotenv import load_dotenv
    load_dotenv()
    
    def main():
      print("Hello from MuApiApp!")
      API_KEY = os.getenv("MUAPIAPP_API_KEY")
      print(f"API_KEY: {API_KEY}")
    
      url = "https://api.muapi.ai/api/v1/generate_wan_ai_effects"
      headers = {
        "Content-Type": "application/json",
        "x-api-key": f"{API_KEY}",
      }
      payload = {
        "prompt": "a blueberry person",
        "image_url": "https://d3adwkbyhxyrtq.cloudfront.net/ai-images/186/833006366055/4f966d88-9ad7-4bd9-966d-c0fd7c5a9eb9.jpg",
        "name": "360 Orbit",
        "aspect_ratio": "16:9",
        "resolution": "480p",
        "quality": "medium",
        "duration": 5
      }
    
      begin = time.time()
      response = requests.post(url, headers=headers, data=json.dumps(payload))
      if response.status_code == 200:
        result = response.json()
        request_id = result["data"]["request_id"]
        print(f"Task submitted successfully. Request ID: {request_id}")
      else:
        print(f"Error: {response.status_code}, {response.text}")
        return
    
      url = f"https://api.muapi.ai/api/v1/predictions/{request_id}/result"
      headers = {"x-api-key": f"{API_KEY}"}
    
      while True:
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
          result = response.json()
          status = result["data"]["status"]
    
          if status == "completed":
            end = time.time()
            print(f"Task completed in {end - begin} seconds.")
            url = result["video"]["url"]
            print(f"Task completed. URL: {url}")
            break
          elif status == "failed":
            print(f"Task failed: {result.get('error')}")
            break
          else:
            print(f"Task still processing. Status: {status}")
        else:
          print(f"Error: {response.status_code}, {response.text}")
          break
    
        time.sleep(0.5)
    
    if __name__ == "__main__":
      main()
    
  • JavaScript

    require('dotenv').config();
    const axios = require('axios');
    
    async function main() {
      console.log("Hello from MuApiApp!");
    
      const API_KEY = process.env.MUAPIAPP_API_KEY;
      console.log(`API_KEY: ${API_KEY}`);
    
      const url = 'https://api.muapi.ai/api/v1/generate_wan_ai_effects';
      const headers = {
        'Content-Type': 'application/json',
        'x-api-key': `${API_KEY}`,
      };
    
      const payload = {
        prompt: 'a blueberry person',
        image_url: 'https://d3adwkbyhxyrtq.cloudfront.net/ai-images/186/833006366055/4f966d88-9ad7-4bd9-966d-c0fd7c5a9eb9.jpg',
        name: '360 Orbit',
        aspect_ratio: '16:9',
        resolution: '480p',
        quality: 'medium',
        duration: 5,
      };
    
      try {
        const begin = Date.now();
        const response = await axios.post(url, payload, { headers });
    
        if (response.status === 200) {
          const requestId = response.data.data.request_id;
          console.log(`Task submitted successfully. Request ID: ${requestId}`);
    
          const resultUrl = `https://api.muapi.ai/api/v1/predictions/${request_id}/result`;
          const pollHeaders = { x-api-key: `${API_KEY}` };
    
          while (true) {
            const pollResponse = await axios.get(resultUrl, { headers: pollHeaders });
    
            if (pollResponse.status === 200) {
              const status = pollResponse.data.data.status;
    
              if (status === 'completed') {
                const end = Date.now();
                console.log(`Task completed in ${(end - begin) / 1000} seconds.`);
                const videoUrl = pollResponse.data.video.url;
                console.log(`Task completed. URL: ${videoUrl}`);
                break;
              } else if (status === 'failed') {
                console.log(`Task failed: ${pollResponse.data.error}`);
                break;
              } else {
                console.log(`Task still processing. Status: ${status}`);
              }
            } else {
              console.log(`Error: ${pollResponse.status}, ${pollResponse.statusText}`);
              break;
            }
    
            await new Promise(resolve => setTimeout(resolve, 500));
          }
        } else {
          console.log(`Error: ${response.status}, ${response.statusText}`);
        }
      } catch (error) {
        console.error(`Request failed: ${error.message}`);
      }
    }
    
    main();
    

Parameters(参数)

Task Submission Parameters(任务提交参数)

Request Parameters(请求参数)

参数类型必填默认值范围说明
promptstring""-生成输出所使用的提示词。
image_urlstring""-用于生成输出的图片。
namestring""-任务或输出文件的自定义名称。
aspect_ratiostring16:91:1、9:16、16:9输出视频的宽高比。
resolutionstring480p480p、720p输出视频的分辨率。
qualitystringmediummedium、high控制整体视频质量,也会影响渲染时间。
durationnumber55 ~ 10生成视频的时长,单位为秒。

Response Parameters(响应参数)

参数类型说明
codeintegerHTTP 状态码,例如成功时为 200。
messagestring状态消息,例如 success。
idstring生成任务的唯一标识符。
outputsarray of strings指向生成视频输出的 URL。
urls.getstring通过任务 ID 获取结果的 API URL。
has_nsfw_contentsarray of booleans指示输出是否包含 NSFW 内容。
statusstring任务状态:completed、failed 或 processing。
created_atstring(timestamp)任务创建时间的 ISO 时间戳。
errorstring任务失败时的错误信息;成功时为空。
executionTimenumber(milliseconds)任务完成所用的总时间,单位为毫秒。
timings.inferencenumber(milliseconds)模型推理所用时间,单位为毫秒。

Result Query Parameters(结果查询参数)

Result Request Parameters(结果请求参数)

参数类型必填默认值说明
idstring-任务 ID

Result Response Parameters(结果响应参数)

参数类型说明
codeintegerHTTP 状态码,例如成功时为 200。
messagestring状态消息,例如 success。
idstring生成任务的唯一标识符。
outputsarray of strings指向生成视频输出的 URL。
urls.getstring通过任务 ID 获取结果的 API URL。
has_nsfw_contentsarray of booleans指示输出是否包含 NSFW 内容。
statusstring任务状态:completed、failed 或 processing。
created_atstring(timestamp)任务创建时间的 ISO 时间戳。
errorstring任务失败时的错误信息;成功时为空。
executionTimenumber(milliseconds)任务完成所用的总时间,单位为毫秒。
timings.inferencenumber(milliseconds)模型推理所用时间,单位为毫秒。
Motion Controls — Muapi Docs