Demos

Below you will find many different examples and demos of OpenShot Cloud API. Sample code is provided in many common programming languages, including Python, C#, and JavaScript.

Demo App (simple-editor)

Check out our free demo app (simple-editor), built with JavaScript, Node.js, and Vue 3, powered by OpenShot Cloud API. This demo is designed as both a showcase for how OpenShot Cloud API can be used and a jump-start for your own software development projects based on OpenShot Cloud API! The source code is licensed under the MIT license, and can be used with both open-source and commercial applications.

Create and manage video editing projects:

Create and manage video editing projects

Upload files, preview videos, and create clips:

Upload files, preview videos, and create clips

Python Example Script

Here is a simple example client script, using Python 3. It connects, creates a new project, uploads a file, creates a clip, and then exports a new video. It should give you a good sense of how things work in general, regardless of programming language. Learn more about the API Endpoints / Schema.

import os
import time
from requests import get, post
from requests.auth import HTTPBasicAuth

PATH = os.path.dirname(os.path.realpath(__file__))
CLOUD_URL = 'http://cloud.openshot.org'
CLOUD_AUTH = HTTPBasicAuth('demo-cloud', 'demo-password')


##########################################################
# Get list of projects
end_point = '/projects/'
r = get(CLOUD_URL + end_point, auth=CLOUD_AUTH)
print(r.json())


##########################################################
# Create new project
end_point = '/projects/'
project_data = {
    "name": "API Project",
    "width": 1920,
    "height": 1080,
    "fps_num": 30,
    "fps_den": 1,
    "sample_rate": 44100,
    "channels": 2,
    "channel_layout": 3,
    "json": "{}",
}
r = post(CLOUD_URL + end_point, data=project_data, auth=CLOUD_AUTH)
print(r.json())
project_id = r.json().get("id")
project_url = r.json().get("url")


##########################################################
# Upload file to project
end_point = '/projects/%s/files/' % project_id
source_path = os.path.join(PATH, "example-video.mp4")
source_name = os.path.split(source_path)[1]
file_data = {
    "media": None,
    "project": project_url,
    "json": "{}"
}
r = post(CLOUD_URL + end_point, data=file_data, files={"media": (source_name, open(source_path, "rb"))}, auth=CLOUD_AUTH)
file_url = r.json().get("url")
print(r.json())


##########################################################
# Create a clip for the previously uploaded file
end_point = '/projects/%s/clips/' % project_id
clip_data = {
    "file": file_url,
    "position": 0.0,
    "start": 0.0,
    "end": 30.0,
    "layer": 1,
    "project": project_url,
    "json": "{}"
}
r = post(CLOUD_URL + end_point, data=clip_data, auth=CLOUD_AUTH)
print(r.json())


##########################################################
# Create export for final rendered video
end_point = '/projects/%s/exports/' % project_id
export_data = {
    "video_format": "mp4",
    "video_codec": "libx264",
    "video_bitrate": 8000000,
    "audio_codec": "ac3",
    "audio_bitrate": 1920000,
    "start_frame": 1,
    "end_frame": None,
    "project": project_url,
    "json": "{}"
}
r = post(CLOUD_URL + end_point, data=export_data, auth=CLOUD_AUTH)
export_url = r.json().get("url")
print(r.json())


##########################################################
# Wait for Export to finish (give up after around 40 minutes)
export_output_url = None
is_exported = False
countdown = 500
while not is_exported and countdown > 1:
    r = get(export_url, auth=CLOUD_AUTH)
    print(r.json())
    is_exported = float(r.json().get("progress", 0.0)) == 100.0
    countdown -= 1
    time.sleep(5.0)

# Get final rendered url
r = get(export_url, auth=CLOUD_AUTH)
export_output_url = r.json().get("output")
print(r.json())
print("Export Successfully Completed: %s!" % export_output_url)

Node.js Example Script

Here is a simple example client script, using JavaScript and Node.js. It connects, creates a new project, uploads some files, creates some clips, exports a video, and then downloads the new video file. It should give you a good sense of how things work using asynchronous JavaScript. Learn more about the API Endpoints / Schema.

var request = require('request-promise');
var fs = require('fs');
var Promise = require("promise");
var promisePoller = require('promise-poller').default;

var projectId = '';
var projectUrl = '';
var exportId = '';
const projectData = {
    'json': '{}',
    'name': 'My Project Name'
};

const protocol = 'http';
const server = 'cloud.openshot.org';
const auth = { 'user': 'demo-cloud',
               'pass': 'demo-password'};

// Create a new project
post('/projects/', projectData)
    .then(function(response){
        projectUrl = JSON.parse(response).url;
        projectId = JSON.parse(response).id;
        console.log('Successfully created project: ' + projectUrl);

        // Add a couple clips (to be asynchronously processed)
        const promiseArray = [];
        promiseArray.push(
            createClip({
                "path": "media-files/MyVideo.mp4",
                "position": 0.0,
                "end": 10.0
            }));
        promiseArray.push(
            createClip({
                "path": "media-files/MyAudio.mp4",
                "position": 0.0,
                "end": 10.0
            }));
        promiseArray.push(
            createClip({
                "path": "media-files/Watermark.JPG",
                "position": 0.0,
                "end": 10.0,
                "layer": 2
            }));

        // Wait until all files and clips are uploaded
        Promise.all(promiseArray).then(function(responseArray){
            // Export as a new video
            exportData = {
                "export_type": "video",
                "video_format": "mp4",
                "video_codec": "libx264",
                "video_bitrate": 8000000,
                "audio_codec": "ac3",
                "audio_bitrate": 1920000,
                "project": projectUrl,
                "json": '{}'
            };
            post('/exports/', exportData)
                .then(function(response){
                    // Export has been created and will begin processing soon
                    var exportUrl = JSON.parse(response).url;
                    exportId = JSON.parse(response).id;
                    console.log('Successfully created export: ' + exportUrl);

                    // Poll until the export has finished
                    var poller = promisePoller({
                        taskFn: isExportCompleted,
                        interval: 1000,
                        retries: 60*60*1000,
                        timeout: 2000
                    }).then(function(exportOutputUrl) {
                        // New exported video is ready for download now
                        console.log('Download ' + exportOutputUrl);
                        request(exportOutputUrl).pipe(fs.createWriteStream('Output-' + projectId + '.mp4'));
                    });
                });
        });
    });

function isExportCompleted() {
    return new Promise(function (resolve, error) {

        get('/exports/' + exportId + '/', {})
            .then(function(response) {
                var exportStatus = JSON.parse(response).status;
                var exportOutputUrl = JSON.parse(response).output;
                if (exportStatus == 'completed') {
                    console.log('Export completed: ' + JSON.stringify(response));
                    resolve(exportOutputUrl);
                }
            });
    });
}

function createClip(clip) {
    // Create new File object (and upload file from filesystem)
    var fileData = {
        'json': '{}',
        'project': projectUrl,
        'media': fs.createReadStream(clip.path)
    };

    return new Promise(function (resolve) {
        post('/files/', fileData)
            .then(function(response) {
                // File uploaded and object created
                var fileUrl = JSON.parse(response).url;
                console.log('Successfully created file: ' + fileUrl);

                // Now we need to add a clip which references this new File object
                var clipData = {
                    'file': fileUrl,
                    'json': '{}',
                    'position': clip.position || 0.0,
                    'start': clip.start || 0.0,
                    'end': clip.end || JSON.parse(response).json.duration,
                    'layer': clip.layer || 0,
                    'project': projectUrl
                };
                return post('/clips/', clipData).then(function(response){
                    var clipUrl = JSON.parse(response).url;
                    console.log('Successfully created clip: ' + clipUrl);
                    resolve();
                });
            });
    });
}

function post(endpoint, data) {
    // Prepare request object and POST data to OpenShot API
    const r = request.post(protocol + '://' + auth.user + ':' + auth.pass + '@' + server + endpoint, function (err, response, body) {
        if (err) {
            return err;
        } else {
            console.log(response.statusCode + ': ' + body);
            return body;
        }
    });

    // Append form data to request form-data
    const form_data = r.form();
    for ( var key in data ) {
        form_data.append(key, data[key]);
    }
    return r;
}

function get(endpoint, data) {
    // Prepare request object and GET data to OpenShot API
    return request.get(protocol + '://' + auth.user + ':' + auth.pass + '@' + server + endpoint, function (err, response, body) {
        if (err) {
            return err;
        } else {
            console.log(response.statusCode + ': ' + body);
            return body;
        }
    });
}

C# Example Script

Here is a simple example client script, using C# (.NET version: 5.0.103). It connects, creates a new project, uploads a file, creates a clips, exports a video, and then prints the new video file link. It should give you a good sense of how things work in C# (This code has been made synchronous on purpose). Learn more about the API Endpoints / Schema. This also uses 2 NuGet packages: Newtonsoft, MimeMapping

using System;
using System.Collections.Generic;
using System.Threading;
using System.Net.Http;
using System.Net.Http.Headers;
using System.IO;

using Newtonsoft.Json.Linq;
using MimeMapping;

 namespace OpenShot
 {
     class Program
     {
         static void Main(string[] args)
         {
             String MakeGetRequest(string url, HttpClient client)
             {
                 Console.WriteLine("GET: " + url);
                 var response = client.GetAsync(url).GetAwaiter().GetResult();
                 Console.WriteLine("Response StatusCode: " + (int)response.StatusCode);

                 if (response.IsSuccessStatusCode){
                     return response.Content.ReadAsStringAsync().GetAwaiter().GetResult();;
                 }else{
                     Console.WriteLine("Request Failed with message:" +
                     response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
                 }
                 return "";
             }
             String MakePostRequest(string url, Dictionary<string, string> formData, HttpClient client)
             {
                 var requestContent = new FormUrlEncodedContent(formData);
                 Console.WriteLine("POST: " + url);
                 var response = client.PostAsync(url, requestContent).GetAwaiter().GetResult();
                 Console.WriteLine("Response StatusCode: " + (int)response.StatusCode);

                 if (response.IsSuccessStatusCode){
                     return response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                 }else{
                     Console.WriteLine("Request Failed with message:" +
                     response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
                 }
                 return "";
             }
             String MakePostRequestWithFile(string url, Dictionary<string, string> formData, HttpClient client, FileInfo fileInfo)
             {
                 var requestContent = new MultipartFormDataContent();
                 var fileContent = new StreamContent(fileInfo.OpenRead());
                 fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                     {
                         Name = "\"media\"",
                         FileName = "\"" + fileInfo.Name + "\""
                     };
                 fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MimeMapping.MimeUtility.GetMimeMapping(fileInfo.Name));

                 foreach (KeyValuePair<string, string> kvp in formData)
                 {
                     requestContent.Add(new StringContent(kvp.Value), kvp.Key);
                 }

                 requestContent.Add(fileContent);
                 Console.WriteLine("POST: " + url);
                 var response = client.PostAsync(url, requestContent).GetAwaiter().GetResult();
                 Console.WriteLine("Response StatusCode: " + (int)response.StatusCode);

                 if (response.IsSuccessStatusCode){
                     return response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                 }else{
                     Console.WriteLine("Request Failed with message:" +
                     response.Content.ReadAsStringAsync().GetAwaiter().GetResult());
                 }
                 return "";
             }
             HttpClient client = new HttpClient();

             // Connection info
             string serverUrl = "http://cloud.openshot.org/";

             // Basic Auth
             String username = "demo-cloud";
             String password = "demo-password";
             String encoded = System.Convert.ToBase64String(
                 System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(
                     username + ":" + password));

             client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", encoded);

             ////////////////////////////////////////////////////////////////////////////////////////
             // Get list of projects
             Console.WriteLine("\n Get list of projects \n");
             String responseGetRequest = MakeGetRequest(serverUrl + "projects/", client);
             Console.WriteLine(responseGetRequest);

             ////////////////////////////////////////////////////////////////////////////////////////
             // Create new project
             Console.WriteLine("\n Create new project \n");
             Dictionary<string, string> payload = new Dictionary<string, string>
             {
                 { "name", "API Project" },
                 { "width", "1920" },
                 {"height", "1080"},
                 {"fps_num", "30"},
                 {"fps_den", "1"},
                 {"sample_rate", "44100"},
                 {"channels", "2"},
                 {"channel_layout", "3"},
                 {"json", "{}" }
             };
             String responsePostRequest = MakePostRequest(serverUrl + "projects/", payload, client);

             Console.WriteLine(responsePostRequest);
             dynamic jsonObj = JObject.Parse(responsePostRequest);

             Int32 projectId = jsonObj.id;
             String projectUrl = jsonObj.url;
             Console.WriteLine("Project ID: " + projectId);
             Console.WriteLine("Project URL: "+ projectUrl);

             ////////////////////////////////////////////////////////////////////////////////////////
             // Upload file to project
             Console.WriteLine("\n Upload file to project \n");
             payload = new Dictionary<string, string>
             {
                 {"media", ""},
                 {"project", projectUrl},
                 {"json", "{}" }
             };
             String filePath = "D:\\test-file.mp4";

             responsePostRequest = MakePostRequestWithFile(
                 projectUrl + "files/",
                 payload,
                 client,
                 new FileInfo(filePath)
             );
             Console.WriteLine(responsePostRequest);
             jsonObj = JObject.Parse(responsePostRequest);
             String fileUrl = jsonObj.url;
             Console.WriteLine("File URL:" + fileUrl);

             ////////////////////////////////////////////////////////////////////////////////////////
             // Create a clip for the previously uploaded file
             Console.WriteLine("\n Create a clip for the previously uploaded file \n");
             payload = new Dictionary<string, string>
             {
                 {"file", fileUrl},
                 {"position", "0.0"},
                 {"start", "0.0"},
                 {"end", "2.0"},
                 {"layer", "1"},
                 {"project", projectUrl},
                 {"json", "{}"}
             };

             responsePostRequest = MakePostRequest(projectUrl + "clips/", payload, client);
             Console.WriteLine(responsePostRequest);

             ////////////////////////////////////////////////////////////////////////////////////////
             // Create export for final rendered video
             Console.WriteLine("\n Create export for final rendered video \n");
             payload = new Dictionary<string, string>
             {
                 {"video_format", "mp4"},
                 {"video_codec", "libx264"},
                 {"video_bitrate", "8000000"},
                 {"audio_codec", "ac3"},
                 {"audio_bitrate", "1920000"},
                 {"start_frame", "1"},
                 {"end_frame", ""},
                 {"project", projectUrl},
                 {"json", "{}"}
             };

             responsePostRequest = MakePostRequest(projectUrl + "exports/", payload, client);
             Console.WriteLine(responsePostRequest);
             jsonObj = JObject.Parse(responsePostRequest);

             String exportUrl = jsonObj.url;
             Boolean isExported = false;
             Int16 countdown = 500;

             while (!isExported && countdown > 1){
                 String responseExportGetRequest = MakeGetRequest(exportUrl, client);
                 jsonObj = JObject.Parse(responseExportGetRequest);
                 String progress = jsonObj.progress;

                 if (progress != null && progress !=""){
                     float progressFloat = float.Parse(progress);
                     if (progressFloat == 100.0){
                         isExported = true;
                     }
                 }
                 countdown -= 1;
                 Thread.Sleep(5000);
             }

             responseGetRequest = MakeGetRequest(exportUrl, client);
             jsonObj = JObject.Parse(responseGetRequest);
             Console.WriteLine(responseGetRequest);
             Console.WriteLine("Export Successfully Completed: " + jsonObj.output);
         }
     }
 }