mirror of
https://github.com/bluenviron/mediamtx
synced 2025-02-04 13:42:57 +00:00
e5ab731d14
* hls source: support fMP4s video streams * hls source: start reading live streams from (end of playlist - starting point) * hls client: wait processing of current fMP4 segment before downloading another one * hls client: support fmp4 trun boxes with default sample duration, flags and size * hls client: merge fmp4 init file reader and writer * hls client: merge fmp4 part reader and writer * hls client: improve precision of go <-> mp4 time conversion * hls client: fix esds generation in go-mp4 * hls client: support audio in separate playlist * hls client: support an arbitrary number of tracks in fmp4 init files * hls client: support EXT-X-BYTERANGE * hls client: support fmp4 segments with multiple parts at once * hls client: support an arbitrary number of mpeg-ts tracks * hls client: synchronize tracks around a primary track * update go-mp4 * hls: synchronize track reproduction around a leading one * hls client: reset stream if playback is too late * hls client: add limit on DTS-RTC difference * hls client: support again streams that don't provide codecs in master playlist
102 lines
2.0 KiB
Go
102 lines
2.0 KiB
Go
package mpegts
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/aler9/gortsplib"
|
|
"github.com/aler9/gortsplib/pkg/mpeg4audio"
|
|
"github.com/asticode/go-astits"
|
|
)
|
|
|
|
func findMPEG4AudioConfig(dem *astits.Demuxer, pid uint16) (*mpeg4audio.Config, error) {
|
|
for {
|
|
data, err := dem.NextData()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if data.PES == nil || data.PID != pid {
|
|
continue
|
|
}
|
|
|
|
var adtsPkts mpeg4audio.ADTSPackets
|
|
err = adtsPkts.Unmarshal(data.PES.Data)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to decode ADTS: %s", err)
|
|
}
|
|
|
|
pkt := adtsPkts[0]
|
|
return &mpeg4audio.Config{
|
|
Type: pkt.Type,
|
|
SampleRate: pkt.SampleRate,
|
|
ChannelCount: pkt.ChannelCount,
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
// Track is a MPEG-TS track.
|
|
type Track struct {
|
|
ES *astits.PMTElementaryStream
|
|
Track gortsplib.Track
|
|
}
|
|
|
|
// FindTracks finds the tracks in a MPEG-TS stream.
|
|
func FindTracks(byts []byte) ([]*Track, error) {
|
|
var tracks []*Track
|
|
dem := astits.NewDemuxer(context.Background(), bytes.NewReader(byts))
|
|
|
|
for {
|
|
data, err := dem.NextData()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if data.PMT != nil {
|
|
for _, es := range data.PMT.ElementaryStreams {
|
|
switch es.StreamType {
|
|
case astits.StreamTypeH264Video,
|
|
astits.StreamTypeAACAudio:
|
|
default:
|
|
return nil, fmt.Errorf("track type %d not supported (yet)", es.StreamType)
|
|
}
|
|
|
|
tracks = append(tracks, &Track{
|
|
ES: es,
|
|
})
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
if tracks == nil {
|
|
return nil, fmt.Errorf("no tracks found")
|
|
}
|
|
|
|
for _, t := range tracks {
|
|
switch t.ES.StreamType {
|
|
case astits.StreamTypeH264Video:
|
|
t.Track = &gortsplib.TrackH264{
|
|
PayloadType: 96,
|
|
}
|
|
|
|
case astits.StreamTypeAACAudio:
|
|
conf, err := findMPEG4AudioConfig(dem, t.ES.ElementaryPID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
t.Track = &gortsplib.TrackMPEG4Audio{
|
|
PayloadType: 96,
|
|
Config: conf,
|
|
SizeLength: 13,
|
|
IndexLength: 3,
|
|
IndexDeltaLength: 3,
|
|
}
|
|
}
|
|
}
|
|
|
|
return tracks, nil
|
|
}
|