hls: add primary playlist

This commit is contained in:
aler9 2021-08-16 18:07:10 +02:00
parent ba41af91b2
commit 96cb56621a
5 changed files with 43 additions and 12 deletions

View File

@ -326,10 +326,10 @@ http://localhost:8888/mystream
where `mystream` is the name of a stream that is being published.
The direct HLS URL, that can be used to read the stream with Javascript libraries (hls.js) can be obtained by appending `/stream.m3u8`:
The direct HLS URL, that can be used to read the stream with players (VLC) or Javascript libraries (hls.js) can be obtained by appending `/index.m3u8`:
```
http://localhost:8888/mystream/stream.m3u8
http://localhost:8888/mystream/index.m3u8
```
Please note that most browsers don't support HLS directly (except Safari); a Javascript library, like [hls.js](https://github.com/video-dev/hls.js), must be used to load the stream.

View File

@ -57,7 +57,7 @@ const create = () => {
const video = document.getElementById('video');
if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'stream.m3u8';
video.src = 'index.m3u8';
video.play();
} else {
const hls = new Hls({
@ -74,7 +74,7 @@ const create = () => {
}
});
hls.loadSource('stream.m3u8');
hls.loadSource('index.m3u8');
hls.attachMedia(video);
video.play();
@ -434,9 +434,13 @@ func (r *hlsRemuxer) handleRequest(req hlsRemuxerRequest) {
}
switch {
case req.File == "index.m3u8":
req.W.Header().Set("Content-Type", `application/x-mpegURL`)
req.Res <- r.muxer.PrimaryPlaylist()
case req.File == "stream.m3u8":
req.W.Header().Set("Content-Type", `application/x-mpegURL`)
req.Res <- r.muxer.Playlist()
req.Res <- r.muxer.StreamPlaylist()
case strings.HasSuffix(req.File, ".ts"):
r := r.muxer.TSFile(req.File)

View File

@ -41,7 +41,7 @@ func TestHLSServerRead(t *testing.T) {
time.Sleep(1 * time.Second)
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-i", "http://localhost:8888/test/stream/stream.m3u8",
"-i", "http://localhost:8888/test/stream/index.m3u8",
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
@ -75,7 +75,7 @@ func TestHLSServerReadAuth(t *testing.T) {
time.Sleep(1 * time.Second)
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-i", "http://testuser:testpass@127.0.0.1:8888/teststream/stream.m3u8",
"-i", "http://testuser:testpass@127.0.0.1:8888/teststream/index.m3u8",
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",

View File

@ -2,6 +2,7 @@ package hls
import (
"bytes"
"encoding/hex"
"io"
"math"
"strconv"
@ -208,15 +209,34 @@ func (m *Muxer) WriteAAC(pts time.Duration, aus [][]byte) error {
return nil
}
// Playlist returns a reader to read the playlist.
func (m *Muxer) Playlist() io.Reader {
m.mutex.RLock()
defer m.mutex.RUnlock()
// PrimaryPlaylist returns a reader to read the primary playlist
func (m *Muxer) PrimaryPlaylist() io.Reader {
var codecs []string
if m.videoTrack != nil {
codecs = append(codecs, "avc1."+hex.EncodeToString(m.h264SPS[1:4]))
}
if m.audioTrack != nil {
codecs = append(codecs, "mp4a.40.2")
}
cnt := "#EXTM3U\n"
cnt += "#EXT-X-STREAM-INF:BANDWIDTH=200000,CODECS=\"" + strings.Join(codecs, ",") + "\"\n"
cnt += "stream.m3u8\n"
return bytes.NewReader([]byte(cnt))
}
// StreamPlaylist returns a reader to read the stream playlist.
func (m *Muxer) StreamPlaylist() io.Reader {
cnt := "#EXTM3U\n"
cnt += "#EXT-X-VERSION:3\n"
cnt += "#EXT-X-ALLOW-CACHE:NO\n"
m.mutex.RLock()
defer m.mutex.RUnlock()
targetDuration := func() uint {
ret := uint(math.Ceil(m.hlsSegmentDuration.Seconds()))

View File

@ -64,7 +64,14 @@ func TestMuxer(t *testing.T) {
})
require.NoError(t, err)
byts, err := ioutil.ReadAll(m.Playlist())
byts, err := ioutil.ReadAll(m.PrimaryPlaylist())
require.NoError(t, err)
require.Equal(t, "#EXTM3U\n"+
"#EXT-X-STREAM-INF:BANDWIDTH=200000,CODECS=\"avc1.010203,mp4a.40.2\"\n"+
"stream.m3u8\n", string(byts))
byts, err = ioutil.ReadAll(m.StreamPlaylist())
require.NoError(t, err)
re := regexp.MustCompile(`^#EXTM3U\n` +