Video Editing Prompts

Video Editing with Text Prompts

In this sample, we'll demonstrate how to use text prompts to perform video editing tasks using the Timeline API. We'll upload video files, use a descriptive prompt to generate an edited timeline, and export the final timeline in OTIO format.

Overview

  • Objective: Edit videos based on a text prompt and export the edited timeline.
  • APIs Used:
    • Asset Management API
    • Timeline API

Steps

  1. Authenticate and set up necessary variables.
  2. Upload the video files using the Asset Management API.
  3. Generate an edited timeline using a text prompt with the Timeline API.
  4. Retrieve and display the generated timeline.
  5. Refine the timeline using a new prompt.
  6. Retrieve and display the refined timeline.
  7. Export the refined timeline in OTIO format.

Detailed Steps with Code

Step 1: Authenticate and Set Up

Set up your API key and necessary variables.

import requests
import json
import time
 
# Replace with your actual API key
API_KEY = 'YOUR_API_KEY'
 
# Base URLs
BASE_URL = 'https://api.play-video.dev'
 
# Headers
headers = {
    'X-API-Key': API_KEY,
    'Content-Type': 'application/json'
}
 
# Helper function to poll asset status
def poll_asset_status(asset_uuid, interval=10, timeout=600):
    status_url = f"{BASE_URL}/asset/{asset_uuid}/status"
    elapsed_time = 0
    while elapsed_time < timeout:
        response = requests.get(status_url, headers=headers)
        response.raise_for_status()
        status = response.json()['status']
        print(f"Asset {asset_uuid} status: {status}")
        if status == 'READY':
            return True
        elif status == 'FAILED':
            raise Exception(f"Asset {asset_uuid} processing failed.")
        time.sleep(interval)
        elapsed_time += interval
    raise TimeoutError(f"Asset {asset_uuid} did not become READY within {timeout} seconds.")

Step 2: Upload the Video Files

We'll upload multiple video files that we want to edit based on a text prompt.

a) Create Assets and Upload Files
asset_uuids = []
 
# List of video files to upload
video_files = [
    '/path/to/your/video1.mp4',
    '/path/to/your/video2.mp4',
    '/path/to/your/video3.mp4'
    # Add more file paths as needed
]
 
for file_path in video_files:
    filename = file_path.split('/')[-1]  # Extract filename from path
 
    # Create an asset
    create_asset_url = f"{BASE_URL}/asset/create"
    create_asset_payload = {
        'filename': filename,
        'indexer_profile_uuid': 'YOUR_INDEXER_PROFILE_UUID'  # Replace with your indexer profile UUID
    }
 
    response = requests.post(create_asset_url, headers=headers, json=create_asset_payload)
    response.raise_for_status()
    asset_response = response.json()
 
    asset_uuid = asset_response['uuid']
    s3_presigned_url = asset_response['s3_presigned_url']
 
    print(f"Asset UUID: {asset_uuid}")
 
    # Upload the file to S3
    with open(file_path, 'rb') as file_data:
        s3_response = requests.put(s3_presigned_url, data=file_data)
        s3_response.raise_for_status()
 
    print(f"File '{filename}' uploaded successfully to S3.")
 
    # Poll the asset status
    try:
        poll_asset_status(asset_uuid)
        print(f"Asset {asset_uuid} is READY.")
    except Exception as e:
        print(str(e))
        continue  # Skip this asset if it failed
 
    # Add the asset UUID to the list
    asset_uuids.append(asset_uuid)

Step 3: Generate an Edited Timeline Using a Text Prompt

Use a descriptive text prompt to specify the desired editing instructions.

# Ensure we have at least one asset
if not asset_uuids:
    print("No assets are READY for generating the timeline.")
    exit(1)
 
# Step 3: Generate edited timeline using a text prompt
generate_timeline_url = f"{BASE_URL}/timelines/generate/subject"
 
# Your editing instructions as a text prompt
text_prompt = (
    "Create a compelling narrative by combining scenes where the protagonist "
    "is facing challenges, followed by moments of triumph. Include any dramatic "
    "music cues and exclude any scenes with background noise."
)
 
# Request payload
generate_timeline_payload = {
    'prompt': text_prompt,
    'files': asset_uuids,
    'subjects': []  # You can specify subjects if needed
}
 
timeline_response = requests.post(generate_timeline_url, headers=headers, json=generate_timeline_payload)
timeline_response.raise_for_status()
timeline_data = timeline_response.json()
 
# Extract the timeline UUID
timeline_uuid = timeline_data['uuid']
 
print(f"Generated Timeline UUID: {timeline_uuid}")

Step 4: Retrieve and Display the Generated Timeline

Retrieve the generated timeline to inspect the edits made based on your prompt.

 
# Step 4: Retrieve the generated timeline
get_timeline_url = f"{BASE_URL}/timelines/{timeline_uuid}"
 
timeline_details_response = requests.get(get_timeline_url, headers=headers)
timeline_details_response.raise_for_status()
timeline_details = timeline_details_response.json()
 
print("Generated Timeline Details:")
print(json.dumps(timeline_details, indent=2))

Step 5: Refine the Timeline Using a New Prompt

Use the /timelines/{uuid}/refine endpoint to refine the existing timeline with new instructions.

# Step 5: Refine the timeline
refine_timeline_url = f"{BASE_URL}/timelines/{timeline_uuid}/refine"
 
# New prompt for refining the timeline
refine_prompt = (
    "Adjust the pacing to be faster, remove any slow-motion scenes, "
    "and add upbeat background music. Focus on action sequences."
)
 
# Request payload
refine_timeline_payload = {
    'prompt': refine_prompt,
    'files': [],  # Optional: You can include additional files if needed
    'subjects': []  # Optional: Specify new subjects if needed
}
 
refine_response = requests.post(refine_timeline_url, headers=headers, json=refine_timeline_payload)
refine_response.raise_for_status()
refined_timeline_data = refine_response.json()
 
print("Timeline has been refined.")

Step 6: Retrieve and Display the Refined Timeline

Retrieve the refined timeline to see the changes made based on the new prompt.

# Optionally, wait for the refined timeline to be ready
time.sleep(60)  # Adjust sleep time as necessary
 
# Step 6: Retrieve the refined timeline
refined_timeline_details_response = requests.get(get_timeline_url, headers=headers)
refined_timeline_details_response.raise_for_status()
refined_timeline_details = refined_timeline_details_response.json()
 
print("Refined Timeline Details:")
print(json.dumps(refined_timeline_details, indent=2))

Step 7: Export the Refined Timeline in OTIO Format

Export the refined timeline to OTIO format for further use in video editing software.

# Step 7: Export the refined timeline to OTIO format
export_format = 'otio'
 
export_timeline_url = f"{BASE_URL}/timelines/{timeline_uuid}/export/{export_format}"
 
export_response = requests.post(export_timeline_url, headers={'X-API-Key': API_KEY})
export_response.raise_for_status()
 
# Save the exported timeline to a file
output_filename = f"refined_edited_timeline.{export_format}"
with open(output_filename, 'wb') as f:
    f.write(export_response.content)
 
print(f"Refined timeline exported as '{output_filename}'.")

Note: The refine endpoint allows you to provide new instructions to adjust the existing timeline. Refer to the Timeline API Documentation for details on the /timelines/{uuid}/refine endpoint.


Note: The effectiveness of the editing depends on the capabilities of the Timeline API in interpreting and acting upon your text prompt. Be as clear and descriptive as possible to achieve the desired results.