Skip to content

Commit

Permalink
muxer: print error in case generation of init.mp4 fails
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 committed Apr 16, 2023
1 parent 4d3c08c commit 62dca14
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 40 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ https://pkg.go.dev/github.com/bluenviron/gohlslib#pkg-index

## Standards

* [RFC2616, HTTP 1.1](https://datatracker.ietf.org/doc/html/rfc2616)
* [RFC8216, HLS](https://datatracker.ietf.org/doc/html/rfc8216)
* [HLS v2](https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis)
* [ITU-T Rec. H.264 (08/2021)](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.264-202108-I!!PDF-E&type=items)
* [ITU-T Rec. H.265 (08/2021)](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.265-202108-I!!PDF-E&type=items)
* ISO 14496-3, Coding of audio-visual objects, part 3, Audio
* [Opus in MP4/ISOBMFF](https://opus-codec.org/docs/opus_in_isobmff.html)
* [RFC2616, HTTP 1.1](https://datatracker.ietf.org/doc/html/rfc2616)
* [Golang project layout](https://github.com/golang-standards/project-layout)

## Links
Expand Down
39 changes: 27 additions & 12 deletions muxer.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,17 @@ func (m *Muxer) Start() error {
m.storageFactory = storage.NewFactoryRAM()
}

m.server = newMuxerServer(
var err error
m.server, err = newMuxerServer(
m.Variant,
m.SegmentCount,
m.VideoTrack,
m.AudioTrack,
m.storageFactory,
)
if err != nil {
return err
}

if m.Variant == MuxerVariantMPEGTS {
m.segmenter = newMuxerSegmenterMPEGTS(
Expand Down Expand Up @@ -203,11 +207,17 @@ func (m *Muxer) WriteH26x(ntp time.Time, pts time.Duration, au [][]byte) error {
}

if update {
m.server.mutex.Lock()
tcodec.SPS = sps
tcodec.PPS = pps
m.server.generateInitFile()
m.server.mutex.Unlock()
err := func() error {
m.server.mutex.Lock()
defer m.server.mutex.Unlock()
tcodec.SPS = sps
tcodec.PPS = pps
return m.server.generateInitFile()
}()
if err != nil {
return fmt.Errorf("unable to generate init.mp4: %v", err)
}

m.forceSwitch = true
}

Expand Down Expand Up @@ -249,12 +259,17 @@ func (m *Muxer) WriteH26x(ntp time.Time, pts time.Duration, au [][]byte) error {
}

if update {
m.server.mutex.Lock()
tcodec.VPS = vps
tcodec.SPS = sps
tcodec.PPS = pps
m.server.generateInitFile()
m.server.mutex.Unlock()
err := func() error {
m.server.mutex.Lock()
defer m.server.mutex.Unlock()
tcodec.VPS = vps
tcodec.SPS = sps
tcodec.PPS = pps
return m.server.generateInitFile()
}()
if err != nil {
return fmt.Errorf("unable to generate init.mp4: %v", err)
}
m.forceSwitch = true
}
}
Expand Down
76 changes: 51 additions & 25 deletions muxer_server.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gohlslib

import (
"fmt"
"io"
"math"
"net/http"
Expand Down Expand Up @@ -64,6 +65,17 @@ func partTargetDuration(
return time.Millisecond * time.Duration(math.Ceil(float64(ret)/float64(time.Millisecond)))
}

func videoHasParameters(videoTrack *Track) bool {
switch tcodec := videoTrack.Codec.(type) {
case *codecs.H264:
return tcodec.SPS != nil && tcodec.PPS != nil

case *codecs.H265:
return tcodec.VPS != nil && tcodec.SPS != nil && tcodec.PPS != nil
}
return false
}

type muxerServer struct {
variant MuxerVariant
segmentCount int
Expand All @@ -90,7 +102,7 @@ func newMuxerServer(
videoTrack *Track,
audioTrack *Track,
storageFactory storage.Factory,
) *muxerServer {
) (*muxerServer, error) {
s := &muxerServer{
variant: variant,
segmentCount: segmentCount,
Expand All @@ -103,9 +115,14 @@ func newMuxerServer(

s.cond = sync.NewCond(&s.mutex)

s.generateInitFile()
if s.videoTrack == nil || videoHasParameters(s.videoTrack) {
err := s.generateInitFile()
if err != nil {
return nil, fmt.Errorf("unable to generate init.mp4: %v", err)
}
}

return s
return s, nil
}

func (s *muxerServer) close() {
Expand Down Expand Up @@ -220,25 +237,31 @@ func (s *muxerServer) handleMultistreamPlaylist(w http.ResponseWriter) {
case *codecs.H264:
var sps h264.SPS
err := sps.Unmarshal(tcodec.SPS)
if err == nil {
resolution = strconv.FormatInt(int64(sps.Width()), 10) + "x" + strconv.FormatInt(int64(sps.Height()), 10)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return nil
}

f := sps.FPS()
if f != 0 {
frameRate = &f
}
resolution = strconv.FormatInt(int64(sps.Width()), 10) + "x" + strconv.FormatInt(int64(sps.Height()), 10)

f := sps.FPS()
if f != 0 {
frameRate = &f
}

case *codecs.H265:
var sps h265.SPS
err := sps.Unmarshal(tcodec.SPS)
if err == nil {
resolution = strconv.FormatInt(int64(sps.Width()), 10) + "x" + strconv.FormatInt(int64(sps.Height()), 10)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return nil
}

f := sps.FPS()
if f != 0 {
frameRate = &f
}
resolution = strconv.FormatInt(int64(sps.Width()), 10) + "x" + strconv.FormatInt(int64(sps.Height()), 10)

f := sps.FPS()
if f != 0 {
frameRate = &f
}
}
}
Expand Down Expand Up @@ -526,18 +549,21 @@ func (s *muxerServer) handleInitFile(w http.ResponseWriter) {
return s.init
}()

if init != nil {
r, err := init.Reader()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer r.Close()
if init == nil {
w.WriteHeader(http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "video/mp4")
w.WriteHeader(http.StatusOK)
io.Copy(w, r)
r, err := init.Reader()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer r.Close()

w.Header().Set("Content-Type", "video/mp4")
w.WriteHeader(http.StatusOK)
io.Copy(w, r)
}

func (s *muxerServer) handleSegmentOrPart(fname string, w http.ResponseWriter) {
Expand Down
3 changes: 1 addition & 2 deletions muxer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ func TestMuxerVideoAudio(t *testing.T) {
// access unit without IDR
d := 1 * time.Second
err = m.WriteH26x(testTime.Add(d-1*time.Second), d, [][]byte{
{0x06},
{0x07},
{1}, // non-IDR
})
require.NoError(t, err)

Expand Down

0 comments on commit 62dca14

Please sign in to comment.