Add transcoder initial idea

This commit is contained in:
2024-04-22 11:39:02 +02:00
parent f3c0015ee3
commit 6757d64c9a

View File

@@ -6,7 +6,7 @@ draft: true
tags: ["ffmpeg", "kyoo"]
---
For [Kyoo](https://github.com/zoriya/kyoo), I need to play video to a variety of clients (from browsers to TVs and mobile apps). Clients does not always support the video codec of the source video since videos are user provided and any valid video should work everywhere.
For [Kyoo](https://github.com/zoriya/kyoo), I need to play video on a variety of clients (browsers, TVs, mobile apps). Clients does not always support the video codec of the source video since videos are user provided. Any valid video should work everywhere. Users should not have to worry about converting videos for Kyoo to work, everything should Work™ the first time.
Users don't always have a stable connection, but they should be able to play their video, even if they are on a train. Those constraints mean that Kyoo needs a service to change videos codec and file size (transcode) on the fly. Why on the fly? Because we don't want users to store all their videos 5 times (the original, a 480p version, a 720p version and so on).
@@ -15,7 +15,7 @@ Users don't always have a stable connection, but they should be able to play the
To put the goal list into text we want a service capable of:
- Streaming a video file
- Allow users to select the video quality
- Allow clients to automatically select the best video quality it can play (and auto-switch)
- Allow clients to automatically select the best video quality it can play (and auto-switch when internet speed changes)
- Prefer the original video if it can be played by the device/connection speed
The last point is particularly important since Kyoo is self-hosted and user's servers are not always powerful enough to always transcode video.
@@ -26,7 +26,7 @@ As for any video services, the following points should also be satisfied:
## The constraints
To allow clients to change quality when the connection's speed changes, two standards exist. HLS and Dash. Both are widely supported and offer the same benefits and constraints. I used HLS, but the two could be used interchangeably without too much issue.
To allow clients to change quality when the connection's speed changes, two standards exist. HLS and Dash. Both are widely supported and offer the same benefits and constraints. I used HLS, but I believe the two could be used interchangeably without too much issue.
I'm going to give you a brief overview of what HLS looks like. It consists of 3 types of files:
@@ -78,8 +78,32 @@ segment-259.ts
</details>
Now that we know what we want, let's talk about what's stopping us from doing what we want.
Now that we know what we want, let's talk about how we could proceed.
## Initial idea
When I think of videos, my first thought initially goes to ffmpeg. As always, ffmpeg does support HLS with the following command:
```bash
ffmpeg -i in.mkv -f hls ...
```
But this approach has a few caveats. The most important one is the time it takes. This command will produce HLS segments one at a time starting from the first. Streaming this file will show users a video of 30s growing untill the command has finished.
![vlc gif of this command playback]
The user can't seek past the transcoded end
If we want to quality switches, we need a command like this:
```bash
ffmpeg -map
```
This command will eagerly transcode the video in all qualities ; killing the server's performances while doing so.
## Wrap ffmpeg
// rust approach: ffmpeg process for each quality on demand => changing qualify restarted the stream at the beginning.
## The bugs of ffmpeg