Introduction

In previous post, I select RTMP and HLS with CMAF as a protocol between service and end-users(streamers and viewers).

flowchart LR
p(Streamer)
subgraph Service Provider
i(Ingest)
t(Transcoder)
e(Edge)
end
s(Viewer)
p -->|RTMP| i
i --> t
t --> e
e -->|HLS\CMAF| s

Each layers(Ingest, Transcoder, Edge) have different requirements.

Whole system require Low-Latency, High-Available and Low-Cost.

So, detail system will be like this.

flowchart LR
p(Streamer)
subgraph .
subgraph Ingest Pool
i(Ingest)
end
tq(Transcoder queue)
subgraph Transcoder Pool
t(Transcoder)
end
subgraph Edge
e(Edge server)
cdn(CDN)
end
end
s(Viewer)
p -->|RTMP| i
i --> tq
tq --> t
t --> e
e --> cdn
cdn -->|HLS\CMAF| s

More detail about Systems

Ingest

  • Primary objective is keep hold stream connection and passing into system immidiatly.
  • Only one stream per on stream-key between multiple instances
  • Due to CAP theory, I think Ingest pool require CP system(Consistency, Partition-tolerance)
    • Ingest inbound has low frequecy, keep connection until stream stop.
    • In AP system, if exist duplicated stream-key while syncing, which one is correct?
  • Stream will be passing transcoder queue

Transcoder

  • Require computing power.
  • This layer is due to Adaptive Streaming(such as DASH, HLS).
  • For scale-out, stream will be queuing into Transcoder buffer, and processing in parallel.
  • Transcode need to make varients resolution. for example, HLS examples listing 7 resolution.

Nine H.264 video variants Gear 9 - 1920x1080 @ 7.8 Mbps Gear 8 - 1920x1080 @ 6.0 Mbps Gear 7 - 1920x1080 @ 4.5 Mbps Gear 6 - 1280x720 @ 3.0 Mbps Gear 5 - 960x540 @ 2.0 Mbps Gear 4 - 768x432 @ 1.1 Mbps Gear 3 - 640x360 @ 730 kbps Gear 2 - 480x270 @ 365 kbps Gear 1 - 416x234 @ 145 kbps Apple>Developer>HTTP Live Streaming>Examples

  • Most common, easist way is just using ffmpeg with input RTMP stream and output HLS.
    • For research, I will using ffmpeg library with raw data(AVC NALU; Network Abstraction Layer Unit) and generate CMAF and manifest by own implement.

Edge server

  • Generate playlist
  • Primary topic is CDN caching related and low cost operation.

Choose development stack

  • DRY(Don’t Repeat Yourself), KISS(Keep It Simple, Stupid), YAGNI(You Ain’t Gonna Need It) is main objective.

There is so many programming language is exist, my selection criteria is simple. well-kown, modern, and safety. my country’s common job requirements, Golang is most common in streaming related industry, Kotlin with SpringBoot is hot on mobile app’s backend stack.

But, i select Rust and Golang due to followin reason.

  • For binary protocol related(Ingest, Transcoder), low-latency and reusability are most valuable.

    • Programming language that provide compile-time safety and easily integrate by other language.
    • Directly C/C++ will provide best performance, but it was very deep knowledge base require for code-level optimization with readability
    • Golang is easy syntax, learning curve and support compile into shared library. But, as I know, Some performance critical issues like GC optimization is not well known within some developers. (Require advanced knowledge means know-how is important. but as i know golang’s well known advantage is steep learning curve, it means deeper is hard)
    • Kotlin provide native build. but, I think compile-time evaluation or metaprogramming like macro is well using for archive performance in parsing related. Officially kotlin don’t provide metaprogramming. exist similar way but I think it is not simple.
    • Rust has performance like C/C++ and language level safety. Can be compile as shared library and WebAssembly.
  • For Edge server, easy maintanance and throughput are most valuable.

    • Design as Microservice
    • node is simple and quite fast in these days. but, I want to select compiled language that provide smaller image size.
    • Golang is support compile. Provide simple code, small deployments and well grown eco system(well trained developers)
  • For transcoder, require video processor, codec related. Cover everything is very hard work.

    • So, In this part i will use exist library. FFMPEG
    • Output HLS segments
      • Transcoded stream will be saving series of segment files
        • Segment name is predictable and passing playlist generator latest saved and on progress.
  • For Low-Latency HLS

    • I think media preload is not available due to CDN.
    • Support playlist delta updates

Results

I will implement below step by step

  • RTMP
    • Rust Library
  • FLV
    • Rust Library
  • Router
    • Rust
  • Transcoder
    • Rust
    • FFMPEG
  • CMAF
    • Rust Library
  • Stream Segmenter
    • Rust
    • Transcoder’s Output
  • HLS Playlist Generator and Microservice
    • Golang

References