SVT Encore

repository·master·Indexed 43 days ago

https://github.com/svt/encore

A scalable video transcoding service built on FFmpeg and Spring Boot that wraps FFmpeg functionality in a REST API. It utilizes Redis for job queuing and supports priority-based distribution across worker pools, making it suitable for automated Video On Demand (VOD) pipelines. Key features include reusable YAML transcoding profiles, progress reporting via HTTP callbacks, and support for segmented transcoding.

Tokens
17.3K
Snippets
52
Records
75
Agent score
55%

What's inside SVT Encore

  1. What is SVT Encore

    master

    SVT Encore is a scalable video transcoding service built on FFmpeg and Spring Boot. It provides a REST API to wrap FFmpeg functionality, using Redis to queue transcoding jobs across a horizontally scalable pool of workers.

    Key features include:

    • Job Queuing: Uses Redis to manage and distribute work.
    • Transcoding Profiles: Jobs are defined using reusable YAML profiles.
    • Priority Queues: Ensures urgent work is processed without being blocked by lower-priority tasks.
    • Progress Reporting: Reports job status via HTTP callbacks.

    It is designed for automated pipelines, such as Video On Demand (VOD) workflows.

  2. Overview of SVT Encore

    master

    SVT Encore is a scalable, open-source Transcoding-as-a-Service tool built on FFmpeg and Spring Boot. It provides a REST API to abstract the complexity of FFmpeg, making it suitable for integration into automated VOD (Video On Demand) transcoding pipelines.

    Key Capabilities:

    • Scalable Architecture: Decoupled web API and worker components using Redis-backed job queues.
    • Profile-driven Transcoding: Uses YAML-based profiles with support for dynamic parameters via SpEL expressions.
    • Advanced Features: Supports H.264, H.265, and any FFmpeg-supported codec; thumbnail generation (single and sprite sheets); VMAF quality metrics; and segmented (parallel chunk-based) transcoding.
    • Monitoring: Provides HTTP progress callbacks for job monitoring.
    • Security: Optional basic authentication with user and admin roles.
    • API Exploration: Built-in Swagger UI for testing and exploring the REST API.
  3. How transcoding profiles work in Encore

    master

    Transcoding profiles define the outputs (video, audio, thumbnails) produced for a given job. They are organized using a two-tier system:

    1. Profile Index File: A central YAML file that maps profile names to their specific file paths.
    2. Profile Files: Individual YAML files containing the actual encoding configurations.

    Profile file paths are resolved relative to the location of the index file.

    # profiles.yml (the index file)
    program: program.yml
    archive: archive.yml
    preview: preview.yml
  4. Encore logging and job context

    master

    Encore uses JSON-structured logging via Logback, designed for easy integration with log aggregation tools like ELK or Loki.

    To improve observability, each job can include a logContext map of key-value pairs. These pairs are added to the MDC (Mapped Diagnostic Context) for all log entries related to that specific job, allowing you to filter and correlate logs effectively.

  5. How the SVT Encore architecture works

    master

    Encore operates as a distributed system consisting of two primary services that communicate through a Redis instance. This design allows you to scale the transcoding capacity horizontally by adding more workers.

    Core Components:

    • encore-web (REST API Service): The entry point for clients. It accepts transcoding jobs via REST, serves the Swagger UI, and can optionally process jobs itself. Clients poll this service to check job status.
    • encore-worker (Headless Worker): Polls Redis for new jobs and executes the actual transcoding using FFmpeg. To increase throughput, you can run multiple encore-worker instances.
    • Redis: Acts as the central data store for job data, the job queue, and the pub/sub mechanism used for job cancellation and segmented transcoding progress.
    • FFmpeg: The underlying engine that performs the transcoding. It must be installed on any machine running encore-web (if polling is enabled) or encore-worker.
  6. Reference multiple inputs in a profile using inputLabel

    master

    Jobs can contain multiple inputs, each assigned a unique videoLabel or audioLabel. To target a specific input in your transcoding profile, use the inputLabel field within an encode definition. This allows you to create separate encodes for different source streams (e.g., a main video stream and an alternative audio stream) within a single job.

    // Job with multiple inputs
    {
      "profile": "composite",
      "outputFolder": "/output",
      "baseName": "composite_output",
      "inputs": [
        {
          "type": "AudioVideo",
          "uri": "/input/main_video.mp4",
          "videoLabel": "main",
          "audioLabel": "main"
        },
        {
          "type": "Audio",
          "uri": "/input/alt_audio.wav",
          "audioLabel": "alt"
        }
      ]
    }
    # Profile referencing those labels
    encodes:
      - type: AudioEncode
        bitrate: 128k
        suffix: _STEREO
        inputLabel: main
    
      - type: AudioEncode
        bitrate: 128k
        suffix: _STEREO_ALT
        inputLabel: alt
  7. Reuse encoded output as thumbnail source

    master

    To avoid re-decoding the original source, both ThumbnailEncode and ThumbnailMapEncode can use the decodeOutput field. Set this field to the zero-based index of an earlier entry in the encodes list. The thumbnail will then be generated by decoding that specific entry's output via FFmpeg's loopback decoder.

    This is useful for fixing thumbnail issues in FFmpeg 7+ and improves performance by only decoding the source once.

    encodes:
      - type: X264Encode # index 0
        suffix: _x264_1080
        height: 1080
    
      - type: ThumbnailEncode
        decodeOutput: 0 # reuse the decoded frames of the X264 output
  8. Use libfdk_aac for advanced AAC encoding

    master

    The libfdk_aac codec supports advanced profiles like aac_he and aac_he_v2.

    Warning: libfdk_aac is not included in standard pre-built Docker images due to licensing. If you are using standard images, you must either:

    1. Use the standard aac codec, in which case you must remove profile:a: aac_he and profile:a: aac_he_v2 from your parameters, as they are not supported by the standard encoder.
    2. Use a custom Docker build that includes libfdk_aac.
  9. How audio mix presets work

    master

    Audio mix presets define how audio channels are mapped when converting between channel layouts (e.g., 5.1 surround to stereo). When an AudioEncode performs a conversion, Encore resolves the pan filter in this specific order:

    1. pan-mapping[source][target]: An explicit mapping for that specific source $\rightarrow$ target pair.
    2. default-pan[target]: A default pan filter for the target layout. This is only used for downmixing (where the target has fewer or equal channels than the source).
    3. fallback-to-auto: If true, fall back to FFmpeg's automatic channel mapping.
    4. Error: If no match is found, the encode fails (or is skipped if optional: true).

    Upmixing Note: Upmixing (e.g., stereo to 5.1) generally requires an explicit pan-mapping entry or relying on fallback-to-auto.

    encore-settings:
      encoding:
        audio-mix-presets:
          default:
            fallback-to-auto: true
            default-pan:
              stereo: "FL=FL+0.707*FC+0.707*BL+0.707*SL|FR=FR+0.707*FC+0.707*BR+0.707*SR"
            pan-mapping:
              mono:
                stereo: "FL=0.707*FC|FR=0.707*FC"
  10. Understand the SVT Encore production architecture

    master

    A production deployment of Encore consists of three primary components:

    1. encore-web: The REST API. It can run behind a load balancer for high availability. By default, it also polls for jobs to process them itself. To restrict it to only serving the API and offload all transcoding to workers, set encore-settings.poll-disabled=true.
    2. encore-worker: A headless component that polls a single job from the queue, performs the transcoding, and then exits. You can scale horizontally by running multiple worker instances. To keep a worker polling until the queue is completely empty, set encore-settings.worker-drain-queue=true.
    3. Redis 8+: Acts as the job storage and queue. It must have the JSON and Search modules enabled. For production, ensure persistence is enabled.
  11. How worker scaling and priority queues work

    master

    Encore uses priority queues to prevent long-running, low-priority transcoding jobs from blocking urgent, high-priority jobs.

    Core Concepts

    • Priority Classes: The encore-settings.concurrency setting defines the number of priority queues (classes) in Redis. Each class has its own queue and its own pool of workers.
    • Job Routing: Jobs are routed to a queue based on their priority (0-100). Higher-priority jobs within a class are processed before lower-priority ones in that same class.
    • Worker Behavior:
      • encore-worker uses a single thread and polls a single queue. You must pin a worker to a specific queue using encore-settings.poll-queue.
      • encore-web (with polling enabled) starts one thread per queue.

    For production, it is recommended to run encore-web with poll-disabled: true and dedicate specific encore-worker pods to each priority class to ensure isolation.

    Priority-to-Queue Mapping Example

    With concurrency: 2, the mapping is:

    • Priority 50–100: Queue 0 (High priority)
    • Priority 0–49: Queue 1 (Low priority)

    Note: Queue 0 is always the highest-priority class, and queue concurrency - 1 is always the lowest.

    graph LR
        API[encore-web<br/>poll-disabled: true] --> Redis[(Redis)]
        Redis --> HP[high-priority-worker<br/>poll-queue: 0]
        Redis --> HP2[high-priority-worker<br/>poll-queue: 0]
        Redis --> LP[low-priority-worker<br/>poll-queue: 1]
        Redis --> LP2[low-priority-worker<br/>poll-queue: 1]
  12. Configure progress callbacks

    master

    If you provide a progressCallbackUri when submitting a job, Encore will send HTTP POST requests to that URL with updates.

    Callbacks are sent during the IN_PROGRESS state and when the job reaches a terminal state (SUCCESSFUL, FAILED, or CANCELLED). Callback failures are logged but do not affect the job execution.

    Callback JSON payload:

    {
      "jobId": "fb2baa17-8972-451b-bb1e-1bc773283476",
      "externalId": "my-ref-123",
      "progress": 57,
      "status": "IN_PROGRESS"
    }