API Code Examples

Code Examples

Here are some examples to help you get started with the AIFrame API in different programming languages.

Python

import requests
import time
import os
 
# Configuration
API_KEY = "your_api_key_here"
BASE_URL = "https://api.aiframe.ai"
# Ensure VIDEO_PATH points to an actual video file for testing
VIDEO_PATH = "/path/to/your/video.mp4" 
DESCRIPTION = "This is a professional sales pitch for our new product line."
 
# Headers for all requests
headers = {
    "X-API-Key": API_KEY
}
 
def process_video():
    # 1. Submit the video for processing
    url = f"{BASE_URL}/api/process-video"
    
    # Check if video file exists
    if not os.path.exists(VIDEO_PATH):
        print(f"Error: Video file not found at {VIDEO_PATH}")
        return
 
    with open(VIDEO_PATH, "rb") as video_file:
        files = {
            "file": (os.path.basename(VIDEO_PATH), video_file)
        }
        
        data = {
            "description": DESCRIPTION,
            "blur_background": "true",
            "lip_sync_correction": "true",
            "eye_contact_correction": "false"
        }
        
        print("Submitting video for processing...")
        try:
            response = requests.post(url, headers=headers, files=files, data=data, timeout=30) # Added timeout
            response.raise_for_status() # Raises an HTTPError for bad responses (4XX or 5XX)
        except requests.exceptions.Timeout:
            print("Error: Request timed out.")
            return
        except requests.exceptions.HTTPError as e:
            print(f"HTTP Error: {e.response.status_code} - {e.response.text}")
            return
        except requests.exceptions.RequestException as e:
            print(f"Request Error: {e}")
            return
        
        result = response.json()
        video_id = result.get("video_id")
        if not video_id:
            print("Error: video_id not found in response.")
            print(result)
            return
            
        print(f"Video submitted successfully! Video ID: {video_id}")
        
        # 2. Poll for job completion
        status_url = f"{BASE_URL}/status/{video_id}"
        polling_interval = 10 # seconds
        max_attempts = 30 # 5 minutes total polling time (30 attempts * 10s)
        attempts = 0
 
        while attempts < max_attempts:
            attempts += 1
            print(f"Checking job status (attempt {attempts}/{max_attempts})...")
            try:
                status_response = requests.get(status_url, headers=headers, timeout=15) # Added timeout
                status_response.raise_for_status()
            except requests.exceptions.Timeout:
                print("Error: Status check timed out.")
                time.sleep(polling_interval)
                continue # Retry polling
            except requests.exceptions.HTTPError as e:
                print(f"HTTP Error during status check: {e.response.status_code} - {e.response.text}")
                break # Stop polling on HTTP error
            except requests.exceptions.RequestException as e:
                print(f"Request Error during status check: {e}")
                break # Stop polling on other request errors
            
            status_data = status_response.json()
            current_status = status_data.get("status")
            progress = status_data.get("progress", 0) # Default progress to 0 if not present
            
            print(f"Status: {current_status}, Progress: {progress}%")
            
            if current_status == "completed":
                download_url = status_data.get("download_url")
                if not download_url:
                    print("Error: Processing completed but no download URL provided.")
                    break
                print(f"Processing complete! Download URL: {download_url}")
                
                # 3. Download the processed video
                output_path = f"processed_{os.path.basename(VIDEO_PATH)}"
                try:
                    download_response = requests.get(download_url, timeout=60) # Added timeout for download
                    download_response.raise_for_status()
                    with open(output_path, "wb") as output_file:
                        output_file.write(download_response.content)
                    print(f"Video downloaded to {output_path}")
                except requests.exceptions.Timeout:
                    print("Error: Download request timed out.")
                except requests.exceptions.HTTPError as e:
                    print(f"HTTP Error during download: {e.response.status_code} - {e.response.text}")
                except requests.exceptions.RequestException as e:
                    print(f"Request Error during download: {e}")
                break
            
            elif current_status == "failed":
                error_message = status_data.get("error_message", "Unknown error.")
                print(f"Processing failed: {error_message}")
                break
            elif current_status == "not_found":
                print(f"Error: Job with video_id {video_id} not found.")
                break
            
            if attempts >= max_attempts:
                print("Max polling attempts reached. Job may still be processing.")
                break
 
            time.sleep(polling_interval)
 
if __name__ == "__main__":
    # Ensure you have a video file at the VIDEO_PATH for this to run
    # For example, create a dummy file: open("dummy_video.mp4", "w").write("dummy content")
    if not os.path.exists(VIDEO_PATH) and VIDEO_PATH == "/path/to/your/video.mp4":
        print(f"Placeholder VIDEO_PATH detected ({VIDEO_PATH}). Please update it to a real video file.")
    else:
        process_video()

Node.js

const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');
const path = require('path');
 
// Configuration
const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.aiframe.ai';
// Ensure VIDEO_PATH points to an actual video file for testing
const VIDEO_PATH = '/path/to/your/video.mp4'; 
const DESCRIPTION = 'This is a professional sales pitch for our new product line.';
 
// Helper function to delay execution
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
 
// Process a video with AIFrame
async function processVideo() {
  try {
    // 1. Submit the video for processing
    console.log('Submitting video for processing...');
    
    if (!fs.existsSync(VIDEO_PATH)) {
        console.error(`Error: Video file not found at ${VIDEO_PATH}`);
        return;
    }
 
    const form = new FormData();
    form.append('file', fs.createReadStream(VIDEO_PATH));
    form.append('description', DESCRIPTION);
    form.append('blur_background', 'true');
    form.append('lip_sync_correction', 'true');
    form.append('eye_contact_correction', 'false');
    
    const submitResponse = await axios.post(`${BASE_URL}/api/process-video`, form, {
      headers: {
        'X-API-Key': API_KEY,
        ...form.getHeaders()
      },
      timeout: 30000 // 30 seconds timeout
    });
    
    const videoId = submitResponse.data.video_id;
    if (!videoId) {
        console.error("Error: video_id not found in response.", submitResponse.data);
        return;
    }
    console.log(`Video submitted successfully! Video ID: ${videoId}`);
    
    // 2. Poll for job completion
    let isCompleted = false;
    const pollingInterval = 10000; // 10 seconds
    const maxAttempts = 30; // 5 minutes total polling time
    let attempts = 0;
    
    while (!isCompleted && attempts < maxAttempts) {
      attempts++;
      console.log(`Checking job status (attempt ${attempts}/${maxAttempts})...`);
      
      const statusResponse = await axios.get(`${BASE_URL}/status/${videoId}`, {
        headers: {
          'X-API-Key': API_KEY
        },
        timeout: 15000 // 15 seconds timeout
      });
      
      const statusData = statusResponse.data;
      const currentStatus = statusData.status;
      const progress = statusData.progress || 0;
      
      console.log(`Status: ${currentStatus}, Progress: ${progress}%`);
      
      if (currentStatus === 'completed') {
        const downloadUrl = statusData.download_url;
        if (!downloadUrl) {
            console.error("Error: Processing completed but no download URL provided.");
            isCompleted = true;
            break;
        }
        console.log(`Processing complete! Download URL: ${downloadUrl}`);
        
        // 3. Download the processed video
        const outputFilename = `processed_${path.basename(VIDEO_PATH)}`;
        const writer = fs.createWriteStream(outputFilename);
        
        const downloadStreamResponse = await axios({
          method: 'get',
          url: downloadUrl,
          responseType: 'stream',
          timeout: 60000 // 60 seconds timeout for download
        });
        
        downloadStreamResponse.data.pipe(writer);
        
        await new Promise((resolve, reject) => {
          writer.on('finish', resolve);
          writer.on('error', reject);
        });
        
        console.log(`Video downloaded to ${outputFilename}`);
        isCompleted = true;
        
      } else if (currentStatus === 'failed') {
        const errorMessage = statusData.error_message || "Unknown error.";
        console.log(`Processing failed: ${errorMessage}`);
        isCompleted = true;
      } else if (currentStatus === 'not_found') {
        console.log(`Error: Job with video_id ${videoId} not found.`);
        isCompleted = true;  
      } else {
        if (attempts >= maxAttempts) {
            console.log("Max polling attempts reached. Job may still be processing.");
            break;
        }
        await delay(pollingInterval);
      }
    }
    
  } catch (error) {
    console.error('Error during video processing:');
    if (error.response) {
      console.error('Response Status:', error.response.status);
      console.error('Response Data:', error.response.data);
    } else if (error.request) {
      console.error('No response received:', error.request);
    } else {
      console.error('Error message:', error.message);
    }
  }
}
 
// Ensure you have a video file at VIDEO_PATH for this to run
if (!fs.existsSync(VIDEO_PATH) && VIDEO_PATH === '/path/to/your/video.mp4') {
    console.log(`Placeholder VIDEO_PATH detected (${VIDEO_PATH}). Please update it to a real video file and install axios, form-data (npm install axios form-data).`);
} else {
    processVideo();
}

cURL Script

This script demonstrates the full process of submitting a video and polling for its status using cURL and jq (for JSON parsing).

#!/bin/bash
 
# Configuration - SET THESE VARIABLES
API_KEY="your_api_key_here"
# Ensure VIDEO_PATH points to an actual video file for testing
VIDEO_PATH="/path/to/your/video.mp4"
DESCRIPTION="This is a professional sales pitch for our new product line."
BASE_URL="https://api.aiframe.ai"
POLLING_INTERVAL=10 # seconds
MAX_POLLING_ATTEMPTS=30 # 5 minutes (30 * 10s)
 
# Check if VIDEO_PATH is set and file exists
if [ "$VIDEO_PATH" = "/path/to/your/video.mp4" ] || [ ! -f "$VIDEO_PATH" ]; then
  echo "Error: VIDEO_PATH is not set to a valid file. Please update the script."
  exit 1
fi
 
# Check for jq
if ! command -v jq &> /dev/null
then
    echo "jq could not be found. Please install jq to run this script."
    echo "On macOS: brew install jq"
    echo "On Debian/Ubuntu: sudo apt-get install jq"
    exit 1
fi
 
# Step 1: Submit the video for processing
echo "Submitting video for processing: $VIDEO_PATH"
 
RESPONSE=$(curl -s -X POST \
  -H "X-API-Key: $API_KEY" \
  --form "description=$DESCRIPTION" \
  --form "blur_background=true" \
  --form "lip_sync_correction=true" \
  --form "eye_contact_correction=false" \
  --form "file=@$VIDEO_PATH" \
  $BASE_URL/api/process-video)
 
# Check for curl error in submission
if [ $? -ne 0 ]; then
  echo "Error: cURL command failed during video submission."
  echo "Response: $RESPONSE"
  exit 1
fi
 
VIDEO_ID=$(echo $RESPONSE | jq -r '.video_id')
INITIAL_STATUS=$(echo $RESPONSE | jq -r '.status')
 
if [ -z "$VIDEO_ID" ] || [ "$VIDEO_ID" = "null" ]; then
  echo "Error submitting video. video_id not found or null."
  echo "Response: $RESPONSE"
  exit 1
fi
 
echo "Video submitted successfully! Video ID: $VIDEO_ID, Initial Status: $INITIAL_STATUS"
 
# Step 2: Poll for job completion
COMPLETED=false
ATTEMPTS=0
 
while [ "$COMPLETED" = false ] && [ $ATTEMPTS -lt $MAX_POLLING_ATTEMPTS ]; do
  ATTEMPTS=$((ATTEMPTS + 1))
  echo "Checking job status (attempt $ATTEMPTS/$MAX_POLLING_ATTEMPTS)..."
  
  STATUS_RESPONSE=$(curl -s -X GET \
    -H "X-API-Key: $API_KEY" \
    $BASE_URL/status/$VIDEO_ID)
 
  # Check for curl error in status check
  if [ $? -ne 0 ]; then
    echo "Error: cURL command failed during status check."
    echo "Response: $STATUS_RESPONSE"
    # Optionally, decide if you want to continue polling or exit
    sleep $POLLING_INTERVAL
    continue
  fi
  
  STATUS=$(echo $STATUS_RESPONSE | jq -r '.status')
  PROGRESS=$(echo $STATUS_RESPONSE | jq -r '.progress // 0') # Default to 0 if null
  
  echo "Current Status: $STATUS, Progress: $PROGRESS%"
  
  if [ "$STATUS" = "completed" ]; then
    DOWNLOAD_URL=$(echo $STATUS_RESPONSE | jq -r '.download_url')
    if [ -z "$DOWNLOAD_URL" ] || [ "$DOWNLOAD_URL" = "null" ]; then
        echo "Error: Processing completed but no download URL provided."
        COMPLETED=true # Exit loop
        break
    fi
    echo "Processing complete! Download URL: $DOWNLOAD_URL"
    
    # Step 3: Download the processed video
    OUTPUT_FILENAME="processed_$(basename "$VIDEO_PATH")"
    echo "Downloading to $OUTPUT_FILENAME..."
    curl -s -o "$OUTPUT_FILENAME" "$DOWNLOAD_URL"
    
    if [ $? -eq 0 ]; then
        echo "Video downloaded successfully to $OUTPUT_FILENAME"
    else
        echo "Error downloading video. cURL exit code: $?"
    fi
    COMPLETED=true
    
  elif [ "$STATUS" = "failed" ]; then
    ERROR_MESSAGE=$(echo $STATUS_RESPONSE | jq -r '.error_message // "Unknown error.'')
    echo "Processing failed: $ERROR_MESSAGE"
    COMPLETED=true
 
  elif [ "$STATUS" = "not_found" ]; then
    echo "Error: Job with video_id $VIDEO_ID not found."
    COMPLETED=true
    
  else # Pending or Processing
    if [ $ATTEMPTS -ge $MAX_POLLING_ATTEMPTS ]; then
        echo "Max polling attempts reached. Job status is still '$STATUS'."
        echo "You may need to check its status later manually or increase MAX_POLLING_ATTEMPTS."
        break
    fi
    echo "Waiting $POLLING_INTERVAL seconds before checking again..."
    sleep $POLLING_INTERVAL
  fi
done
 
if [ "$COMPLETED" = false ]; then
    echo "Polling finished, but job did not reach a final state (completed/failed/not_found)."
fi