Create And Upload MediaObjects

Create a MediaObject and upload its native media

When uploading a file via the Limecraft Flow UI in the browser, a MediaObject will be created and the bytes uploaded will be assumed to represent the native media of the MediaObject. This section explains the steps involved in this process.

Create a MediaObject

We start the upload by doing a POST call and passing it at least the name, size and fileName properties of the file we want to upload.

POST /production/{prId}/mo

{
    "size": 184915, // this is in bytes
    "fileName": "1.mp4", // name of the file with a relevant path to it
}

In the resulting object, you will find location parameter, which can be used to do the actual upload of the clip. After a successful upload, the user finishes up by sending the close upload call.

The resulting object also contains a workflowId parameter, which is the id of the Ingest workflow which will process the media once it is uploaded.

Besides size and fileName, more options exists. See MediaObjectRequest for a full overview. These are the most important ones for a basic upload:

Field Description

fileName

The name of the file.

size

The size in bytes.

attachToEoId

Can contain the id of the EditorialObject (subcollection) the upload should be attached to.

Send data

The call in Create a MediaObject returned a JSON object which had a location field. Now we start uploading chunks of data through PUT`s to this `location.

We advise you to upload the file in chunks to avoid timeouts. Depending on your connection speed, choose a chunk size between 1MB and 100MB.

Per chunk of data, you perform a PUT to location (Content-Type:application/octet-stream). Use a query parameter position to indicate the byte position from which you are sending. In pseudo-code:

# configuration
chunkSize = 5 * 1024 * 1024        # 5 MB (choose between 1 MB and 100 MB)

file = openFile("path/to/file")
fileSize = file.getSize()

bytePosition = 0

while bytePosition < fileSize:

    # determine actual size of this chunk
    remainingBytes = fileSize - bytePosition
    currentChunkSize = min(chunkSize, remainingBytes)

    # read a slice of the file to use as the PUT body
    chunk = file.readSlice(
        start = bytePosition,
        length = currentChunkSize
    )

    # send the chunk
    PUT {{uploadLocation}}?position={{bytePosition}}
        Headers:
            Content-Type: application/octet-stream
            Content-Length: currentChunkSize
        Body:
            chunk   # <-- binary slice of the file

    # advance to next position
    bytePosition += currentChunkSize

# loop exits when the entire file has been uploaded
...

The chunk size does not have to be the same for each PUT. It can be adapted to the network conditions. The Limecraft Flow web application starts with a chunk size of 5MB and adjusts the chunk size so it takes about 20s to upload a chunk.

When a PUT fails, it can be executed again (so only that chunk has to be uploaded again). This is, besides avoiding timeouts, another argument for not choosing the chunk size too large. But also don’t make the chunks too slow as it comes with some network overhead, starting a new chunk slows the upload down a bit.

Close the upload

POST /production/{prId}/mo/{id}/close

This API call will consider the upload to be finished.

Details
Description

This will automatically trigger the default ingest workflow.

Parameters
Path Parameters
Name Description Required Type

prId

ID of the production.

✔

Long

id

ID of the MediaObject.

✔

Long

Body Parameters
Name Description Required Type

CloseRequest

✘

CloseRequest

CloseRequest

Field Name Required Type Description Format

skipIngest

✘

Boolean

skipVerification

✘

Boolean

Return Type

MediaObject

Field Name Required Type Description Format

annotations

✘

Set of Annotation

created

✘

Date

The time when this resource was created

date-time

createdBy

✘

String

The request or process that created this resource

createdByShareId

✘

Long

int64

createdBySharedUserId

✘

Long

int64

creatorId

✘

Long

The id of the user who created this resource

int64

deleted

✘

Date

date-time

duration

✘

Long

int64

durationSeconds

✘

Double

double

growing

✘

Boolean

id

✔

Long

The id of this resource

int64

keyFrame

✘

Long

int64

lastUpdated

✘

Date

The time when this resource was last updated

date-time

mediaObjectInstances

✘

Set of MediaObjectInstance

modifiedBy

✔

String

The request or process responsible for the last update of this resource

name

✘

String

objectType

✘

String

The data model type or class name of this resource

packageId

✘

Long

int64

productionId

✘

Long

int64

proxyOnline

✘

Boolean

sampleRate

✘

SampleRate

timecode

✘

SMPTETimePoint

timecodeFrames

✘

Long

int64

tracks

✘

Set of MediaObjectTrack

type

✘

String

Enum: IMAGE, DOCUMENT, PENDING, AUDIO, VIDEO, SNIPPET, PACKAGE,

umid

✘

String

version

✔

Long

The version of this resource, used for Optimistic Locking

int64

wfr

✘

Set of MediaObjectWorkflowReport

workflowId

✘

String

Content Type
  • application/json

Responses
Table 1. http response codes
Code Description Datatype

201

The request was successful.

MediaObject

403

The user needs LIBRARY_UPLOAD or SharePermission.UPLOAD rights.

ForbiddenError

404

The production or media object was not found.

NotFoundError

412

The upload was not complete.

IncompleteUploadError

Closing the upload tells the API it should no longer expect more bytes to come in. The file is complete. This will usually start the Ingest workflow.

Cancel upload

POST /production/{prId}/mo/{id}/cancel

__

Details
Description
Parameters
Path Parameters
Name Description Required Type

prId

✔

Long

id

✔

Long

Return Type

MediaObject

Field Name Required Type Description Format

annotations

✘

Set of Annotation

created

✘

Date

The time when this resource was created

date-time

createdBy

✘

String

The request or process that created this resource

createdByShareId

✘

Long

int64

createdBySharedUserId

✘

Long

int64

creatorId

✘

Long

The id of the user who created this resource

int64

deleted

✘

Date

date-time

duration

✘

Long

int64

durationSeconds

✘

Double

double

growing

✘

Boolean

id

✔

Long

The id of this resource

int64

keyFrame

✘

Long

int64

lastUpdated

✘

Date

The time when this resource was last updated

date-time

mediaObjectInstances

✘

Set of MediaObjectInstance

modifiedBy

✔

String

The request or process responsible for the last update of this resource

name

✘

String

objectType

✘

String

The data model type or class name of this resource

packageId

✘

Long

int64

productionId

✘

Long

int64

proxyOnline

✘

Boolean

sampleRate

✘

SampleRate

timecode

✘

SMPTETimePoint

timecodeFrames

✘

Long

int64

tracks

✘

Set of MediaObjectTrack

type

✘

String

Enum: IMAGE, DOCUMENT, PENDING, AUDIO, VIDEO, SNIPPET, PACKAGE,

umid

✘

String

version

✔

Long

The version of this resource, used for Optimistic Locking

int64

wfr

✘

Set of MediaObjectWorkflowReport

workflowId

✘

String

Content Type
  • application/json

Responses
Table 2. http response codes
Code Description Datatype

0

default response

MediaObject

If the user wants to stop uploading (and immediately delete the clip), use the cancel call instead of the close call.

Wait for the Ingest workflow to finish

After the upload completes, the Ingest workflow will start processing the uploaded data. Its type, duration and other media properties are detected, versions are created which can be visualized in a browser, etc. Before continuing with the MediaObject, it is advised to wait for the Ingest workflow to complete.

For more info on workflows, please refer to the Workflow section.

GET /production/{prId}/{alias}/{id}/progress

This is a generic workflow progress monitor call, which can be used to monitor the ingest workflow in particular, but all other workflows as well.

Details
Description

Wait for the given workflow to finish.

Parameters
Path Parameters
Name Description Required Type

alias

Either workflow or workflowReport. Both are aliases of each other.

✔

String

prId

ID of the production.

✔

Long

id

ID of the workflow.

✔

String

Return Type

String

Content Type
  • application/json

Responses
Table 3. http response codes
Code Description Datatype

200

The request was successful.

String

403

The user needs PRODUCTION_VIEW rights.

ForbiddenError

404

The production or workflow was not found.

NotFoundError

Remember that the Create a MediaObject call returned a workflowId field on its response, which is the id of the workflow we want to wait for.

Create a placeholder MediaObject without uploading media

It is also possible to only create the MediaObject, without uploading any media. We again do the same POST call, but now we do not pass the fileName and size parameters. The API interprets this as "I shouldn’t expect an upload for this".

A simple placeholder

POST /production/{prId}/mo

{
  "name": "My super clip"
}
POST /production/{prId}/mo

This API call creates a placeholder or prepares for an upload depending on the presence of the fileName/size properties.

Details
Description
Parameters
Path Parameters
Name Description Required Type

prId

ID of the production.

✔

Long

Body Parameters
Name Description Required Type

MediaObjectRequest

Media object.

✘

MediaObjectRequest

MediaObjectRequest

Field Name Required Type Description Format

acceptedType

✘

String

accessToken

✘

String

annotations

✘

Set of object

attachToEdlId

✘

Long

int64

attachToEoId

✘

Long

int64

circled

✘

Boolean

clipMetadata

✘

Object

cloud

✘

Boolean

collections

✘

List of object

content

✘

String

created

✘

Date

The time when this resource was created

date-time

createdBy

✘

String

The request or process that created this resource

createdByShareId

✘

Long

int64

createdBySharedUserId

✘

Long

int64

creatorId

✘

Long

The id of the user who created this resource

int64

customFields

✘

CustomFields

data

✘

Boolean

deleted

✘

Date

date-time

description

✘

String

duration

✘

Long

int64

durationSeconds

✘

Double

double

enableHDProxy

✘

Boolean

enableProxy

✘

Boolean

enableShot

✘

Boolean

enableSpeaker

✘

Boolean

enableSpeech

✘

Boolean

enableStitch

✘

Boolean

fileName

✘

String

forceOverwrite

✘

Boolean

growing

✘

Boolean

hash

✘

String

id

✔

Long

The id of this resource

int64

isCloud

✘

Boolean

isData

✘

Boolean

isProxy

✘

Boolean

keyFrame

✘

Long

int64

label

✘

String

language

✘

String

lastUpdated

✘

Date

The time when this resource was last updated

date-time

loggingStatus

✘

String

Enum: NOT_STARTED, EDITING, COMPLETED,

markForRemoval

✘

Boolean

matchingType

✘

String

Enum: NONE, VIDEO_ONLY, AUDIO_ONLY, FULL,

mediaInfo

✘

Object

mediaInfoObject

✘

MediaInfo

mediaInfoProxy

✘

String

mediaInfoString

✘

String

mediaObjectId

✘

Long

int64

mediaObjectInstanceId

✘

Long

int64

mediaObjectInstances

✘

Set of object

modifiedBy

✔

String

The request or process responsible for the last update of this resource

name

✘

String

nonPreferred

✘

Boolean

objectType

✘

String

The data model type or class name of this resource

origin

✘

String

packageId

✘

Long

int64

prefix

✘

String

productionId

✘

Long

int64

proxy

✘

Boolean

proxyOnline

✘

Boolean

proxyProfile

✘

String

rating

✘

Double

double

rawPath

✘

String

resolveMethod

✘

String

Enum: FINGERPRINT, FINGERPRINT_2, NAME, CRITERIA,

reviewStatus

✘

String

sampleRate

✘

SampleRate

screenshot

✘

List of ByteArray

byte

screenshotMimeType

✘

String

size

✘

Long

int64

smallHash

✘

String

source

✘

String

subtitlingStatus

✘

String

Enum: NOT_STARTED, EDITING, COMPLETED, AUTOMATIC_STARTED, AUTOMATIC_COMPLETED, AUTOMATIC_FAILED,

subtitlingStatuses

✘

SubtitlingStatusMap

synchronizeOptions

✘

Map of SynchronizeConfiguration

systemFields

✘

CustomFields

tags

✘

Set of string

timecode

✘

SMPTETimePoint

timecodeFrames

✘

Long

int64

tracks

✘

Set of MediaObjectTrack

transcriptionStatus

✘

String

Enum: NOT_STARTED, EDITING, COMPLETED, AUTOMATIC_STARTED, AUTOMATIC_COMPLETED, AUTOMATIC_FAILED,

transcriptionStatuses

✘

TranscriptionStatusMap

type

✘

String

Enum: IMAGE, DOCUMENT, PENDING, AUDIO, VIDEO, SNIPPET, PACKAGE,

umid

✘

String

url

✘

String

version

✔

Long

The version of this resource, used for Optimistic Locking

int64

wfr

✘

Set of MediaObjectWorkflowReport

workflowId

✘

String

Return Type

FileUploadResponse

The response you get when creating a new upload

Field Name Required Type Description Format

location

✘

String

mediaObjectAnnotation

✘

MediaObjectAnnotation

mediaObjectAnnotationId

✘

Long

int64

mediaObjectId

✘

Long

int64

mediaObjectInstances

✘

List of MediaObjectInstance

position

✘

Long

int64

syncReport

✘

SyncReport

uploadId

✘

String

Content Type
  • application/json

Responses
Table 4. http response codes
Code Description Datatype

201

The request was successful.

FileUploadResponse

402

The user is not allowed to create more resources, quota exceeded.

ForbiddenError

403

The user needs LIBRARY_UPLOAD or SharePermission.UPLOAD rights.

ForbiddenError

404

The production was not found.

NotFoundError

If you like, you can send a thumbnail image to use for this clip using this call:

PUT /production/{prId}/mo/{id}/screenshot

This call allows the user to upload a custom screenshot to a clip, acting as its thumbnail on Limecraft Flow.

Details
Description
Parameters
Path Parameters
Name Description Required Type

prId

ID of the production.

✔

Long

id

ID of the MediaObject.

✔

Long

Body Parameters
Name Description Required Type

ScreenshotUpdateRequest

✘

ScreenshotUpdateRequest

ScreenshotUpdateRequest

Field Name Required Type Description Format

screenshot

✘

List of ByteArray

byte

screenshotType

✘

String

Return Type

MediaObject

Field Name Required Type Description Format

annotations

✘

Set of Annotation

created

✘

Date

The time when this resource was created

date-time

createdBy

✘

String

The request or process that created this resource

createdByShareId

✘

Long

int64

createdBySharedUserId

✘

Long

int64

creatorId

✘

Long

The id of the user who created this resource

int64

deleted

✘

Date

date-time

duration

✘

Long

int64

durationSeconds

✘

Double

double

growing

✘

Boolean

id

✔

Long

The id of this resource

int64

keyFrame

✘

Long

int64

lastUpdated

✘

Date

The time when this resource was last updated

date-time

mediaObjectInstances

✘

Set of MediaObjectInstance

modifiedBy

✔

String

The request or process responsible for the last update of this resource

name

✘

String

objectType

✘

String

The data model type or class name of this resource

packageId

✘

Long

int64

productionId

✘

Long

int64

proxyOnline

✘

Boolean

sampleRate

✘

SampleRate

timecode

✘

SMPTETimePoint

timecodeFrames

✘

Long

int64

tracks

✘

Set of MediaObjectTrack

type

✘

String

Enum: IMAGE, DOCUMENT, PENDING, AUDIO, VIDEO, SNIPPET, PACKAGE,

umid

✘

String

version

✔

Long

The version of this resource, used for Optimistic Locking

int64

wfr

✘

Set of MediaObjectWorkflowReport

workflowId

✘

String

Content Type
  • application/json

Responses
Table 5. http response codes
Code Description Datatype

200

The request was successful.

MediaObject

403

The user needs LIBRARY_UPDATE_METADATA rights.

ForbiddenError

404

The production or media object was not found.

NotFoundError

Synchronize clips

Clips can also be synchronized with Limecraft Flow. For more info on that one, please check out this page.