Impl. live streaming system: Rough design
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 likeC/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.
- Transcoded stream will be saving series of segment files
- So, In this part i will use exist library.
-
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