The Encoding API for Co-Creation Stage is a self-contained Express application for uploading media files to AWS S3 and starting Elastic Transcoder encoding jobs. This is a self-contained version of the API found in the Co-Creation Space and can be deployed with a minimal amount of dependencies
In order to run the application, a JSON file containing AWS credentials called
aws.json needs to be placed in the application root. The file must have the
following structure:
{
"accessKeyId": "[YOUR_ACCESS_KEY]",
"secretAccessKey": "[YOUR_SECRET_KEY]",
"region": "[AWS_REGION]"
}
Further, the file .env-sample needs to be renamed to .env and the following
values need to be filled in:
SESSION_SECRET a string of random characters that is used to sign the JSON
Web TokensBUCKET_NAME the name of the S3 bucket that the files should be uploaded toETS_PIPELINE the ID of the Elastic Transcoder pipeline used to transcode
uploaded media files. NB: Make sure to supply the ID of the pipeline and not
the nameFor development, make sure you have docker, node and yarn installed.
Build and start the container as such:
docker compose build
docker compose up -d
Because the application bundle is mounted inside the container from the host machine, it needs to be built as well. This is done as follows:
yarn install
yarn build
After any change to the code, yarn build needs to be run in order to refresh
the compiled bundle. Also docker compose restart web should be run to ensure
the application is restarted using the new bundle.
The application itself is now available on port 3001.
There is a separate Docker Compose config file for production environments
named docker-compose.production.yml. This does not require compiling the
bundle locally and is thus ideal for deployment environments or if there is no
intention of changing the code. To build such a production image, invoke Docker
Compose as such:
docker compose -f docker-compose.production.yml build
docker compose -f docker-compose.production.yml up -d
This image is completely self-contained (except for .env and aws.json) and
can also easily be deployed in a Docker Swarm environment.
The application uses SQLite to manage user accounts. Initially, the database is
empty, but new user accounts can be added using the script register.js.
In order to run this script, ensure the container is running and invoke the following command from the command line:
docker compose exec web yarn register
The script will ask for a new username and a password. The selected values are inserted into the database and can then be used to log into the API and obtain a JSON Web Token for all further calls. The obtained token is valid for 60 days.
NB: The script will fail if the chosen username already exists, i.e. usernames must be unique.
By default, the application supports the resolutions 720p, 480p, 360p and
240p. One can, however, add custom encoding presets by creating them in the
Transcoder preset config menu on AWS and adding their preset IDs to a file
named presets.json in the application root. A sample file with custom presets
named presets.json-sample is provided.
The file contains a JSON dictionary, with the keys being unique, descriptive names, e.g. denoting the resolution that the preset produces. Each key is associated to its corresponding preset ID.
Once added, the application should be restarted. The availability of the custom
presets can be verified by calling GET /api/upload/encode/resolutions.
The following sections document each of the API endpoints that the application supplies in order to facilitate media upload and encoding. This documentation can also be used as a specification to implement alternative APIs, e.g. ones that do not rely on external cloud services.
NB: The Content-Type header of requests which send data should be set to
application/json to ensure that the request is interpreted quickly. This
does not apply to /api/upload/raw.
Please refer to the script example.py, which illustrates a sample interaction
with the API, including login, file upload, starting of a transcoding job,
checking of job status and finally deleting the originally uploaded file. In
order to run the script, the package requests has to be installed.
In order to interact with the API, the caller is required to supply a JSON Web
Token along with each request. This token can be obtained by calling the route
/api/login with a valid user account. Refer to the previous section on how to
add new user accounts. The endpoint expects the parameters username and
password inside a JSON dictionary in the body of the request:
POST /api/login
Content-Type: application/json
{ "username": "test", "password": "test" }
Upon successful login, the API returns a JSON dictionary containing the keys
_id, username and token. The value of token should then be used to
authenticate requests to any other endpoint.
The endpoint /api/upload/raw serves to upload files to the associated S3
bucket. The file should be submitted in the body of a multipart/form-data
request under the key file. Also take note of the presence of the previously
obtained token in the Authorization header.
POST /api/upload/raw
Authorization: Bearer [TOKEN]
Content-Type: multipart/form-data; charset=utf-8; boundary=__BOUNDARY__
--__BOUNDARY__
Content-Disposition: form-data; name="file"; filename="example.mp4"
[FILE_CONTENTS]
--__BOUNDARY__--
A request like this can be executed in curl as such:
curl -v -XPOST --header "Authorization: Bearer [TOKEN]" -F file=@[PATH_TO_FILE] http://example.com/api/upload/raw
Upon success, the call with return a JSON dictionary containing the path to
the newly uploaded file under the key name.
Previously uploaded files can be deleted by calling /api/upload/raw with the
verb HTTP DELETE, supplying the path to the file to be deleted under the key
key in the JSON request body.
DELETE /api/upload/raw
Authorization: Bearer [TOKEN]
Content-Type: application/json
{ "key": "[PATH_TO_FILE_ON_S3]" }
The endpoint for starting new transcoding jobs offers a parameter which allows
one to specify the desired output resolutions. This endpoint allows the caller
to retrieve a list of available output resolutions. The resolutions 720p,
480p, 360p and 240p are always available. Also refer to the section
about adding custom presets for more information.
GET /api/upload/encode/resolutions
Authorization: Bearer [TOKEN]
A JSON data structure with the key resolutions is returned which contains a
list of supported resolutions for the transcoding job.
In order to start a DASH transcoding job for an uploaded video or audio file,
a request to the endpoint /api/upload/encode has to be made. The endpoint
expects the key input containing the path to the file to be encoded in the
JSON body of the request.
Optionally, a list of desired output resolutions can be submitted as an array.
A list of available resolutions can be retrieved by calling the endpoint
/api/upload/encode/resolutions. If the parameter is omitted, the file is
encoded to 720p, 480p and 360p by default.
Also note, if a video file which does not contain an audio track is to be
encoded, the option hasAudio set to false has to be passed in the request
body. Otherwise the encoding will fail. If omitted, hasAudio defaults to
true.
POST /api/upload/encode
Authorization: Bearer [TOKEN]
Content-Type: application/json
{ "input": "[PATH_TO_FILE_ON_S3]", "resolutions": ["1080p", "360p"] }
If an unknown resolution is passed, it will be ignored. Upon success, the
response will contain the job ID of the newly started transcoding job under the
key jobId in the JSON response body.
To check the status of a started transcoding job, the API supplies the endpoint
/api/upload/encode/status/:jobId, where :jobID is the job ID of a
transcoding job.
GET /api/upload/encode/status/[JOB_ID]
Authorization: Bearer [TOKEN]
The request will return the current status of the transcoding job with the
specified ID. The key jobStatus will contain one of Submitted,
Progressing, Complete, Canceled or Error. If the value of jobStatus
is equal to Complete, the response will also contain the key manifest,
which contains the path to the DASH manifest that can be used to play back the
encoded media file.