Files
gortsplib/pkg/media/medias.go
Alessandro Ros a1396206b5 convert Tracks into Medias and Formats (#155)
* split tracks from medias

* move tracks into dedicated package

* move media into dedicated package

* edit Medias.Marshal() in order to return SDP

* add medias.Find() and simplify examples

* improve coverage

* fix rebase errors

* replace TrackIDs with MediaIDs

* implement media-specific and track-specific callbacks for reading RTCP and RTP packets

* rename publish into record, read into play

* add v2 tag

* rename tracks into formats
2022-12-11 22:03:22 +01:00

105 lines
2.3 KiB
Go

package media
import (
"fmt"
"reflect"
"strconv"
psdp "github.com/pion/sdp/v3"
"github.com/aler9/gortsplib/v2/pkg/sdp"
)
// Medias is a list of media streams.
type Medias []*Media
// Unmarshal decodes medias from the SDP format.
func (ms *Medias) Unmarshal(mds []*psdp.MediaDescription) error {
*ms = make(Medias, len(mds))
for i, md := range mds {
var m Media
err := m.unmarshal(md)
if err != nil {
return fmt.Errorf("media %d is invalid: %v", i+1, err)
}
(*ms)[i] = &m
}
return nil
}
// Marshal encodes the medias in SDP format.
func (ms Medias) Marshal(multicast bool) *sdp.SessionDescription {
var address string
if multicast {
address = "224.1.0.0"
} else {
address = "0.0.0.0"
}
sout := &sdp.SessionDescription{
SessionName: psdp.SessionName("Stream"),
Origin: psdp.Origin{
Username: "-",
NetworkType: "IN",
AddressType: "IP4",
UnicastAddress: "127.0.0.1",
},
// required by Darwin Streaming Server
ConnectionInformation: &psdp.ConnectionInformation{
NetworkType: "IN",
AddressType: "IP4",
Address: &psdp.Address{Address: address},
},
TimeDescriptions: []psdp.TimeDescription{
{Timing: psdp.Timing{StartTime: 0, StopTime: 0}},
},
MediaDescriptions: make([]*psdp.MediaDescription, len(ms)),
}
for i, media := range ms {
sout.MediaDescriptions[i] = media.Marshal()
}
return sout
}
// Clone clones the media list.
func (ms Medias) Clone() Medias {
ret := make(Medias, len(ms))
for i, media := range ms {
ret[i] = media.Clone()
}
return ret
}
// CloneAndSetControls clones the media list and sets the control attribute
// of all medias in the list.
func (ms Medias) CloneAndSetControls() Medias {
ret := ms.Clone()
ret.SetControls()
return ret
}
// SetControls sets the control attribute of all medias in the list.
func (ms Medias) SetControls() {
for i, media := range ms {
media.Control = "mediaID=" + strconv.FormatInt(int64(i), 10)
}
}
// Find finds a certain format among all the formats in all the medias.
// If the format is found, it is inserted into trak, and format media is returned.
func (ms *Medias) Find(trak interface{}) *Media {
for _, media := range *ms {
for _, trakk := range media.Formats {
if reflect.TypeOf(trakk) == reflect.TypeOf(trak).Elem() {
reflect.ValueOf(trak).Elem().Set(reflect.ValueOf(trakk))
return media
}
}
}
return nil
}