Products

SIGN UPLOG IN

Video Moderation / Stored Video Moderation

Stored Video Moderation sync

Introduction

Moderating a stored video with the synchronous moderation API is quick and easy:

  1. Your back-end submits a video to Sightengine through an API request
  2. Sightengine analyzes the video and sends back the detailed moderation results in the request response

Everything happens within a single API request cycle.

Since this has to fit within a single API request cycle, this approach will only work for videos that are less than 60 seconds long. To moderate longer videos, use the Asynchronous Video Moderation.

Get API access credentials

The Sightengine API uses a key pair that consists of an API user id and an API secret for authentication. To get your own API credentials, create an account and go the the API key page to retrieve them.

Pick your Moderation Models

Sightengine has a long list of moderation models that you can pick and choose from. A model is a video recognition engine that has been designed to spot certain types of unwanted content.

Here are our most popular models video moderation:

nudity-2.0

Detect all types of nudity and sexual content. Pornography, X-rated nudity, partial nudity, suggestive scenes and poses, lingerie... More

offensive

Detect offensive and hateful signs, symbols, flags and gestures. More

wad

Detect weapons, firearms and threatening knives More

face-attributes

Detect faces along with their main attributes: gender, age...

gore

Detect horrific imagery including scenes with blood, wounds, self-harm, guts... More

wad

Detect recreational and medical drugs More

gambling

Detect gambling, casinos, slot machines... More

tobacco

Detect smoking and tobacco products More

money

Detect displays of money and banknotes More

The full list of models along with details is available in the Model Reference.

Submit a Video to Sightengine

There are two ways to submit a video for Moderation:

  • Via raw bytes upload (you send the video file to our API). This is usually the best solution if you have a stored video that is not available through a public URL.
  • Via a public URL (you send a URL pointing to your video).

Moderate by uploading the Video


curl -X POST 'https://api.sightengine.com/1.0/video/check-sync.json' \
  -F 'media=@/path/to/video' \
  -F 'models=nudity-2.0' \
  -F 'api_user={api_user}' \
  -F 'api_secret={api_secret}'


# this example uses requests
import requests
import json

params = {
  # specify the models you want to apply
  'models': 'nudity-2.0',
  'api_user': '{api_user}',
  'api_secret': '{api_secret}'
}
files = {'media': open('/path/to/video', 'rb')}
r = requests.post('https://api.sightengine.com/1.0/video/check-sync.json', files=files, data=params)

output = json.loads(r.text)


$params = array(
  'media' => new CurlFile('/path/to/video'),
  // specify the models you want to apply
  'models' => 'nudity-2.0',
  'api_user' => '{api_user}',
  'api_secret' => '{api_secret}',
);

// this example uses cURL
$ch = curl_init('https://api.sightengine.com/1.0/video/check-sync.json');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($ch);
curl_close($ch);

$output = json_decode($response, true);


// this example uses axios and form-data
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

data = new FormData();
data.append('media', fs.createReadStream('/path/to/video'));
// specify the models you want to apply
data.append('models', 'nudity-2.0');
data.append('api_user', '{api_user}');
data.append('api_secret', '{api_secret}');

axios({
  method: 'post',
  url:'https://api.sightengine.com/1.0/video/check-sync.json',
  data: data,
  headers: data.getHeaders()
})
.then(function (response) {
  // on success: handle response
  console.log(response.data);
})
.catch(function (error) {
  // handle error
  if (error.response) console.log(error.response.data);
  else console.log(error.message);
});

Moderate by submitting a Video URL


curl -X GET -G 'https://api.sightengine.com/1.0/video/check-sync.json' \
  --data-urlencode 'stream_url=https://yourvideo/path' \
  -d 'models=nudity-2.0' \
  -d 'api_user={api_user}' \
  -d 'api_secret={api_secret}'


# if you haven't already, install the SDK with "pip install sightengine"
from sightengine.client import SightengineClient
client = SightengineClient('{api_user}', '{api_secret}')
output = client.check('nudity-2.0').video_sync('https://yourvideo/path')


// if you haven't already, install the SDK with "composer require sightengine/client-php"
use \Sightengine\SightengineClient;
$client = new SightengineClient('{api_user}', '{api_secret}');
$output = $client->check(['nudity-2.0'])->video_sync('https://yourvideo/path');


// if you haven't already, install the SDK with "npm install sightengine --save"
var sightengine = require('sightengine')('{api_user}', '{api_secret}');
sightengine.check(['nudity-2.0']).video_sync('https://yourvideo/path').then(function(result) {
  // The API response (result)
}).catch(function(err) {
  // Handle error
});

Please note that you will have to choose the models you wish to apply to your video, and make sure you have an API user and API secret. You can get those from your dashboard.

Keep in mind that it can take a bit of time to process a video. You should therefore make sure that your request timeout settings allow for long request times. We recommend a timeout setting of 60s or more.
Otherwise you can use the Asynchronous Video Moderation to let the moderation happen asynchronously (outside of the API request cycle).

Moderation results

The Moderation API will download your video and then immediately start analyzing it. The request to the API will remain open while processing goes on and as soon as this processing has finished the API will return the full moderation results and close the connection.

Here is an example JSON response for Nudity Detection:

            
            
{
    "status": "success",
    "request": {
        "id": "req_1ML249NoEZ8j12op9Lipg",
        "timestamp": 1508774201.3177
    },
    "media": {
        "id": "med_1ML2wKmVgucuNPBN6xT33",
        "uri": "funfair.mp4"
    },
    "data": {
      "frames" : [
        {
          "info": {
              "id": "med_1ML2wKmVgucuNPBN6xT33_1",
              "position": 0
          },
          "nudity": {
            "sexual_activity": 0.01,
            "sexual_display": 0.01,
            "erotica": 0.01,
            "sextoy": 0.01,
            "suggestive": 0.01,
            "suggestive_classes": {
              "bikini": 0.01,
              "cleavage": 0.01,
              "cleavage_categories": {
                "very_revealing": 0.01,
                "revealing": 0.01,
                "none": 0.99
              },
              "male_chest": 0.01,
              "male_chest_categories": {
                "very_revealing": 0.01,
                "revealing": 0.01,
                "slightly_revealing": 0.01,
                "none": 0.99
              },
              "male_underwear": 0.01,
              "lingerie": 0.01,
              "miniskirt": 0.01,
              "other": 0.01
            }, 
            "none": 0.99,
            "context": {
              "sea_lake_pool": 0.01,
              "outdoor_other": 0.99,
              "indoor_other": 0.01
            }
          }
        },
        {
          "info": {
              "id": "med_1ML2wKmVgucuNPBN6xT33_2",
              "position": 2000
          },
          "nudity": {
            "sexual_activity": 0.01,
            "sexual_display": 0.01,
            "erotica": 0.01,
            "sextoy": 0.01,
            "suggestive": 0.01,
            "suggestive_classes": {
              "bikini": 0.01,
              "cleavage": 0.01,
              "cleavage_categories": {
                "very_revealing": 0.01,
                "revealing": 0.01,
                "none": 0.99
              },
              "male_chest": 0.01,
              "male_chest_categories": {
                "very_revealing": 0.01,
                "revealing": 0.01,
                "slightly_revealing": 0.01,
                "none": 0.99
              },
              "male_underwear": 0.01,
              "lingerie": 0.01,
              "miniskirt": 0.01,
              "other": 0.01
            }, 
            "none": 0.99,
            "context": {
              "sea_lake_pool": 0.01,
              "outdoor_other": 0.99,
              "indoor_other": 0.01
            }
          }
        }
      ]
    }
}
            
        

Was this page helpful?