Skip to content

Repository files navigation

Transcoder

This program allows you to execute transcoding operation via an API using gstreamer.
What you can do with it :

  • Predefine your encoding / muxing presets in a json configuration file
  • Post result(s) to another http(s) server (upload sample)
  • Follow transcoding progression and send notification to another http(s) server
  • Stop a transcoding operation
  • Transcode subtitles except image based subtitles
  • Verify if the transcoder will be able to transcode media before adding media to queue

What you can't do with it :

  • Define demuxing / decoding operation in the json configuration file.
  • Muxing subtitles in the final container

How does it work

  1. (opt) Query the endpoint /support to verify that your media is supported
  2. Query endpoint /transcode to add the media. It will re-test if the media can be transcoded (like /support endpoint). When all is successful it will add the media to transcoding queue in redis.
  3. Worker start transcoding using gstreamer
  4. During the process, if progress url was sent to /transcode, it will periodically notify it with the progression data ({ "status": "progress", "jobId": 123, "progress": 10.2 } or if it failed { "status": "failed", "jobId": 123 })
  5. Once transcoding is completed / cancelled, if end url was sent to /transcode, it will notify this url with media information as body and cancelled(=0|1) in query string.

Dev installation

Starting

First define .env file in the project, then docker-compose -f ./docker-compose.dev.yml up.
Use npm run warmup to create cache.json if needed.

Sample basic .env :

STORAGE_PATH=.dataDEBUG=app:*PRESET_FILE=./example_presets/presets-full.jsonPORT=3000ARENA_PORT=3001ALLOW_QUERY_FILE_PATH=1ALLOWED_API_KEYS=test

Before transcoding

In dev env, before querying /transcode, please verify that the user 1000 has the permission to read / write in $STORAGE_PATH/virtual_storage folder.

Api test

You can import api definition (<rootDir>/insomnia/transcoder.yml) with insomnia

Env configuration

nameexampledescription
PORT3000Exposed api listen port (mapped to 4000 in dev docker-compose)
REDIS_HOSTredis.hostRedis address
REDIS_PORT6379Redis port (this variable is used only by the app and don't change redis service in dev docker-compose)
REDIS_PASSWORDRedis password (this variable is used only by the app and don't change redis service in dev docker-compose)
REDIS_PREFIXtranscoRedis queue prefix
DEBUGapp:*Used to activate debug output see debug for usage
ARENA_PORT3001Exposed arena port (mapped to 4001 in dev docker-compose)
ARENA_HOST0.0.0.0Listen address for arena
ALLOWED_API_KEYSApi keys used by the API, you can use alphanum char, to define multiple api keys use , separator. Theses api keys are case insensitive. To disable api key auth, let this variable empty
PRESET_FILE./example_presets/presets-full.jsonPreset filepath (see example dir for some presets sample)
VERSIONVersion used by sentry
SENTRY_DSNSentry DSN
PROXIEDTo define if this application is behind a reverse proxy
SENTRY_ENVdevSentry env
ALLOW_QUERY_FILE_PATHSet value to 1 if you want to allow filepath in api queries
STORAGE_PATH.dataDocker volumes path
DISCOVER_TIMEOUT60Timeout for discovering media's metadata (in seconds)
JOB_TIMEOUT300000Job timeout (max duration without progress in ms)

Preset file

KeyTypeRequiredDescription
constraintsobjectnPlugins whitelist section
constraints.audioobjectnPlugins whitelist for audio
constraints.audio.parsersstring[]nPlugins whitelist for audio parsers (unused if empty)
constraints.audio.decodersstring[]nPlugins whitelist for audio decoders (unused if empty)
constraints.videoobjectnPlugins whitelist for video
constraints.video.parsersstring[]nPlugins whitelist for video parsers (unused if empty)
constraints.video.decodersstring[]nPlugins whitelist for video decoders (unused if empty)
constraints.demuxersstring[]nDemuxers whitelist
queuePropsobjectnQueue element props
srcobjectnSrc element section
src.httpobjectnHttp src element section
src.http.elementstringnElement name for http(s) links
src.http.propsobjectnElement props for http(s) links
src.fileobjectnFile src element section
src.file.elementstringnElement name for files
src.file.propsobjectnElement props for files
sinkobjectnSink element section
sink.httpobjectnHttp sink element section
sink.http.elementstringnElement name
sink.http.propsobjectElement props
sink.fileobjectnFile sink element section
sink.file.elementstringnElement name
sink.file.propsobjectnElement props
subtitlesobjectnSubtitles section (/!\ this feature has his decoding pipeline mostly hardcoded and can have hazardous behavior)
subtitles.acceptregexyAccepted subtitles mimetype
subtitles.filenamestringnOutput filename, %i will be remplaced by the stream offset
subtitles.encoderobjectySubtitles encoder section
subtitles.encoder.instancestringySubtitle element name
subtitles.encoder.paramsstringnSubtitle element props
presetsobjectyPresets section
presets.<name>objectyPreset section, you can use whatever you want as
presets.<name>.minHeightintnMin media height for this preset, it the original media is lower than this height, the preset will be ignored except if media's width is greater than minWidth
presets.<name>.minWidthintnMin media width for this preset, it the original media is lower than this width, the preset will be ignored except if media's height is greater than minHeight
presets.<name>.muxerobjectyMuxer section
presets.<name>.muxer.typestringyMuxer element name
presets.<name>.muxer.filenamestringyOutput filename
presets.<name>.muxer.paramsobjectnMuxer element properties, ex : { "streamable": true }
presets.<name>.videoarraynVideo pipeline
presets.<name>.video[X]objectnElement / Caps definition
presets.<name>.video[X].removeIfStreamHeightintnRemove this element / caps if media's height equals removeIfStreamHeight
presets.<name>.video[X].instancestring(element,caps)yElement type
presets.<name>.video[X].paramsobjectyElement or caps parameters
presets.<name>.video[X].params.typestringyElement or caps type ex: video/x-raw or videoscale
presets.<name>.video[X].params.propsobjectnElement or caps properties, ex: { "height": 480 }. bitrate property is specific, you must define the unit associated to this value with bitrateUnit field. It will be used to keep the original bitrate if media's bitrate is lower than the one you wrote
presets.<name>.audioarraynAudio pipeline
presets.<name>.audio[X]objectnElement / Caps definition
presets.<name>.audio[X].instancestring(element,caps)yElement type
presets.<name>.audio[X].paramsobjectyElement or caps parameters
presets.<name>.audio[X].params.typestringyElement or caps type ex: audio/x-raw or audioconvert
presets.<name>.audio[X].params.propsobjectnElement or caps properties, ex: { "bitrate": 160000, "bitrateUnit": "b" }. bitrate property is specific, you must define the unit associated to this value with bitrateUnit field. It will be used to keep the original bitrate if media's bitrate is lower than the one you wrote

About

Toto transco

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages