mpdparser

package
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 27, 2021 License: MIT Imports: 13 Imported by: 0

README

MPD parser

I have encountered few problems with ffmpeg when playing FRANCE2 content delivered with DASH protocol.

  • manifest.mpd: Invalid data found when processing input (maybe subtitle stream)
  • wrong video size selection
  • HTTP 302 redirection not followed

The idea is to get the MPD from the server and edit it for:

  • follow the redirection to get the licensed content
  • removing the subtitles
  • removing all but best video quality
  • serve this edited mpd to ffmpeg

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetPTasDuration

func GetPTasDuration(pt string) (time.Duration, error)

GetPTasDuration gets presentation time as time.Duration

Types

type AdaptationSet

type AdaptationSet struct {
	ID                        string                     `xml:"id,attr"`
	Group                     string                     `xml:"group,attr,omitempty"`
	ContentType               string                     `xml:"contentType,attr,omitempty"`
	Lang                      string                     `xml:"lang,attr,omitempty,omitempty"`
	SegmentAlignment          string                     `xml:"segmentAlignment,attr,omitempty"`
	AudioSamplingRate         string                     `xml:"audioSamplingRate,attr,omitempty"`
	MimeType                  string                     `xml:"mimeType,attr,omitempty"`
	Codecs                    string                     `xml:"codecs,attr,omitempty"`
	StartWithSAP              string                     `xml:"startWithSAP,attr,omitempty"`
	Par                       string                     `xml:"par,attr,omitempty"`
	MinBandwidth              int                        `xml:"minBandwidth,attr,omitempty"`
	MaxBandwidth              int                        `xml:"maxBandwidth,attr,omitempty"`
	MaxWidth                  int                        `xml:"maxWidth,attr,omitempty"`
	MaxHeight                 int                        `xml:"maxHeight,attr,omitempty"`
	Sar                       string                     `xml:"sar,attr,omitempty"`
	FrameRate                 string                     `xml:"frameRate,attr,omitempty"`
	AudioChannelConfiguration *AudioChannelConfiguration `xml:"AudioChannelConfiguration,omitempty"`
	Role                      []Role                     `xml:"Role,omitempty"`
	SegmentTemplate           *SegmentTemplate           `xml:"SegmentTemplate,omitempty"`
	Representation            []*Representation          `xml:"Representation"`
}

func (*AdaptationSet) GetBestRepresentation

func (a *AdaptationSet) GetBestRepresentation() *Representation

func (*AdaptationSet) GetRepresentationByID

func (a *AdaptationSet) GetRepresentationByID(s string) *Representation

type AudioChannelConfiguration

type AudioChannelConfiguration struct {
	SchemeIdUri string `xml:"schemeIdUri,attr"`
	Value       string `xml:"value,attr"`
}

type MPD

type MPD struct {
	XMLName xml.Name `xml:"urn:mpeg:dash:schema:mpd:2011 MPD"`
	// Xmlns   string   `xml:"xmlns,attr"`
	// XsiName                   string   `xml:"http://www.w3.org/2001/XMLSchema-instance name,attr"`
	SchemaLocation string `xml:"http://www.w3.org/2001/XMLSchema-instance schemaLocation,attr"`
	// Cenc                      string   `xml:"cenc,attr"`
	// Mas                       string   `xml:"xmlns:mas,attr"`
	Type                      string    `xml:"type,attr"`
	MediaPresentationDuration string    `xml:"mediaPresentationDuration,attr"`
	MaxSegmentDuration        string    `xml:"maxSegmentDuration,attr"`
	MinBufferTime             string    `xml:"minBufferTime,attr"`
	Profiles                  string    `xml:"profiles,attr"`
	Period                    []*Period `xml:"Period"`
}

type MPDParser

type MPDParser struct {
	*MPD
	ActualURL string
}

MPDParser holds the MPD structure

func NewMPDParser

func NewMPDParser() *MPDParser

NewMPDParser allocate a new MPD parser

func (*MPDParser) AbsolutizeURLs

func (p *MPDParser) AbsolutizeURLs(base string) error

AbsolutizeURLs change relative urls to absolute Either there is a BaseURL, and we have to make it absolute. In this case, segment templates should be relative Either there isn't BasURL. Then if Segments templates are relative to MDP's URI Check BaseURL or SegmentTemplates

func (*MPDParser) Get

func (p *MPDParser) Get(ctx context.Context, url string) error

Get queries the webserver, remember the redirected location and get the MPD

func (*MPDParser) KeepBestVideoStream

func (p *MPDParser) KeepBestVideoStream() error

KeepBestVideoStream discard all video stream but the one with the highest bandwidth

func (*MPDParser) Marshal

func (p *MPDParser) Marshal() ([]byte, error)

func (*MPDParser) MediaURIs

func (mpd *MPDParser) MediaURIs(ManifestURL string, p *Period, a *AdaptationSet, r *Representation) (SegmentIterator, error)

func (*MPDParser) Read

func (p *MPDParser) Read(rc io.ReadCloser) error

Read the MPD from the reader and close it

func (*MPDParser) StripSTPPStream

func (p *MPDParser) StripSTPPStream() error

StripSTPPStream isn't correctly handeld by FFMPEG at writing time

func (*MPDParser) Unmarshal

func (p *MPDParser) Unmarshal(b []byte) error

Unmarshal bytes as MPD

func (*MPDParser) Write

func (p *MPDParser) Write(wc io.WriteCloser) error

Write the MPD to the writer and close it

type Period

type Period struct {
	ID            string           `xml:"id,attr,omitempty"`
	Duration      string           `xml:"duration,attr,omitempty"`
	BaseURL       string           `xml:"BaseURL,omitempty"`
	AdaptationSet []*AdaptationSet `xml:"AdaptationSet"`
}

func (*Period) GetAdaptationSetByContentType

func (p *Period) GetAdaptationSetByContentType(s string) *AdaptationSet

func (*Period) GetAdaptationSetByID

func (p *Period) GetAdaptationSetByID(s string) *AdaptationSet

func (*Period) GetAdaptationSetByMimeType

func (p *Period) GetAdaptationSetByMimeType(s string) *AdaptationSet

type Representation

type Representation struct {
	ID        string `xml:"id,attr"`
	Bandwidth int    `xml:"bandwidth,attr,omitempty"`
	Width     int    `xml:"width,attr,omitempty"`
	Height    int    `xml:"height,attr,omitempty"`
	Codecs    string `xml:"codecs,attr,omitempty"`
	ScanType  string `xml:"scanType,attr,omitempty"`
}

type Role

type Role struct {
	SchemeIdUri string `xml:"schemeIdUri,attr"`
	Value       string `xml:"value,attr"`
}

type SegmentItem

type SegmentItem struct {
	S        string
	Position segmentPostion
	Err      error
}

type SegmentIterator

type SegmentIterator interface {
	Next() <-chan SegmentItem // Call it until error == io.EOF
	Cancel()                  // To stop the iterator before the end
	Err() error
	Content() string
	Lang() string
}

type SegmentTemplate

type SegmentTemplate struct {
	Timescale       int    `xml:"timescale,attr"`
	Duration        int    `xml:"duration,attr,omitempty"`
	StartNumber     int    `xml:"startNumber,attr,omitempty"`
	Initialization  string `xml:"initialization,attr"`
	Media           string `xml:"media,attr"`
	SegmentTimeline struct {
		S []struct {
			N int `xml:"n,attr,omitempty"`
			T int `xml:"t,attr,omitempty"`
			D int `xml:"d,attr,omitempty"`
			R int `xml:"r,attr,omitempty"`
		} `xml:"S"`
	} `xml:" ,omitempty"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL