Skip to content

Commit 79505cd

Browse files
authored
Merge pull request #17 from m1k1o/hls-vod
(WIP) Hls vod
2 parents 1cfd7d9 + c5e9c47 commit 79505cd

File tree

10 files changed

+1486
-6
lines changed

10 files changed

+1486
-6
lines changed

README.md

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# go-transcode HTTP on-demand transcoding API
22

3+
On demand transcoding of live sources and static files (with seeking).
4+
35
## Why
46

57
Transcoding is expensive and resource consuming operation on CPU and GPU. For big companies with thousands of customers it is essential, to have a dedicated 24/7 transcoding servers which can store all the transcoded versions.
@@ -12,17 +14,21 @@ This feature is common in media centers (plex, jellyfin) but there was no simple
1214

1315
Sources:
1416
- [x] Live streams
15-
- [ ] Static files (basic support)
17+
- [x] VOD (static files, basic support)
1618
- [x] Any codec/container supported by ffmpeg
1719

18-
Outputs:
20+
Live Outputs:
1921
- [x] Basic MP4 over HTTP (h264+aac) : `http://go-transcode/[profile]/[stream-id]`
2022
- [x] Basic HLS over HTTP (h264+aac) : `http://go-transcode/[profile]/[stream-id]/index.m3u8`
2123
- [x] Demo HTML player (for HLS) : `http://go-transcode/[profile]/[stream-id]/play.html`
2224
- [x] HLS proxy : `http://go-transcode/hlsproxy/[hls-proxy-id]/[original-request]`
2325

26+
VOD Outputs:
27+
- [x] HLS master playlist (h264+aac) : `http://go-transcode/vod/[media-path]/index.m3u8`
28+
- [x] HLS custom profile (h264+aac) : `http://go-transcode/vod/[media-path]/[profile].m3u8`
29+
2430
Features:
25-
- [ ] Seeking for static files (index)
31+
- [x] Seeking for static files (indexed vod files)
2632
- [ ] Audio/Subtitles tracks
2733
- [ ] Private mode (serve users authenticated by reverse proxy)
2834

@@ -53,18 +59,58 @@ static: /var/www/html
5359
# TODO: issue #4
5460
proxy: true
5561

62+
# For live streaming
5663
streams:
5764
cam: rtmp://localhost/live/cam
5865
ch1_hd: http://192.168.1.34:9981/stream/channelid/85
5966
ch2_hd: http://192.168.1.34:9981/stream/channelid/43
6067

68+
# For static files
69+
vod:
70+
# Source, where are static files, that will be transcoded
71+
media-dir: ./media
72+
# Temporary transcode output directory, if empty, default tmp folder will be used
73+
transcode-dir: ./transcode
74+
# Available video profiles
75+
video-profiles:
76+
360p:
77+
width: 640 # px
78+
height: 360 # px
79+
bitrate: 800 # kbps
80+
540p:
81+
width: 960
82+
height: 540
83+
bitrate: 1800
84+
720p:
85+
width: 1280
86+
height: 720
87+
bitrate: 2800
88+
1080p:
89+
width: 1920
90+
height: 1080
91+
bitrate: 5000
92+
# Use video keyframes as existing reference for chunks split
93+
# Using this might cause long probing times in order to get
94+
# all keyframes - therefore they should be cached
95+
video-keyframes: false
96+
# Single audio profile used
97+
audio-profile:
98+
bitrate: 192 # kbps
99+
# If cache is enabled
100+
cache: true
101+
# If dir is empty, cache will be stored in the same directory as media source
102+
# If not empty, cache files will be saved to specified directory
103+
cache-dir: ./cache
104+
# Use custom ffmpeg & ffprobe binary paths
105+
ffmpeg-binary: ffmpeg
106+
ffprobe-binary: ffmpeg
107+
61108
# For proxying HLS streams
62109
hls-proxy:
63110
my_server: http://192.168.1.34:9981
64-
65111
```
66112
67-
## Transcoding profiles
113+
## Transcoding profiles for live streams
68114
69115
go-transcode supports any formats that ffmpeg likes. We provide profiles out-of-the-box for h264+aac (mp4 container) for 360p, 540p, 720p and 1080p resolutions: `h264_360p`, `h264_540p`, `h264_720p` and `h264_1080p`. Profiles can have any name, but must match regex: `^[0-9A-Za-z_-]+$`
70116

@@ -160,6 +206,7 @@ The source code is in the following files/folders:
160206

161207
- `cmd/` and `main.go`: source for the command-line interface
162208
- `hls/`: process runner for HLS transcoding
209+
- `hlsvod/`: process runner for HLS VOD transcoding (for static files)
163210
- `internal/`: actual source code logic
164211

165212
*TODO: document different modules/packages and dependencies*

hlsvod/cache.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package hlsvod
2+
3+
import (
4+
"crypto/sha1"
5+
"fmt"
6+
"os"
7+
"path"
8+
)
9+
10+
const cacheFileSuffix = ".go-transcode-cache"
11+
12+
func (m *ManagerCtx) getCacheData() ([]byte, error) {
13+
// check for local cache
14+
localCachePath := m.config.MediaPath + cacheFileSuffix
15+
if _, err := os.Stat(localCachePath); err == nil {
16+
m.logger.Warn().Str("path", localCachePath).Msg("media local cache hit")
17+
return os.ReadFile(localCachePath)
18+
}
19+
20+
// check for global cache
21+
h := sha1.New()
22+
h.Write([]byte(m.config.MediaPath))
23+
hash := h.Sum(nil)
24+
25+
fileName := fmt.Sprintf("%x%s", hash, cacheFileSuffix)
26+
globalCachePath := path.Join(m.config.CacheDir, fileName)
27+
if _, err := os.Stat(globalCachePath); err == nil {
28+
m.logger.Warn().Str("path", globalCachePath).Msg("media global cache hit")
29+
return os.ReadFile(globalCachePath)
30+
}
31+
32+
return nil, os.ErrNotExist
33+
}
34+
35+
func (m *ManagerCtx) saveLocalCacheData(data []byte) error {
36+
localCachePath := m.config.MediaPath + cacheFileSuffix
37+
return os.WriteFile(localCachePath, data, 0755)
38+
}
39+
40+
func (m *ManagerCtx) saveGlobalCacheData(data []byte) error {
41+
h := sha1.New()
42+
h.Write([]byte(m.config.MediaPath))
43+
hash := h.Sum(nil)
44+
45+
fileName := fmt.Sprintf("%x%s", hash, cacheFileSuffix)
46+
globalCachePath := path.Join(m.config.CacheDir, fileName)
47+
return os.WriteFile(globalCachePath, data, 0755)
48+
}

0 commit comments

Comments
 (0)