Kyoo/transcoder/src/transcoder.go
2024-02-19 17:14:41 +01:00

147 lines
2.7 KiB
Go

package src
import (
"os"
"path"
)
type Transcoder struct {
// All file streams currently running, index is file path
streams CMap[string, *FileStream]
clientChan chan ClientInfo
tracker *Tracker
}
func NewTranscoder() (*Transcoder, error) {
out := Settings.Outpath
dir, err := os.ReadDir(out)
if err != nil {
return nil, err
}
for _, d := range dir {
err = os.RemoveAll(path.Join(out, d.Name()))
if err != nil {
return nil, err
}
}
ret := &Transcoder{
streams: NewCMap[string, *FileStream](),
clientChan: make(chan ClientInfo, 10),
}
ret.tracker = NewTracker(ret)
return ret, nil
}
func (t *Transcoder) getFileStream(path string, route string) (*FileStream, error) {
var err error
ret, _ := t.streams.GetOrCreate(path, func() *FileStream {
sha, err := GetHash(path)
if err != nil {
return nil
}
return NewFileStream(path, sha, route)
})
ret.ready.Wait()
if err != nil || ret.err != nil {
t.streams.Remove(path)
return nil, ret.err
}
return ret, nil
}
func (t *Transcoder) GetMaster(path string, client string, route string) (string, error) {
stream, err := t.getFileStream(path, route)
if err != nil {
return "", err
}
t.clientChan <- ClientInfo{
client: client,
path: path,
quality: nil,
audio: -1,
head: -1,
}
return stream.GetMaster(), nil
}
func (t *Transcoder) GetVideoIndex(
path string,
quality Quality,
client string,
route string,
) (string, error) {
stream, err := t.getFileStream(path, route)
if err != nil {
return "", err
}
t.clientChan <- ClientInfo{
client: client,
path: path,
quality: &quality,
audio: -1,
head: -1,
}
return stream.GetVideoIndex(quality)
}
func (t *Transcoder) GetAudioIndex(
path string,
audio int32,
client string,
route string,
) (string, error) {
stream, err := t.getFileStream(path, route)
if err != nil {
return "", err
}
t.clientChan <- ClientInfo{
client: client,
path: path,
audio: audio,
head: -1,
}
return stream.GetAudioIndex(audio)
}
func (t *Transcoder) GetVideoSegment(
path string,
quality Quality,
segment int32,
client string,
route string,
) (string, error) {
stream, err := t.getFileStream(path, route)
if err != nil {
return "", err
}
t.clientChan <- ClientInfo{
client: client,
path: path,
quality: &quality,
audio: -1,
head: segment,
}
return stream.GetVideoSegment(quality, segment)
}
func (t *Transcoder) GetAudioSegment(
path string,
audio int32,
segment int32,
client string,
route string,
) (string, error) {
stream, err := t.getFileStream(path, route)
if err != nil {
return "", err
}
t.clientChan <- ClientInfo{
client: client,
path: path,
audio: audio,
head: segment,
}
return stream.GetAudioSegment(audio, segment)
}