Movatterモバイル変換


[0]ホーム

URL:


Notice  The highest tagged major version isv16.

core

commandmodule
v0.0.0-...-31c1c1eLatest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2022 License:Apache-2.0Imports:5Imported by:0

Details

Repository

github.com/datarhei/core

README

Core

The cloud-native audio/video processing API.

CodeQLGo Report CardPkgGoDev

datarhei Core is management for FFmpeg processes without development effort. It is a central interface for mapping AV processes, is responsible for design and management, and provides all necessary interfaces to access the video content. The included control for FFmpeg can keep all used functions reliable and executable without the need for software developers to take care of it. In addition, process and resource limitation for all FFmpeg processes protects the host system from application overload. The overall system gives access to current process values (CPU, RAM) and complete control of system resources and loads with statistical access to process data and current and historical logs.

Features

  • Unrestricted FFmpeg process management
  • Optimized for long-running tasks
  • In-Memory- and Disk-Filesystem for media assets
  • HTTP and RTMP services
  • Let's Encrypt for HTTPS and RTMPS
  • HLS/DASH Session tracking with bandwidth and current viewer limiters
  • Multiple resource limiters and monitoring
  • FFmpeg progress data
  • Metrics incl. Prometheus support
  • Logging and debugging for FFmpeg processes with history
  • Multiple auth. by JWT and Auth0
  • 100% JSON REST API (Swagger documented)
  • GraphQL for metrics, process, and progress data

Quick start

  1. Run the Docker image
docker run --name core -d \    -e CORE_API_AUTH_USERNAME=admin \    -e CORE_API_AUTH_PASSWORD=secret \    -p 8080:8080 \    -v ${HOME}/core/config:/core/config \    -v ${HOME}/core/data:/core/data \    datarhei/core:latest
  1. Open Swaggerhttp://host-ip:8080/api/swagger/index.html

  2. Log in with SwaggerAuthorize > Basic authorization > Username: admin, Password: secret

Docker images

Native (linux/amd64,linux/arm64,linux/arm/v7)

  • datarhei/base:alpine-core-latest
  • datarhei/base:ubuntu-core-latest

Bundle with FFmpeg (linux/amd64,linux/arm64,linux/arm/v7)

  • datarhei/core:latest

Bundle with FFmpeg for Raspberry Pi (linux/arm/v7)

  • datarhei/core:rpi-latest

Bundle with FFmpeg for Nvidia Cuda (linux/amd64)

  • datarhei/core:cuda-latest

Bundle with FFmpeg for Intel VAAPI (linux/amd64)

  • datarhei/core:vaapi-latest

Documentation

Environment variables

The environment variables can be set in the file.env, e.g.

CORE_API_AUTH_USERNAME=adminCORE_API_AUTH_PASSWORD=datarhei...

You can also provide them on the command line, whatever you prefer. If the same environment variable is setin the.env file and on the command line, the one set on the command line will overrule the one from the.env file.

The currently known environment variables (but not all will be respected) are:

NameDefaultDescription
CORE_CONFIGFILE(not set)Path to a config file. The following environment variables will override the respective values in the config file.
CORE_ADDRESS:8080HTTP listening address.
CORE_LOG_LEVELinfosilent, error, warn, info, debug.
CORE_LOG_TOPICS(not set)List of topics to log (comma separated)
CORE_LOG_MAXLINES1000Number of latest log lines to keep in memory.
CORE_DB_DIR.Directory for holding the operational data. This directory must exist.
CORE_HOST_NAME(not set)Set to the domain name of the host this instance is running on.
CORE_HOST_AUTOtrueEnable detection of public IP addresses.
CORE_API_READ_ONLYfalseAllow only ready only access to the API
CORE_API_ACCESS_HTTP_ALLOW(not set)Comma separated list of IP ranges in CIDR notation (HTTP traffic), e.g.127.0.0.1/32,::1/128.
CORE_API_ACCESS_HTTP_BLOCK(not set)Comma separated list of IP ranges in CIDR notation (HTTP traffic), e.g.127.0.0.1/32,::1/128.
CORE_API_ACCESS_HTTPS_ALLOW(not set)Comma separated list of IP ranges in CIDR notation (HTTPS traffic), e.g.127.0.0.1/32,::1/128.
CORE_API_ACCESS_HTTPS_BLOCK(not set)Comma separated list of IP ranges in CIDR notation (HTTPS traffic), e.g.127.0.0.1/32,::1/128.
CORE_API_AUTH_ENABLEtrueSet tofalse to disable auth for all clients.
CORE_API_AUTH_DISABLE_LOCALHOSTfalseSet totrue to disable auth for clients from localhost.
CORE_API_AUTH_USERNAME(required)Username for auth.
CORE_API_AUTH_PASSWORD(required)Password for auth.
CORE_API_AUTH_JWT_SECRET(not set)A secret for en- and decrypting the JWT. If not set, a secret will be generated.
CORE_API_AUTH_AUTH0_ENABLEfalseEnable Auth0.
CORE_API_AUTH_AUTH0_TENANTS(not set)List of base64 encoded Auth0 tenant JSON objects (comma-separated). The tenant JSON object is defined as{"domain":string,"audience":string,"users":array of strings}
CORE_TLS_ADDRESS:8181Port to listen on for HTTPS requests.
CORE_TLS_ENABLEfalseSet totrue to enable TLS support.
CORE_TLS_AUTOfalseSet totrue to enable automatic retrieval of a Let's Encrypt certificate. RequiresCORE_TLS_ENABLE to betrue andCORE_HOST_NAME to be set withCORE_HOST_AUTO tofalse.
CORE_TLS_CERTFILE(not set)TLS certificate file in PEM format.
CORE_TLS_KEYFILE(not set)TLS key file in PEM format.
CORE_STORAGE_DISK_DIR.A directory that will be exposed by HTTP on /. This directory must exist.
CORE_STORAGE_DISK_MAXSIZEMBYTES0Max. allowed megabytes forCORE_STORAGE_DISK_DIR.
CORE_STORAGE_DISK_CACHE_ENABLEtrueEnable cache for files fromCORE_STORAGE_DISK_DIR.
CORE_STORAGE_DISK_CACHE_MAXSIZEMBYTES0Max. allowed cache size, 0 for unlimited.
CORE_STORAGE_DISK_CACHE_TTLSECONDS300Seconds to keep files in cache.
CORE_STORAGE_DISK_CACHE_MAXFILESIZEMBYTES1Max. file size to put in cache.
CORE_STORAGE_DISK_CACHE_TYPES(not set)List of file extensions to cache (space-separated, e.g. ".html .js"), empty for all.
CORE_STORAGE_MEMORY_AUTH_ENABLEtrueEnable basic auth for PUT,POST, and DELETE on /memfs.
CORE_STORAGE_MEMORY_AUTH_USERNAME(not set)Username for Basic-Auth of/memfs. Required if auth is enabled.
CORE_STORAGE_MEMORY_AUTH_PASSWORD(not set)Password for Basic-Auth of/memfs. Required if auth is enabled.
CORE_STORAGE_MEMORY_MAXSIZEMBYTES0Max. allowed megabytes for/memfs. Any value <= 0 means unlimited.
CORE_STORAGE_MEMORY_PURGEfalseSet totrue to remove the oldest entries if the/memfs is full.
CORE_STORAGE_COCORE_ORIGINS*List of allowed CORS origins (comma separated). Will be used for/ and/memfs.
CORE_STORAGE_MIMETYPES_FILEmime.typesPath to file with MIME type definitions.
CORE_RTMP_ENABLEfalseEnable RTMP server.
CORE_RTMP_ENABLE_TLSfalseEnable RTMP over TLS (RTMPS). RequiresCORE_TLS_ENABLE to betrue.
CORE_RTMP_ADDRESS:1935RTMP server listen address.
CORE_RTMP_APP/RTMP app for publishing.
CORE_RTMP_TOKEN(not set)RTMP token for publishing and playing. The token is the value of the URL query parametertoken.
CORE_FFMPEG_BINARYffmpegPath to FFmpeg binary.
CORE_FFMPEG_MAXPROCESSES0Max. allowed simultaneously running FFmpeg instances. Any value <= 0 means unlimited.
CORE_FFMPEG_ACCESS_INPUT_ALLOW(not set)List of pattern for allowed input URI (space-separated), leave emtpy to allow any.
CORE_FFMPEG_ACCESS_INPUT_BLOCK(not set)List of pattern for blocked input URI (space-separated), leave emtpy to block none.
CORE_FFMPEG_ACCESS_OUTPUT_ALLOW(not set)List of pattern for allowed output URI (space-separated), leave emtpy to allow any.
CORE_FFMPEG_ACCESS_OUTPUT_BLOCK(not set)List of pattern for blocked output URI (space-separated), leave emtpy to block none.
CORE_FFMPEG_LOG_MAXLINES50Number of latest log lines to keep for each process.
CORE_FFMPEG_LOG_MAXHISTORY3Number of latest logs to keep for each process.
CORE_PLAYOUT_ENABLEfalseEnable playout API where available
CORE_PLAYOUT_MINPORT0Min. port a playout server per input can run on.
CORE_PLAYOUT_MAXPORT0Max. port a playout server per input can run on.
CORE_DEBUG_PROFILINGfalseSet totrue to enable profiling endpoint on/profiling.
CORE_DEBUG_FORCEGC0Number of seconds between forcing GC to return memory to the OS. Use in conjuction withGODEBUG=madvdontneed=1. Any value <= 0 means not to force GC.
CORE_METRICS_ENABLEfalseEnable collecting historic metrics data.
CORE_METRICS_ENABLE_PROMETHEUSfalseEnable prometheus endpoint /metrics.
CORE_METRICS_RANGE_SECONDS300Seconds to keep history metric data.
CORE_METRICS_INTERVAL_SECONDS2Interval for collecting metrics.
CORE_SESSIONS_ENABLEfalseEnable HLS statistics for/memfs.
CORE_SESSIONS_IP_IGNORELIST(not set)Comma separated list of IP ranges in CIDR notation, e.g.127.0.0.1/32,::1/128.
CORE_SESSIONS_SESSION_TIMEOUT_SEC30Timeout of a session in seconds.
CORE_SESSIONS_PERSISTfalseWhether to persist the session history. Will be stored inCORE_DB_DIR.
CORE_SESSIONS_MAXBITRATE_MBIT0Max. allowed outgoing bitrate in mbit/s, 0 for unlimited.
CORE_SESSIONS_MAXSESSIONS0Max. allowed number of simultaneous sessions, 0 for unlimited.
CORE_ROUTER_BLOCKED_PREFIXES/apiList of path prefixes that can't be routed.
CORE_ROUTER_ROUTES(not set)List of route mappings of the form [from]:[to], e.g./foo:/bar. Leave empty for no routings.
CORE_ROUTER_UI_PATH(not set)Path to directory with files for a UI. It will be mounted to/ui and usesindex.html as default index page.

Config

The minimum config file has to look like this:

{    "version": 1}

All other values will be filled with default values and persisted on disk. The entire default config file:

{    "version": 1,    "id": "[will be generated if not given]",    "name": "[will be generated if not given]",    "address": ":8080",    "log": {        "level": "info",        "topics": [],        "max_lines": 1000    },    "db": {        "dir": "./config"    },    "host": {        "name": [],        "auto": true    },    "api": {        "read_only": false,        "access": {            "http": {                "allow": [],                "block": []            },            "https": {                "allow": [],                "block": []            }        },        "auth": {            "enable": true,            "disable_localhost": false,            "username": "",            "password": "",            "jwt": {                "secret": ""            },            "auth0": {                "enable": false,                "tenants": []            }        }    },    "tls": {        "address": ":8181",        "enable": false,        "auto": false,        "cert_file": "",        "key_file": ""    },    "storage": {        "disk": {            "dir": "./data",            "max_size_mbytes": 0,            "cache": {                "enable": true,                "max_size_mbytes": 0,                "ttl_seconds": 300,                "max_file_size_mbytes": 1,                "types": []            }        },        "memory": {            "auth": {                "enable": true,                "username": "admin",                "password": "vxbx0ViqfA75P1KCyw"            },            "max_size_mbytes": 0,            "purge": false        },        "cors": {            "origins": [                "*"            ]        },        "mimetypes_file": "mime.types"    },    "rtmp": {        "enable": false,        "enable_tls": false,        "address": ":1935",        "app": "/",        "token": ""    },    "ffmpeg": {        "binary": "ffmpeg",        "max_processes": 0,        "access": {            "input": {                "allow": [],                "block": []            },            "output": {                "allow": [],                "block": []            }        },        "log": {            "max_lines": 50,            "max_history": 3        }    },    "playout": {        "enable": false,        "min_port": 0,        "max_port": 0    },    "debug": {        "profiling": false,        "force_gc": 0    },    "stats": {        "enable": true,        "ip_ignorelist": [            "127.0.0.1/32",            "::1/128"        ],        "session_timeout_sec": 30,        "persist": false,        "persist_interval_sec": 300,        "max_bitrate_mbit": 0,        "max_sessions": 0    },    "service": {        "enable": false,        "token": "",        "url": "https://service.datarhei.com"    },    "router": {        "blocked_prefixes": [            "/api"        ],        "routes": {}    }}

If you don't provide a path to a config file, the default config will be used, and nothing will be persisted to the disk. Default values can be overruled by environment variables.

TLS / HTTPS

Enable TLS / HTTPS support by settingCORE_TLS_ENABLE=true and provide the certificate file and key file in PEM format by setting the environment variablesCORE_TLS_CERTFILE andCORE_TLS_KEYFILE accordingly. If a certificate authority signs the certificate, the certificate file should be the concatenation of the server's certificate, any intermediates, and the CA's certificate.

If TLS with given certificates is enabled, an HTTP server listening onCORE_ADDRESS (address) will be additionally started. This server provides access to the same memory filesystem as the HTTPS server (including limits and authorization), but its access is restricted to localhost only.

Let's Encrypt

If you want to use automatic certificates from Let's Encrypt, set the environment variableCORE_TLS_AUTO totrue. To work, theenvironment variablesCORE_TLS_ENABLE have to betrue, andCORE_HOST_NAME has to be set to the host this host will be reachable. Otherwise, the ACME challenge will not work. The environment variablesCORE_TLS_CERTFILE andCORE_TLS_KEYFILE will be ignored.

If automatic TLS is enabled, the HTTP server (CORE_ADDRESS, resp. address) must listen on port 80. It is required to automatically acquire the certificate (serving theHTTP-01 challenge). As a further requirement,CORE_HOST_NAME (host.name) must be set because it is used a the canonical name for the certificate.

The obtained certificates will be stored inCORE_DB_DIR/cert to be available after a restart.

The obtained certificates will be stored inCORE_DB_DIR/cert to be available after a restart.

Self-Signed certificates

To create a self-signed certificate and key file pair, run this command and provide a reasonable value for the Common Name (CN). The CN is the fully qualified name of the host the instance is running on (e.g.,localhost). You can also use an IP address or a wildcard name, e.g.,*.example.com.

RSA SSL certificate

openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem -subj '/CN=localhost'

ECDSA SSL certificate

openssl ecparam -name secp521r1 -genkey -out key.pemopenssl req -new -x509 -key key.pem -out cert.pem -days 365 -subj '/CN=localhost'

Callopenssl ecparam -list_curves to see all available supported curves listed.

Access Control

To control who has access to the API, a list of allowed IPs can be defined. This list is provided at startup with the environment variablesCORE_API_ACCESS_HTTP_BLOCK andCORE_API_ACCESS_HTTP_ALLOW. This is a comma-separated list of IPs in CIDR notation,e.g.127.0.0.1/32,::1/128. If the list is empty, then all IPs are allowed. If the list contains any invalid IP range, the serverwill refuse to start. This can be separately defined for the HTTP and HTTPS server if you have TLS enabled with the environment variablesCORE_API_ACCESS_HTTPS_BLOCK andCORE_API_ACCESS_HTTPS_ALLOW.

Input/Output Control

To control where FFmpeg can read and where FFmpeg can write, you can define a pattern that matches theinput addresses or the output addresses. These patterns are regular expressions that can be provided at startup with theenvironment variablesCORE_FFMPEG_ACCESS_INPUT andCORE_FFMPEG_ACCESS_OUTPUT. The expressions need to be space-separated, e.g.HTTPS?:// RTSP:// RTMP://. If one of the lists is empty, then no restriction on input, resp. The output will be applied.

Independently of the value ofCORE_FFMPEG_ACCESS_OUTPUT there's a check that verifies that output can only be written to the specifiedCORE_STORAGE_DISK_DIR and works as follows: If the address has a protocol specifier other thanfile:, then no further checks will be applied. If the protocol isfile: or no protocol specifier is given, the address is assumed to be a path that is checked against the path shown inCORE_STORAGE_DISK_DIR.

It will be rejected if the address is outside theCORE_STORAGE_DISK_DIR directory. Otherwise, the protocolfile: will be prepended. If you give some expressions forCORE_FFMPEG_ACCESS_OUTPUT, you should also allowfile:.

Special cases are the output addresses- (which will be rewritten topipe:), and/dev/null (which will be allowed even though it's outside ofCORE_STORAGE_DISK_DIR).

If you set a value forCORE_STORAGE_DISK_CACHE_MAXSIZEMBYTES, which is larger than0, it will be interpreted as max—allowed megabytes for theCORE_STORAGE_DISK_DIR. As soon as the limit is reached, all processes that have outputs writing toCORE_STORAGE_DISK_DIR will be stopped. You are responsible for cleaning up the directory and restarting these processes.

RTMP

The datarhei Core includes a simple RTMP server for publishing and playing streams. Set the environment variableCORE_RTMP_ENABLE totrue to enable the RTMP server. It is listening onCORE_RTMP_ADDRESS. UseCORE_RTMP_APP to limit the app a stream can be published on, e.g./live to require URLs to start with/live. To prevent anybody can publish streams, setCORE_RTMP_TOKEN to a secret only known to the publishers. The token has to be put in the query of the stream URL, e.g./live/stream?token=....

MethodPathDescription
GET/api/v3/rtmpList all currently published streams.

Playout

FFmpeg processes with aavstream: (orplayout:) input stream can expose an HTTP API to control the playout of that stream. WithCORE_PLAYOUT_ENABLE you enable exposing this API. The API is only exposed tolocalhost and is transparently connected to the datarhei Core API. You have to provide a port range (CORE_PLAYOUT_MINPORT andCORE_PLAYOUT_MAXPORT) where datarhei/core can use ports to assign it to the playout API.

MethodPathDescription
GET/api/v3/process/:id/playout/:inputid/statusRetrieve the current status as JSON.
GET/api/v3/process/:id/playout/:inputid/keyframe/*nameRetrieve the last deliverd key frame from the input stream as JPEG (ifname has the ending.jpg) or PNG (ifname has the ending.png).
GET/api/v3/process/:id/playout/:inputid/errorframe/encodeImmediately encode the error frame to a GOP. Will only have an effect if the last key frame is currently in a loop.
PUT/POST/api/v3/process/:id/playout/:inputid/errorframe/*nameUpload any image or video media that can be decoded and will be used to replace the key frame loop. If the key frame is currently in a loop, it will be repaced immediately. Otherwise, it will be used the next time the key frame is in a loop. The body of the request is the media file.
PUT/api/v3/process/:id/playout/:inputid/streamReplace the current stream. The body of the request is the URL of the new stream.

MIME Types

The file with the MIME types has one MIME type per line followed by a list of file extensions (including the ".").

text/plain  .txttext/html   .htm .html...

Memory Filesystem

AA very simple in-memory filesystem is available. The uploaded data is stored in a map, where the path used to upload the fileis used as the key. Use thePOST orPUT method with the proper direction for uploading a file. The body of the request contains the contents of the file. No particular encoding orContent-Type is required. The file can then be downloaded from the same path.

MethodPathDescription
POST/memfs/*pathUpload a file to the memory filesystem. The filename ispath which can contain slashes. If there's already a file with the samepath, it will be overwritten.
PUT/memfs/*pathSame as POST.
GET/memfs/*pathDownload the file stored underpath. The MIME types are applied based on the extension in thepath.
DELETE/memfs/*pathDelete the file stored underpath.
POST/api/v3/memfs/*pathUpload a file to the memory filesystem.
PUT/api/v3/memfs/*pathSame as POST.
GET/api/v3/memfs/*pathDownload the file stored underpath.
PATCH/api/v3/memfs/*pathCreate a link to a file. The body contains the path to that file.
DELETE/api/v3/memfs/*pathDelete the file stored underpath.
GET/api/v3/memfsList all files that are currently stored in the in-memory filesystem.

Use these endpoints to, e.g., store HLS chunks and .m3u8 files (in contrast to an actual disk or a ramdisk):

ffmpeg -f lavfi -re -i testsrc2=size=640x480:rate=25 -c:v libx264 -preset:v ultrafast -r 25 -g 50 -f hls -start_number 0 -hls_time 2 -hls_list_size 6 -hls_flags delete_segments+temp_file+append_list -method PUT -hls_segment_filename http://localhost:8080/memfs/foobar_%04d.ts -y http://localhost:8080/memfs/foobar.m3u8

Then you can play it generally with, e.g.,ffplay http://localhost:3000/memfs/foobar.m3u8.

Use the environment variablesCORE_STORAGE_MEMORY_AUTH_USERNAME andCORE_STORAGE_MEMORY_AUTH_PASSWORD to protect the/memfs with Basic-Auth. Basic-Auth will only be enabledif both environment variables are set to non-empty values. TheGET /memfs/:path will not be protected with Basic-Auth.

Use the environment variableCORE_STORAGE_MEMORY_MAXSIZEMBYTES to limit the amount of data that is allowed to be stored. The value is interpreted as megabytes. Use a value equal to or smaller than0 not to impose any limits. A507 Insufficient Storage will be returned if you hit the limit.

Listing all currently stored files is done by calling/v3/memfs with the credentials set by the environment variablesCORE_API_AUTH_USERNAME andCORE_API_AUTH_PASSWORD.It also accepts the query parametersort (name,size, orlastmod) andorder (asc ordesc). If a valid value forsort is given, the results are sorted in ascending order.

Routes

All contents inCORE_STORAGE_DISK_DIR are served from/. If you want to redirect some paths to an existing file, you can add static routes inrouter.routes by providing a direct mapping, e.g.

router: {    routes: {        "/foo.txt": "/bar.txt",    }}

The paths have to start with a/. Alternatively, you can serve whole directories from another root thanCORE_STORAGE_DISK_DIR. Use a/* at the end of a path as key and a path on the filesystem as the target, e.g.

router: {    routes: {        "/ui/*": "/path/to/ui",    }}

If you use a relative path as target, then it will be added to the current working directory.

API

Check the detailed API description on/api/swagger/index.html.

Login / Auth

With auth enabled, you have to retrieve a JWT/OAuth token before you can access the/v3/ API calls.

MethodPathDescription
POST/api/loginRetrieve a token to access the API.
GET/api/v3/refresh_tokenRetrieve a fresh token with a new expiry date.

For the login you have to send

{    "username": "...",    "password": "..."}

Theusername and thepassword are set by the environment variablesCORE_API_AUTH_USERNAME andCORE_API_AUTH_PASSWORD.

On successful login, the response looks like this:

{    "expire": "2019-01-18T19:55:55+01:00",    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDc4Mzc3NTUsImlkIjpudWxsLCJvcmlnX2lhdCI6MTU0NzgzNDE1NX0.ZcrpD4oRBqG3wUrfnh1DOVpXdUT7dvUnvetKFEVRKKc"}

Use thetoken in all subsequent calls to the/api/v3/ endpoints, e.g.

http http://localhost:8080/api/v3/process "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDc4Mzc3NTUsImlkIjpudWxsLCJvcmlnX2lhdCI6MTU0NzgzNDE1NX0.ZcrpD4oRBqG3wUrfnh1DOVpXdUT7dvUnvetKFEVRKKc"
Config
MethodPathDescription
GET/api/v3/configRetrieve the current config without the override values from the environment variables.
GET/api/v3/config/activeRetrieve the current config with the override values from the environment variables are taken into account.
PUT/api/v3/configStore a new config. Only some values are respected, and the new config will only be used after a restart.
GET/api/v3/config/reloadReload the config. The config will be re-read and validated from the store. It will cause a restart of all services.

When retrieving the config via the API, critical values (such as passwords) will be disguised if not required otherwise.

Process

With the process API call, you can manage different FFmpeg processes. A process is defined as:

{    "id": "SomeId",    "reference": "SomeId",    "type": "ffmpeg",    "input": [        {            "id": "inputid",            "address": "rtsp://1.2.3.4/stream.sdp",            "options": [                ... list of input options ...            ]        },        ... list of inputs ...    ],    "output": [        {            "id": "outputid",            "address": "rtmp://rtmp.youtube.com/live2/...",            "options": [                ... list of output options ...            ],            "cleanup": [{                "pattern": "(memfs|diskfs):...",                "max_files: "number,                "max_file_age_seconds": "number",                "purge_on_delete: "(true|false)"            }]        },        ... list of outputs ...    ],    "options": [        ... list of global options ...    ],    "reconnect": (true|false),    "reconnect_delay_seconds": 10,    "autostart": (true|false),    "stale_timeout_seconds": 30}

The input, output, and global options are interpreted as command-line options for FFmpeg.

Process Cleanup

With the optional array of cleanup rules for each output, it is possible to define rules for removing files from thememory filesystem or disk. Each rule consists of a glob pattern and a max. allowed number of files matching that pattern orpermitted maximum age for the files matching that pattern. The pattern starts with eithermemfs: ordiskfs: depending onwhich filesystem this rule is designated to. Then aglob pattern follows toidentify the files. Ifmax_files is set to a number > 0, then the oldest files from the matching files will be deleted ifthe list of matching files is longer than that number. Ifmax_file_age_seconds is set to a number > 0, then all filesthat are older than this number of seconds from the matching files will be deleted. Ifpurge_on_delete is set totrue,then all matching files will be deleted when the process is deleted.

The API calls are

MethodPathDescription
POST/api/v3/processAdds a process. Overwriting an existing ID will result in an error.
GET/api/v3/processRetrieve a list of all known processes. Use the query parameterids to list (comma separated) the IDs of the process you want to be part of the response. If the list is empty, all processes will be listed. Use the query parameterfilter to list (comma separated) the wanted details per process (config,state,log). If the list is empty, all details will be included.
GET/api/v3/process/:idRetreive the details of a process including the config, state, and logs. Use the query parameterfilter to list (comma separated) the wanted details per process (config,state,log). If the list is empty, all details will be included.
PUT/api/v3/process/:idReplaces the process with a new config.
GET/api/v3/process/:id/configRetrieve the config of a process as it was provided.
GET/api/v3/process/:id/stateRetrieve the current state of a process. This includes the progress data if the process is running.
GET/api/v3/process/:id/reportRetrieve the report and logs of a process.
GET/api/v3/process/:id/debugRetrieve an anonymized version of the details of a process.
DELETE/api/v3/process/:idRemove a specific process. Only possible if the process is not running.
PUT/api/v3/process/:id/commandSend a command to a process.
GET/api/v3/process/:id/dataGet all arbitrary JSON data that is stored with this process.
GET/api/v3/process/:id/data/:keyGet arbitrary JSON data that is stored under the keykey.
PUT/api/v3/process/:id/data/:keyStore aribtrary JSON data under the keykey. If the data isnull, the key will be removed.
Commands

A command is defined as:

{    "command": ("start"|"stop"|"restart"|"reload")}
CommandDescription
startStart the process. If the process is already started, this won't have any effect.
stopStop the process. If the process is already stopped, this won't have any effect.
restartRestart the process. If the process is not running, this won't have any effect.
reloadReload the process. If the process was running, the reloaded process will start automatically.
Placeholder

Currently supported placeholders are:

PlaceholderDescriptionLocation
{diskfs}Will be replaced by the providedCORE_STORAGE_DISK_DIR.options,input.address,input.options,output.address,output.options
{memfs}Will be replace by the base URL of the MemFS.input.address,input.options,output.address,output.options
{processid}Will be replaced by the ID of the process.input.id,input.address,input.options,output.id,output.address,output.options,output.cleanup.pattern
{reference}Will be replaced by the reference of the processinput.id,input.address,input.options,output.id,output.address,output.options,output.cleanup.pattern
{inputid}Will be replaced by the ID of the input.input.address,input.options
{outputid}Will be replaced by the ID of the output.output.address,output.options,output.cleanup.pattern

Before replacing the placeholder in the process, all references will be resolved, i.e., you can put the placeholder also in the params for anoption.

References

The input address of a process may contain a reference to the output of another process. It has the form#[processid]:output=[id].

A reference starts with a# followed by the process ID it refers to, followed by a:. Then comesoutput, followed by a=.and the ID of the output.

FFmpeg

Statistics

This repository contains a patch for the FFmpeg program to provide detailed progress information. With this patch, FFmpeg will outputthe progress information in a JSON string that contains the data for each input and output stream individually. The JSON output is enabledby default. It can be enabled with the global-jsonstats switch on the command line. Use the-stats switchon the command line for the standard progress output.

The Docker image that you can build with the provided Dockerfile includes the patched version of FFmpeg for your convenience.

Example output with-stats:

frame=  143 fps= 25 q=-1.0 Lsize=     941kB time=00:00:05.68 bitrate=1357.0kbits/s speed=0.995x

Example output with-jsonstats:

JSONProgress:{"inputs":[{"id":0, "stream":0, "type":"video", "codec":"rawvideo", "coder":"rawvideo", "pix_fmt":"rgb24", "frame":188, "fps":24.95, "width":1280, "height":720, "size_kb":507600, "bitrate_kbps":552960.0},{"id":1, "stream":0, "type":"audio", "codec":"pcm_u8", "coder":"pcm_u8", "frame":314, "sampling_hz":44100, "layout":"stereo", "size_kb":628, "bitrate_kbps":705.6}], "outputs":[{"id":0, "stream":0, "type":"video", "codec":"h264", "coder":"libx264", "pix_fmt":"yuv420p", "frame":188, "fps":24.95, "q":-1.0, "width":1280, "height":720, "size_kb":1247, "bitrate_kbps":1365.6},{"id":0, "stream":1, "type":"audio", "codec":"aac", "coder":"aac", "frame":315, "sampling_hz":44100, "layout":"stereo", "size_kb":2, "bitrate_kbps":2.1}], "frame":188, "fps":24.95, "q":-1.0, "size_kb":1249, "bitrate_kbps":1367.7, "time":"0h0m7.48s", "speed":0.993, "dup":0, "drop":0}

The same output but nicely formatted:

{    "bitrate_kbps": 1367.7,    "drop": 0,    "dup": 0,    "fps": 24.95,    "frame": 188,    "inputs": [        {            "bitrate_kbps": 552960.0,            "codec": "rawvideo",            "coder": "rawvideo",            "fps": 24.95,            "frame": 188,            "height": 720,            "id": 0,            "pix_fmt": "rgb24",            "size_kb": 507600,            "stream": 0,            "type": "video",            "width": 1280        },        {            "bitrate_kbps": 705.6,            "codec": "pcm_u8",            "coder": "pcm_u8",            "frame": 314,            "id": 1,            "layout": "stereo",            "sampling_hz": 44100,            "size_kb": 628,            "stream": 0,            "type": "audio"        }    ],    "outputs": [        {            "bitrate_kbps": 1365.6,            "codec": "h264",            "coder": "libx264",            "fps": 24.95,            "frame": 188,            "height": 720,            "id": 0,            "pix_fmt": "yuv420p",            "q": -1.0,            "size_kb": 1247,            "stream": 0,            "type": "video",            "width": 1280        },        {            "bitrate_kbps": 2.1,            "codec": "aac",            "coder": "aac",            "frame": 315,            "id": 0,            "layout": "stereo",            "sampling_hz": 44100,            "size_kb": 2,            "stream": 1,            "type": "audio"        }    ],    "q": -1.0,    "size_kb": 1249,    "speed": 0.993,    "time": "0h0m7.48s"}
Resilient Streaming

Prepend the input source withavstream:, e.g.... -i avstream:rtsp://1.2.3.4/stream.sdp .... It will reconnect to the stream if it breaks and repeats the last known intraframe until new data from the input stream is available.

Example

Startcore with the proper environment variables. Create a.env file or provide them on the command line. For this example, please use the following command line:

env CORE_API_AUTH_USERNAME=admin CORE_API_AUTH_PASSWORD=datarhei CORE_LOGLEVEL=debug CORE_STORAGE_DISK_DIR=./data ./core

Also, make sure that the directory./data exists. Otherwise, the state will not be stored and will be lost after a restart ofdatarhei/core and the FFmpeg process will not be able to write the files.

In this example, we will add a fake video and audio source. The video will be encoded with H264, and the audio will be encoded with AAC. The output will be an m3u8 stream.

To talk to the API, we use the programhttpie.

First, we create a JSON file with the process definition (e.g.testsrc.json):

{    "id": "testsrc",    "type": "ffmpeg",    "options": ["-loglevel", "info", "-err_detect", "ignore_err"],    "input": [        {            "address": "testsrc=size=1280x720:rate=25",            "id": "video",            "options": ["-f", "lavfi", "-re"]        },        {            "address": "anullsrc=r=44100:cl=stereo",            "id": "audio",            "options": ["-f", "lavfi"]        }    ],    "output": [        {            "address": "http://127.0.0.1:8080/memfs/{processid}_{outputid}.m3u8",            "id": "hls",            "options": [                "-codec:v",                "libx264",                "-preset:v",                "ultrafast",                "-r",                "25",                "-g",                "50",                "-pix_fmt",                "yuv420p",                "-b:v",                "1024k",                "-codec:a",                "aac",                "-b:a",                "64k",                "-hls_time",                "2",                "-hls_list_size",                "10",                "-hls_flags",                "delete_segments+temp_file+append_list",                "-hls_segment_filename",                "http://127.0.0.1:8080/memfs/{processid}_{outputid}_%04d.ts"            ]        }    ],    "reconnect": true,    "reconnect_delay_seconds": 10,    "stale_timeout_seconds": 10}

and POST it to the API:

http POST http://localhost:8080/v3/process < testsrc.json

Then check if it is there (as provided)

http http://localhost:8080/v3/process/testsrc

For the advanced, create another JSON file (e.g.dump.json):

{    "id": "dump",    "type": "ffmpeg",    "options": ["-loglevel", "info", "-err_detect", "ignore_err"],    "input": [        {            "address": "#testsrc:output=hls",            "id": "video",            "options": []        }    ],    "output": [        {            "address": "{diskfs}/{processid}.mp4",            "id": "hls",            "options": ["-codec", "copy", "-y"]        }    ],    "reconnect": true,    "reconnect_delay_seconds": 10,    "stale_timeout_seconds": 10}

and POST it to the API:

http POST http://localhost:8080/v3/process < dump.json

Then check if it is there (as provided)

http http://localhost:8080/v3/process/dump

Let's start thetestsrc process

http PUT http://localhost:8080/v3/process/testsrc/command command=start

Now we can observe the progress of the process

http http://localhost:8080/v3/process/testsrc

or the log of the process

http http://localhost:8080/v3/process/testsrc/log

If you want to change the video bitrate, edit thetestsrc.json file accordingly and replace the process:

http PUT http://localhost:8080/v3/process/testsrc < testsrc.json

It will stop the process, replace the config, and restart it.

Now open, e.g., VLC, and load the streamhttp://localhost:8080/memfs/testsrc_hls.m3u8.

This is enough; let's stop it

http PUT http://localhost:8080/v3/process/testsrc/command command=stop

and check its progress again

HTTP http://localhost:8080/v3/process/testsrc

Delete the process

HTTP DELETE http://localhost:8080/v3/process/testsrc

Metrics

Metrics for the processes and other aspects are provided for a Prometheus scraper on/metrics.

Currently, available metrics are:

MetricTypeDimensionsDescription
ffmpeg_processgaugecore,process,nameGeneral stats per process.
ffmpeg_process_iogaugecore,process,type,id,index,media,nameStats per input and output of a process.
mem_limit_bytesgaugecoreTotal available memory in bytes.
mem_free_bytesgaugecoreFree memory in bytes.
net_rx_bytesgaugecore,interfaceNumber of received bytes by interface.
net_tx_bytesgaugecore,interfaceNumber of sent bytes by interface.
cpus_system_time_secsgaugecore,cpuSystem time per CPU in seconds.
cpus_user_time_secsgaugecore,cpuUser time per CPU in seconds.
cpus_idle_time_secsgaugecore,cpuIdle time per CPU in seconds.
session_totalcountercore,collectorTotal number of sessions by collector.
session_activegaugecore,collectorCurrent number of active sessions by collector.
session_rx_bytescountercore,collectorTotal received bytes by collector.
session_tx_bytescountercore,collectorTotal sent bytes by collector.

Profiling

Profiling information is available under/profiling. Set the environment variableCORE_DEBUG_PROFILING=true to make this endpointavailable. If authentication is enabled, you have to provide the token in the header.

Development

Requirement
Build

Clone the repository and build the binary

git clone git@github.com:datarhei/core.gitcd coremake

After the build process, the binary is available ascore

For more build options, runmake help.

Cross Compile

If you want to run the binary on a different operating system and/or architecture, you create the appropriate binary by simply setting someenvironment variables, e.g.

env GOOS=linux GOARCH=arm go build -o core-linux-armenv GOOS=linux GOARCH=arm64 go build -o core-linux-arm64env GOOS=freebsd GOARCH=amd64 go build -o core-freebsd-amd64env GOOS=windows GOARCH=amd64 go build -o core-windows-amd64env GOOS=macos GOARCH=amd64 go build -o core-macos-amd64...
Docker

Build the Docker image and run it to try out the API

docker build -t core .docker run -it --rm -v ${PWD}/data:/core/data -p 8080:8080 core
API Documentation

The documentation of the API is available on/api/swagger/index.html.

To generate the API documentation from the code, useswag.

go install github.com/swaggo/swag (unless already installed)make swagger
Code style

The source code is formatted withgo fmt, or simply runmake fmt. Static analysis of the source code is done withstaticcheck(seestaticcheck), or simply runmake lint.

Before committing changes, you should runmake commit to ensure that the source code is in shape.

License

datarhei/core is licensed under the Apache License 2.0

Documentation

The Go Gopher

There is no documentation for this package.

Source Files

View all Source files

Directories

PathSynopsis
Package config implements types for handling the configuation for the app.
Package config implements types for handling the configuation for the app.
Package docs GENERATED BY SWAG; DO NOT EDIT This file was generated by swaggo/swag
Package docs GENERATED BY SWAG; DO NOT EDIT This file was generated by swaggo/swag
encoding
json
Package json implements
Package json implements
skills
Package skills provides an easy way to find out which codec, de/muxers, filters, and formats ffmpeg supports and which devices are available for ffmpeg on the system.
Package skills provides an easy way to find out which codec, de/muxers, filters, and formats ffmpeg supports and which devices are available for ffmpeg on the system.
api
Package api provides types for communicating with the REST API
Package api provides types for communicating with the REST API
cors
Package cors implements a validator for CORS origins
Package cors implements a validator for CORS origins
handler/api
Package api implements various handlers for the API routes
Package api implements various handlers for the API routes
jwt/jwks
Package jwks implements a JSON Web Key Set Based on https://github.com/MicahParks/keyfunc without implementing the KeyFunc
Package jwks implements a JSON Web Key Set Based on https://github.com/MicahParks/keyfunc without implementing the KeyFunc
middleware/bodysize
Package bodysize is an echo middleware that fixes the final number of body bytes sent on the wire
Package bodysize is an echo middleware that fixes the final number of body bytes sent on the wire
middleware/cache
Package cache is an in-memory LRU cache middleware
Package cache is an in-memory LRU cache middleware
middleware/log
Package log implements a logging middleware
Package log implements a logging middleware
middleware/mime
mime-type middleware
mime-type middleware
middleware/redirect
Package redirect is an echo middleware that applies defined redirects
Package redirect is an echo middleware that applies defined redirects
middleware/session
Package session is a HLS session middleware for Gin
Package session is a HLS session middleware for Gin
io
fs
Package fs provides a simple interface for a filesystem
Package fs provides a simple interface for a filesystem
Package log provides an opiniated logging facility as it provides only 4 log levels.
Package log provides an opiniated logging facility as it provides only 4 log levels.
math
Package net provides convenience types around types from the golang/net package.
Package net provides convenience types around types from the golang/net package.
Package process is a wrapper of exec.Cmd for controlling a ffmpeg process.
Package process is a wrapper of exec.Cmd for controlling a ffmpeg process.
Package rtmp provides an RTMP server
Package rtmp provides an RTMP server
Package session provides functions to track sessions with a throughput of data
Package session provides functions to track sessions with a throughput of data

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f orF : Jump to
y orY : Canonical URL
go.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.Learn more.

[8]ページ先頭

©2009-2025 Movatter.jp