diff --git a/transcoder/main.go b/transcoder/main.go index 08c19c1a..8cf6db04 100644 --- a/transcoder/main.go +++ b/transcoder/main.go @@ -2,6 +2,7 @@ package main import ( "net/http" + "strconv" "github.com/zoriya/kyoo/transcoder/src" @@ -96,7 +97,10 @@ func (h *Handler) GetVideoIndex(c echo.Context) error { func (h *Handler) GetAudioIndex(c echo.Context) error { resource := c.Param("resource") slug := c.Param("slug") - audio := c.Param("audio") + audio, err := strconv.ParseInt(c.Param("audio"), 10, 32) + if err != nil { + return err + } client, err := GetClientId(c) if err != nil { @@ -108,7 +112,7 @@ func (h *Handler) GetAudioIndex(c echo.Context) error { return err } - ret, err := h.transcoder.GetAudioIndex(path, audio, client) + ret, err := h.transcoder.GetAudioIndex(path, int32(audio), client) if err != nil { return err } @@ -157,7 +161,10 @@ func (h *Handler) GetVideoSegment(c echo.Context) error { func (h *Handler) GetAudioSegment(c echo.Context) error { resource := c.Param("resource") slug := c.Param("slug") - audio := c.Param("audio") + audio, err := strconv.ParseInt(c.Param("audio"), 10, 32) + if err != nil { + return err + } segment, err := ParseSegment(c.Param("chunk")) if err != nil { return err @@ -173,7 +180,7 @@ func (h *Handler) GetAudioSegment(c echo.Context) error { return err } - ret, err := h.transcoder.GetAudioSegment(path, audio, segment, client) + ret, err := h.transcoder.GetAudioSegment(path, int32(audio), segment, client) if err != nil { return err } diff --git a/transcoder/src/audiostream.go b/transcoder/src/audiostream.go new file mode 100644 index 00000000..85968b5e --- /dev/null +++ b/transcoder/src/audiostream.go @@ -0,0 +1,34 @@ +package src + +import ( + "fmt" + "log" +) + +type AudioStream struct { + Stream + index int32 +} + +func NewAudioStream(file *FileStream, idx int32) *AudioStream { + log.Printf("Creating a audio stream %d for %s", idx, file.Path) + ret := new(AudioStream) + ret.index = idx + ret.Stream = NewStream(file, ret) + return ret +} + +func (as *AudioStream) getOutPath() string { + return fmt.Sprintf("%s/segment-a%d-%%03d.ts", as.file.Out, as.index) +} + +func (as *AudioStream) getTranscodeArgs(segments string) []string { + return []string{ + "-map", fmt.Sprintf("0:a:%d", as.index), + "-c:a", "aac", + // TODO: Support 5.1 audio streams. + "-ac", "2", + // TODO: Support multi audio qualities. + "-b:a", "128k", + } +} diff --git a/transcoder/src/filestream.go b/transcoder/src/filestream.go index 9b38cb22..4f9ff3d1 100644 --- a/transcoder/src/filestream.go +++ b/transcoder/src/filestream.go @@ -20,7 +20,8 @@ type FileStream struct { Info *MediaInfo streams map[Quality]*VideoStream vlock sync.RWMutex - // audios map[uint32]*AudioStream + audios map[int32]*AudioStream + alock sync.RWMutex } func GetOutPath() string { @@ -60,6 +61,7 @@ func NewFileStream(path string) (*FileStream, error) { CanTransmux: can_transmux, Info: info.info, streams: make(map[Quality]*VideoStream), + audios: make(map[int32]*AudioStream), }, nil } @@ -211,3 +213,28 @@ func (fs *FileStream) GetVideoSegment(quality Quality, segment int32, client str stream := fs.getVideoStream(quality) return stream.GetSegment(segment, client) } + +func (fs *FileStream) getAudioStream(audio int32) *AudioStream { + fs.alock.RLock() + stream, ok := fs.audios[audio] + fs.alock.RUnlock() + + if ok { + return stream + } + + fs.alock.Lock() + defer fs.alock.Unlock() + fs.audios[audio] = NewAudioStream(fs, audio) + return fs.audios[audio] +} + +func (fs *FileStream) GetAudioIndex(audio int32, client string) (string, error) { + stream := fs.getAudioStream(audio) + return stream.GetIndex(client) +} + +func (fs *FileStream) GetAudioSegment(audio int32, segment int32, client string) (string, error) { + stream := fs.getAudioStream(audio) + return stream.GetSegment(segment, client) +} diff --git a/transcoder/src/stream.go b/transcoder/src/stream.go index bae9651c..b5df1f4c 100644 --- a/transcoder/src/stream.go +++ b/transcoder/src/stream.go @@ -172,7 +172,6 @@ func (ts *Stream) run(start int32) error { // we need this and not a return in the condition because we want to unlock // the lock (and can't defer since this is a loop) if should_stop { - println("close because requested", encoder_id) return } } diff --git a/transcoder/src/transcoder.go b/transcoder/src/transcoder.go index 84b3935c..03d08134 100644 --- a/transcoder/src/transcoder.go +++ b/transcoder/src/transcoder.go @@ -88,8 +88,12 @@ func (t *Transcoder) GetVideoIndex(path string, quality Quality, client string) return stream.GetVideoIndex(quality, client) } -func (t *Transcoder) GetAudioIndex(path string, audio string, client string) (string, error) { - return "", nil +func (t *Transcoder) GetAudioIndex(path string, audio int32, client string) (string, error) { + stream, err := t.getFileStream(path) + if err != nil { + return "", err + } + return stream.GetAudioIndex(audio, client) } func (t *Transcoder) GetVideoSegment( @@ -107,9 +111,13 @@ func (t *Transcoder) GetVideoSegment( func (t *Transcoder) GetAudioSegment( path string, - audio string, + audio int32, segment int32, client string, ) (string, error) { - return "", nil + stream, err := t.getFileStream(path) + if err != nil { + return "", err + } + return stream.GetAudioSegment(audio, segment, client) }