Video API

Welcome to the Microsoft Project Oxford Video API. Video API is a cloud-based API that provides advanced algorithms for tracking faces, detecting motion, and stabilizing video. These APIs allow you to build more personalized and intelligent apps by understanding and automatically transforming your video content.

Motion Detection

Detects motion in a video, and returns the frame and duration of the motion that was captured.
• The supported input video formats include MP4, MOV, and WMV. Video file size should be no larger than 100MB.
• User can input detection zones to set up as areas to detect motion.
• User can specify motion sensitivity: high, medium, and low. Higher sensitivity means more motions will be detected at a cost that more false alarms will be reported.
• Motion Detection is optimized for stationary background videos.
• User can specify whether light change events should be detected. A light change refers to a change in the frame that was caused by a light turning off and on. Some developers do not want to detect this, as they consider it a false alarm. Other developers want to make sure they capture any change, light changes included.
• User can specify whether successive motions should be merged together by passing in a parameter (mergeTimeThreshold) For example, if a motion happens from 1 to 4 seconds and the next motion happens from 5 to 10 seconds, some developers will want to count that as one instance of motion.
• User can specify which frames to be detected by passing in a parameter (frameSamplingValue).
• Some motion may not be detected due to technical challenges; e.g. semi-transparent objects, and some small objects.
• Output files are deleted after 24 hours.

Open API testing console

Request URL

Request parameters

(optional)
string

Specify the detection sensitivity level: “low”, “medium”, “high”. Higher sensitivity means more motions will be detected at a cost that more false alarms will be reported. The default value is “medium”.

(optional)
number

User may skip frames by setting this parameter. It can be used as a tradeoff between performance and cost, skipping frames may reduce processing time but result in worse detection performance. The default value is 1, meaning detecting motion for every frame. If set to 2, then the algorithm will detect one frame for every two frames. The upper bound is 20.

(optional)
string

User can setup detection zones by passing in a string like “detectionZones=0,0;0.5,0;1,0;1,0.5;1,1;0.5,1;0,1;0,0.5 |0.3,0.3;0.55,0.3;0.8,0.3; 0.8,0.55;0.8,0.8;0.55,0.8;0.3,0.8;0.3,0.55;| 0,0;1,0;1,1;0,1”, each detection zone is separated by a “|” and each point is defined by a “x,y” pair and separated by a “;”. At most 8 detection zones are supported and each detection zone should be defined by at least 3 points and no more than 16 points. The default setting is “detectionZones=0,0;0.5,0;1,0;1,0.5;1,1;0.5,1;0,1;0,0.5”, i.e. the whole frame defined by an 8-point polygon.

(optional)
boolean

Specify whether light change events should be detected. The default value is false.

(optional)
number

Specify the threshold on whether successive motions should be merged together, if the interval between successive motions is <= mergeTimeThreshold, they will be merged. The default value is 0.0 and upper bound is 10.0.

Request headers

(optional)
string
Media type of the body sent to the API.
string
Subscription key which provides access to this API. Found in your Cognitive Services accounts.

Request body

{
	"url":"http://www.example.com/sample.mp4"
}
[binary video data]

Response 202

The service has accepted the request and will start the process later.
In the response, there is a "Operation-Location" header. Client side should further query the operation status from the URL specified in this header.

Operation-LocationClient side should use this URL to query video operation status/result.
Example: https://api.projectoxford.ai/video/v1.0/operations/EF217D0C-9085-45D7-AAE0-2B36471B89B5 .

Response 400

Error code and message returned in JSON:

Error CodeDescription
InvalidVideoSizeVideo size is too small or too big.
BadArgumentFailed to deserialize JSON request.

{
   "error":
             {
                 "code":"InvalidVideoSize",
                 "message":"Video size is too small or too big."
             }
}

Response 415

When Content-Type is not application/json or application/octet-stream.

Response 401

Access denied due to invalid subscription key.

{
    "error":{
        "code": "Unauthorized",
        "message": "Access denied due to invalid subscription key. Make sure to provide a valid key for an active subscription." 
    }
}

Response 403

Quota limit exceeded.

{
    "error":{
        "code": "QuotaLimitExceeded",
        "message": "Out of call volume quota. Quota will be replenished later." 
    }
}

Response 429

Rate limit exceeded.

{
    "error":{
        "code": "RateLimitExceeded",
        "message": "Rate limit is exceeded. Try again later." 
    }
}

Code samples

@ECHO OFF

curl -v -X POST "https://westus.api.cognitive.microsoft.com/video/v1.0/detectmotion?sensitivityLevel={string}&frameSamplingValue={number}&detectionZones={string}&detectLightChange={boolean}&mergeTimeThreshold={number}"
-H "Content-Type: application/json"
-H "Ocp-Apim-Subscription-Key: {subscription key}"

--data-ascii "{body}" 
using System;
using System.Net.Http.Headers;
using System.Text;
using System.Net.Http;
using System.Web;

namespace CSHttpClientSample
{
    static class Program
    {
        static void Main()
        {
            MakeRequest();
            Console.WriteLine("Hit ENTER to exit...");
            Console.ReadLine();
        }
        
        static async void MakeRequest()
        {
            var client = new HttpClient();
            var queryString = HttpUtility.ParseQueryString(string.Empty);

            // Request headers
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "{subscription key}");

            // Request parameters
            queryString["sensitivityLevel"] = "{string}";
            queryString["frameSamplingValue"] = "{number}";
            queryString["detectionZones"] = "{string}";
            queryString["detectLightChange"] = "{boolean}";
            queryString["mergeTimeThreshold"] = "{number}";
            var uri = "https://westus.api.cognitive.microsoft.com/video/v1.0/detectmotion?" + queryString;

            HttpResponseMessage response;

            // Request body
            byte[] byteData = Encoding.UTF8.GetBytes("{body}");

            using (var content = new ByteArrayContent(byteData))
            {
               content.Headers.ContentType = new MediaTypeHeaderValue("< your content type, i.e. application/json >");
               response = await client.PostAsync(uri, content);
            }

        }
    }
}	
// // This sample uses the Apache HTTP client from HTTP Components (http://hc.apache.org/httpcomponents-client-ga/)
import java.net.URI;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class JavaSample 
{
    public static void main(String[] args) 
    {
        HttpClient httpclient = HttpClients.createDefault();

        try
        {
            URIBuilder builder = new URIBuilder("https://westus.api.cognitive.microsoft.com/video/v1.0/detectmotion");

            builder.setParameter("sensitivityLevel", "{string}");
            builder.setParameter("frameSamplingValue", "{number}");
            builder.setParameter("detectionZones", "{string}");
            builder.setParameter("detectLightChange", "{boolean}");
            builder.setParameter("mergeTimeThreshold", "{number}");

            URI uri = builder.build();
            HttpPost request = new HttpPost(uri);
            request.setHeader("Content-Type", "application/json");
            request.setHeader("Ocp-Apim-Subscription-Key", "{subscription key}");


            // Request body
            StringEntity reqEntity = new StringEntity("{body}");
            request.setEntity(reqEntity);

            HttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();

            if (entity != null) 
            {
                System.out.println(EntityUtils.toString(entity));
            }
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}

<!DOCTYPE html>
<html>
<head>
    <title>JSSample</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>
<body>

<script type="text/javascript">
    $(function() {
        var params = {
            // Request parameters
            "sensitivityLevel": "{string}",
            "frameSamplingValue": "{number}",
            "detectionZones": "{string}",
            "detectLightChange": "{boolean}",
            "mergeTimeThreshold": "{number}",
        };
      
        $.ajax({
            url: "https://westus.api.cognitive.microsoft.com/video/v1.0/detectmotion?" + $.param(params),
            beforeSend: function(xhrObj){
                // Request headers
                xhrObj.setRequestHeader("Content-Type","application/json");
                xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","{subscription key}");
            },
            type: "POST",
            // Request body
            data: "{body}",
        })
        .done(function(data) {
            alert("success");
        })
        .fail(function() {
            alert("error");
        });
    });
</script>
</body>
</html>
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
    NSString* path = @"https://westus.api.cognitive.microsoft.com/video/v1.0/detectmotion";
    NSArray* array = @[
                         // Request parameters
                         @"entities=true",
                         @"sensitivityLevel={string}",
                         @"frameSamplingValue={number}",
                         @"detectionZones={string}",
                         @"detectLightChange={boolean}",
                         @"mergeTimeThreshold={number}",
                      ];
    
    NSString* string = [array componentsJoinedByString:@"&"];
    path = [path stringByAppendingFormat:@"?%@", string];

    NSLog(@"%@", path);

    NSMutableURLRequest* _request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:path]];
    [_request setHTTPMethod:@"POST"];
    // Request headers
    [_request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [_request setValue:@"{subscription key}" forHTTPHeaderField:@"Ocp-Apim-Subscription-Key"];
    // Request body
    [_request setHTTPBody:[@"{body}" dataUsingEncoding:NSUTF8StringEncoding]];
    
    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData* _connectionData = [NSURLConnection sendSynchronousRequest:_request returningResponse:&response error:&error];

    if (nil != error)
    {
        NSLog(@"Error: %@", error);
    }
    else
    {
        NSError* error = nil;
        NSMutableDictionary* json = nil;
        NSString* dataString = [[NSString alloc] initWithData:_connectionData encoding:NSUTF8StringEncoding];
        NSLog(@"%@", dataString);
        
        if (nil != _connectionData)
        {
            json = [NSJSONSerialization JSONObjectWithData:_connectionData options:NSJSONReadingMutableContainers error:&error];
        }
        
        if (error || !json)
        {
            NSLog(@"Could not parse loaded json with error:%@", error);
        }
        
        NSLog(@"%@", json);
        _connectionData = nil;
    }
    
    [pool drain];

    return 0;
}
<?php
// This sample uses the Apache HTTP client from HTTP Components (http://hc.apache.org/httpcomponents-client-ga/)
require_once 'HTTP/Request2.php';

$request = new Http_Request2('https://westus.api.cognitive.microsoft.com/video/v1.0/detectmotion');
$url = $request->getUrl();

$headers = array(
    // Request headers
    'Content-Type' => 'application/json',
    'Ocp-Apim-Subscription-Key' => '{subscription key}',
);

$request->setHeader($headers);

$parameters = array(
    // Request parameters
    'sensitivityLevel' => '{string}',
    'frameSamplingValue' => '{number}',
    'detectionZones' => '{string}',
    'detectLightChange' => '{boolean}',
    'mergeTimeThreshold' => '{number}',
);

$url->setQueryVariables($parameters);

$request->setMethod(HTTP_Request2::METHOD_POST);

// Request body
$request->setBody("{body}");

try
{
    $response = $request->send();
    echo $response->getBody();
}
catch (HttpException $ex)
{
    echo $ex;
}

?>
########### Python 2.7 #############
import httplib, urllib, base64

headers = {
    # Request headers
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-Key': '{subscription key}',
}

params = urllib.urlencode({
    # Request parameters
    'sensitivityLevel': '{string}',
    'frameSamplingValue': '{number}',
    'detectionZones': '{string}',
    'detectLightChange': '{boolean}',
    'mergeTimeThreshold': '{number}',
})

try:
    conn = httplib.HTTPSConnection('westus.api.cognitive.microsoft.com')
    conn.request("POST", "/video/v1.0/detectmotion?%s" % params, "{body}", headers)
    response = conn.getresponse()
    data = response.read()
    print(data)
    conn.close()
except Exception as e:
    print("[Errno {0}] {1}".format(e.errno, e.strerror))

####################################

########### Python 3.2 #############
import http.client, urllib.request, urllib.parse, urllib.error, base64

headers = {
    # Request headers
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-Key': '{subscription key}',
}

params = urllib.parse.urlencode({
    # Request parameters
    'sensitivityLevel': '{string}',
    'frameSamplingValue': '{number}',
    'detectionZones': '{string}',
    'detectLightChange': '{boolean}',
    'mergeTimeThreshold': '{number}',
})

try:
    conn = http.client.HTTPSConnection('westus.api.cognitive.microsoft.com')
    conn.request("POST", "/video/v1.0/detectmotion?%s" % params, "{body}", headers)
    response = conn.getresponse()
    data = response.read()
    print(data)
    conn.close()
except Exception as e:
    print("[Errno {0}] {1}".format(e.errno, e.strerror))

####################################
require 'net/http'

uri = URI('https://westus.api.cognitive.microsoft.com/video/v1.0/detectmotion')
uri.query = URI.encode_www_form({
    # Request parameters
    'sensitivityLevel' => '{string}',
    'frameSamplingValue' => '{number}',
    'detectionZones' => '{string}',
    'detectLightChange' => '{boolean}',
    'mergeTimeThreshold' => '{number}'
})

request = Net::HTTP::Post.new(uri.request_uri)
# Request headers
request['Content-Type'] = 'application/json'
# Request headers
request['Ocp-Apim-Subscription-Key'] = '{subscription key}'
# Request body
request.body = "{body}"

response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    http.request(request)
end

puts response.body