From 9fad5da0a4746a07c1e25522713ecb6c0db97226 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Mon, 1 Jul 2024 17:20:29 +0000 Subject: [PATCH] Create different index.m3u8 for audio and video --- transcoder/src/audiostream.go | 26 +++++++++++++++++++++++++ transcoder/src/filestream.go | 36 +++++++++++++++++------------------ transcoder/src/stream.go | 29 +--------------------------- transcoder/src/videostream.go | 28 +++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 46 deletions(-) diff --git a/transcoder/src/audiostream.go b/transcoder/src/audiostream.go index 23452a4f..0dc2af74 100644 --- a/transcoder/src/audiostream.go +++ b/transcoder/src/audiostream.go @@ -36,3 +36,29 @@ func (as *AudioStream) getTranscodeArgs(segments string) []string { "-b:a", "128k", } } + +func (ts *AudioStream) GetIndex() (string, error) { + index := `#EXTM3U +#EXT-X-VERSION:7 +#EXT-X-PLAYLIST-TYPE:EVENT +#EXT-X-START:TIME-OFFSET=0 +#EXT-X-MEDIA-SEQUENCE:0 +#EXT-X-INDEPENDENT-SEGMENTS +#EXT-X-MAP:URI="init.mp4" +` + index += fmt.Sprintf("#EXT-X-TARGETDURATION:%d\n", int(OptimalFragmentDuration)+1) + + count := int32((float64(ts.file.Info.Duration) / OptimalFragmentDuration)) + for segment := int32(0); segment < count; segment++ { + index += fmt.Sprintf("#EXTINF:%.6f\n", OptimalFragmentDuration) + index += fmt.Sprintf("segment-%d.m4s\n", segment) + } + + last_ts := float64(count) * OptimalFragmentDuration + if last_ts > 0 { + index += fmt.Sprintf("#EXTINF:%.6f\n", float64(ts.file.Info.Duration)-last_ts) + index += fmt.Sprintf("segment-%d.m4s\n", count) + } + index += `#EXT-X-ENDLIST` + return index, nil +} diff --git a/transcoder/src/filestream.go b/transcoder/src/filestream.go index 08c81664..4c4660b9 100644 --- a/transcoder/src/filestream.go +++ b/transcoder/src/filestream.go @@ -114,24 +114,24 @@ func (fs *FileStream) GetMaster() string { } } } - // for _, audio := range fs.Info.Audios { - // master += "#EXT-X-MEDIA:TYPE=AUDIO," - // master += "GROUP-ID=\"audio\"," - // if audio.Language != nil { - // master += fmt.Sprintf("LANGUAGE=\"%s\",", *audio.Language) - // } - // if audio.Title != nil { - // master += fmt.Sprintf("NAME=\"%s\",", *audio.Title) - // } else if audio.Language != nil { - // master += fmt.Sprintf("NAME=\"%s\",", *audio.Language) - // } else { - // master += fmt.Sprintf("NAME=\"Audio %d\",", audio.Index) - // } - // if audio.IsDefault { - // master += "DEFAULT=YES," - // } - // master += fmt.Sprintf("URI=\"./audio/%d/index.m3u8\"\n", audio.Index) - // } + for _, audio := range fs.Info.Audios { + master += "#EXT-X-MEDIA:TYPE=AUDIO," + master += "GROUP-ID=\"audio\"," + if audio.Language != nil { + master += fmt.Sprintf("LANGUAGE=\"%s\",", *audio.Language) + } + if audio.Title != nil { + master += fmt.Sprintf("NAME=\"%s\",", *audio.Title) + } else if audio.Language != nil { + master += fmt.Sprintf("NAME=\"%s\",", *audio.Language) + } else { + master += fmt.Sprintf("NAME=\"Audio %d\",", audio.Index) + } + if audio.IsDefault { + master += "DEFAULT=YES," + } + master += fmt.Sprintf("URI=\"./audio/%d/index.m3u8\"\n", audio.Index) + } return master } diff --git a/transcoder/src/stream.go b/transcoder/src/stream.go index 7cdcd013..602f1cfc 100644 --- a/transcoder/src/stream.go +++ b/transcoder/src/stream.go @@ -26,6 +26,7 @@ type StreamHandle interface { getTranscodeArgs(segments string) []string getSegmentName() string getFlags() Flags + GetIndex() (string, error) } type Stream struct { @@ -377,34 +378,6 @@ func (ts *Stream) run(start int32) error { return nil } -func (ts *Stream) GetIndex() (string, error) { - // playlist type is event since we can append to the list if Keyframe.IsDone is false. - // start time offset makes the stream start at 0s instead of ~3segments from the end (requires version 6 of hls) - index := `#EXTM3U -#EXT-X-VERSION:7 -#EXT-X-PLAYLIST-TYPE:EVENT -#EXT-X-START:TIME-OFFSET=0 -#EXT-X-MEDIA-SEQUENCE:0 -#EXT-X-INDEPENDENT-SEGMENTS -#EXT-X-MAP:URI="init.mp4" -` - index += fmt.Sprintf("#EXT-X-TARGETDURATION:%d\n", int(OptimalFragmentDuration)) - length, is_done := ts.file.Keyframes.Length() - - for segment := int32(0); segment < length-1; segment++ { - index += fmt.Sprintf("#EXTINF:%.6f\n", ts.file.Keyframes.Get(segment+1)-ts.file.Keyframes.Get(segment)) - index += fmt.Sprintf("segment-%d.m4s\n", segment) - } - // do not forget to add the last segment between the last keyframe and the end of the file - // if the keyframes extraction is not done, do not bother to add it, it will be retrieval on the next index retrieval - if is_done { - index += fmt.Sprintf("#EXTINF:%.6f\n", float64(ts.file.Info.Duration)-ts.file.Keyframes.Get(length-1)) - index += fmt.Sprintf("segment-%d.m4s\n", length-1) - index += `#EXT-X-ENDLIST` - } - return index, nil -} - func (ts *Stream) GetInit() (string, error) { // No need to lock, the channel won't change. select { diff --git a/transcoder/src/videostream.go b/transcoder/src/videostream.go index 80ea8b7a..dd80901c 100644 --- a/transcoder/src/videostream.go +++ b/transcoder/src/videostream.go @@ -72,3 +72,31 @@ func (vs *VideoStream) getTranscodeArgs(segments string) []string { ) return args } + +func (ts *VideoStream) GetIndex() (string, error) { + // playlist type is event since we can append to the list if Keyframe.IsDone is false. + // start time offset makes the stream start at 0s instead of ~3segments from the end (requires version 6 of hls) + index := `#EXTM3U +#EXT-X-VERSION:7 +#EXT-X-PLAYLIST-TYPE:EVENT +#EXT-X-START:TIME-OFFSET=0 +#EXT-X-MEDIA-SEQUENCE:0 +#EXT-X-INDEPENDENT-SEGMENTS +#EXT-X-MAP:URI="init.mp4" +` + index += fmt.Sprintf("#EXT-X-TARGETDURATION:%d\n", int(OptimalFragmentDuration)+1) + length, is_done := ts.file.Keyframes.Length() + + for segment := int32(0); segment < length-1; segment++ { + index += fmt.Sprintf("#EXTINF:%.6f\n", ts.file.Keyframes.Get(segment+1)-ts.file.Keyframes.Get(segment)) + index += fmt.Sprintf("segment-%d.m4s\n", segment) + } + // do not forget to add the last segment between the last keyframe and the end of the file + // if the keyframes extraction is not done, do not bother to add it, it will be retrieval on the next index retrieval + if is_done { + index += fmt.Sprintf("#EXTINF:%.6f\n", float64(ts.file.Info.Duration)-ts.file.Keyframes.Get(length-1)) + index += fmt.Sprintf("segment-%d.m4s\n", length-1) + index += `#EXT-X-ENDLIST` + } + return index, nil +}