|  | 
| 5 | 5 | 	"encoding/hex" | 
| 6 | 6 | 	"encoding/xml" | 
| 7 | 7 | 	"errors" | 
| 8 |  | -	"fmt" | 
| 9 | 8 | 	"strings" | 
| 10 | 9 | 	"time" | 
| 11 | 10 | 
 | 
| @@ -126,171 +125,80 @@ type CommonAttributesAndElements struct { | 
| 126 | 125 | 	InbandEventStream         *DescriptorType       `xml:"inbandEventStream,attr"` | 
| 127 | 126 | } | 
| 128 | 127 | 
 | 
|  | 128 | +type contentProtections []ContentProtectioner | 
|  | 129 | + | 
|  | 130 | +func (as *contentProtections) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { | 
|  | 131 | +	var scheme string | 
|  | 132 | +	for _, a := range start.Attr { | 
|  | 133 | +		if a.Name.Local == "schemeIdUri" { | 
|  | 134 | +			scheme = a.Value | 
|  | 135 | +			break | 
|  | 136 | +		} | 
|  | 137 | +	} | 
|  | 138 | +	var target ContentProtectioner | 
|  | 139 | +	switch scheme { | 
|  | 140 | +	case CONTENT_PROTECTION_ROOT_SCHEME_ID_URI: | 
|  | 141 | +		target = &CENCContentProtection{} | 
|  | 142 | +	case CONTENT_PROTECTION_PLAYREADY_SCHEME_ID: | 
|  | 143 | +		target = &PlayreadyContentProtection{} | 
|  | 144 | +	case CONTENT_PROTECTION_WIDEVINE_SCHEME_ID: | 
|  | 145 | +		target = &WidevineContentProtection{} | 
|  | 146 | +	default: | 
|  | 147 | +		target = &ContentProtection{} | 
|  | 148 | +	} | 
|  | 149 | +	if err := d.DecodeElement(target, &start); err != nil { | 
|  | 150 | +		return err | 
|  | 151 | +	} | 
|  | 152 | +	*as = append(*as, target) | 
|  | 153 | +	return nil | 
|  | 154 | +} | 
|  | 155 | + | 
|  | 156 | +// wrappedAdaptationSet provides the default xml unmarshal | 
|  | 157 | +// to take care of the majority of our unmarshalling | 
|  | 158 | +type wrappedAdaptationSet AdaptationSet | 
|  | 159 | + | 
|  | 160 | +// dtoAdaptationSet parses the items out of AdaptationSet | 
|  | 161 | +// that give us trouble: | 
|  | 162 | +// * Content Protection interface | 
|  | 163 | +type dtoAdaptationSet struct { | 
|  | 164 | +	wrappedAdaptationSet | 
|  | 165 | +	ContentProtection contentProtections `xml:"ContentProtection,omitempty"` | 
|  | 166 | +} | 
|  | 167 | + | 
| 129 | 168 | type AdaptationSet struct { | 
| 130 | 169 | 	CommonAttributesAndElements | 
| 131 |  | -	XMLName            xml.Name              `xml:"AdaptationSet"` | 
| 132 |  | -	ID                 *string               `xml:"id,attr"` | 
| 133 |  | -	SegmentAlignment   *bool                 `xml:"segmentAlignment,attr"` | 
| 134 |  | -	Lang               *string               `xml:"lang,attr"` | 
| 135 |  | -	Group              *string               `xml:"group,attr"` | 
| 136 |  | -	PAR                *string               `xml:"par,attr"` | 
| 137 |  | -	MinBandwidth       *string               `xml:"minBandwidth,attr"` | 
| 138 |  | -	MaxBandwidth       *string               `xml:"maxBandwidth,attr"` | 
| 139 |  | -	MinWidth           *string               `xml:"minWidth,attr"` | 
| 140 |  | -	MaxWidth           *string               `xml:"maxWidth,attr"` | 
| 141 |  | -	MinHeight          *string               `xml:"minHeight,attr"` | 
| 142 |  | -	MaxHeight          *string               `xml:"maxHeight,attr"` | 
| 143 |  | -	ContentType        *string               `xml:"contentType,attr"` | 
| 144 |  | -	ContentProtection  []ContentProtectioner `xml:"ContentProtection,omitempty"` // Common attribute, can be deprecated here | 
| 145 |  | -	Roles              []*Role               `xml:"Role,omitempty"` | 
| 146 |  | -	SegmentBase        *SegmentBase          `xml:"SegmentBase,omitempty"` | 
| 147 |  | -	SegmentList        *SegmentList          `xml:"SegmentList,omitempty"` | 
| 148 |  | -	SegmentTemplate    *SegmentTemplate      `xml:"SegmentTemplate,omitempty"` // Live Profile Only | 
| 149 |  | -	Representations    []*Representation     `xml:"Representation,omitempty"` | 
| 150 |  | -	AccessibilityElems []*Accessibility      `xml:"Accessibility,omitempty"` | 
|  | 170 | +	XMLName            xml.Name          `xml:"AdaptationSet"` | 
|  | 171 | +	ID                 *string           `xml:"id,attr"` | 
|  | 172 | +	SegmentAlignment   *bool             `xml:"segmentAlignment,attr"` | 
|  | 173 | +	Lang               *string           `xml:"lang,attr"` | 
|  | 174 | +	Group              *string           `xml:"group,attr"` | 
|  | 175 | +	PAR                *string           `xml:"par,attr"` | 
|  | 176 | +	MinBandwidth       *string           `xml:"minBandwidth,attr"` | 
|  | 177 | +	MaxBandwidth       *string           `xml:"maxBandwidth,attr"` | 
|  | 178 | +	MinWidth           *string           `xml:"minWidth,attr"` | 
|  | 179 | +	MaxWidth           *string           `xml:"maxWidth,attr"` | 
|  | 180 | +	MinHeight          *string           `xml:"minHeight,attr"` | 
|  | 181 | +	MaxHeight          *string           `xml:"maxHeight,attr"` | 
|  | 182 | +	ContentType        *string           `xml:"contentType,attr"` | 
|  | 183 | +	Roles              []*Role           `xml:"Role,omitempty"` | 
|  | 184 | +	SegmentBase        *SegmentBase      `xml:"SegmentBase,omitempty"` | 
|  | 185 | +	SegmentList        *SegmentList      `xml:"SegmentList,omitempty"` | 
|  | 186 | +	SegmentTemplate    *SegmentTemplate  `xml:"SegmentTemplate,omitempty"` // Live Profile Only | 
|  | 187 | +	Representations    []*Representation `xml:"Representation,omitempty"` | 
|  | 188 | +	AccessibilityElems []*Accessibility  `xml:"Accessibility,omitempty"` | 
| 151 | 189 | } | 
| 152 | 190 | 
 | 
| 153 | 191 | func (as *AdaptationSet) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { | 
| 154 |  | -	var ( | 
| 155 |  | -		adaptationSet struct { | 
| 156 |  | -			CommonAttributesAndElements | 
| 157 |  | -			XMLName            xml.Name              `xml:"AdaptationSet"` | 
| 158 |  | -			ID                 *string               `xml:"id,attr"` | 
| 159 |  | -			SegmentAlignment   *bool                 `xml:"segmentAlignment,attr"` | 
| 160 |  | -			Lang               *string               `xml:"lang,attr"` | 
| 161 |  | -			Group              *string               `xml:"group,attr"` | 
| 162 |  | -			PAR                *string               `xml:"par,attr"` | 
| 163 |  | -			MinBandwidth       *string               `xml:"minBandwidth,attr"` | 
| 164 |  | -			MaxBandwidth       *string               `xml:"maxBandwidth,attr"` | 
| 165 |  | -			MinWidth           *string               `xml:"minWidth,attr"` | 
| 166 |  | -			MaxWidth           *string               `xml:"maxWidth,attr"` | 
| 167 |  | -			MinHeight          *string               `xml:"minHeight,attr"` | 
| 168 |  | -			MaxHeight          *string               `xml:"maxHeight,attr"` | 
| 169 |  | -			ContentType        *string               `xml:"contentType,attr"` | 
| 170 |  | -			ContentProtection  []ContentProtectioner `xml:"ContentProtection,omitempty"` // Common attribute, can be deprecated here | 
| 171 |  | -			Roles              []*Role               `xml:"Role,omitempty"` | 
| 172 |  | -			SegmentBase        *SegmentBase          `xml:"SegmentBase,omitempty"` | 
| 173 |  | -			SegmentList        *SegmentList          `xml:"SegmentList,omitempty"` | 
| 174 |  | -			SegmentTemplate    *SegmentTemplate      `xml:"SegmentTemplate,omitempty"` // Live Profile Only | 
| 175 |  | -			Representations    []*Representation     `xml:"Representation,omitempty"` | 
| 176 |  | -			AccessibilityElems []*Accessibility      `xml:"Accessibility,omitempty"` | 
| 177 |  | -		} | 
| 178 |  | -		contentProtectionTags []ContentProtectioner | 
| 179 |  | -		roles                 []*Role | 
| 180 |  | -		segmentBase           *SegmentBase | 
| 181 |  | -		segmentList           *SegmentList | 
| 182 |  | -		segmentTemplate       *SegmentTemplate | 
| 183 |  | -		representations       []*Representation | 
| 184 |  | -	) | 
| 185 |  | - | 
| 186 |  | -	// decode inner elements | 
| 187 |  | -	for { | 
| 188 |  | -		t, err := d.Token() | 
| 189 |  | -		if err != nil { | 
| 190 |  | -			return err | 
| 191 |  | -		} | 
| 192 |  | - | 
| 193 |  | -		switch tt := t.(type) { | 
| 194 |  | -		case xml.StartElement: | 
| 195 |  | -			switch tt.Name.Local { | 
| 196 |  | -			case "ContentProtection": | 
| 197 |  | -				var ( | 
| 198 |  | -					schemeUri string | 
| 199 |  | -					cp        ContentProtectioner | 
| 200 |  | -				) | 
| 201 |  | - | 
| 202 |  | -				for _, attr := range tt.Attr { | 
| 203 |  | -					if attr.Name.Local == "schemeIdUri" { | 
| 204 |  | -						schemeUri = attr.Value | 
| 205 |  | -					} | 
| 206 |  | -				} | 
| 207 |  | -				switch schemeUri { | 
| 208 |  | -				case CONTENT_PROTECTION_ROOT_SCHEME_ID_URI: | 
| 209 |  | -					cp = new(CENCContentProtection) | 
| 210 |  | -				case CONTENT_PROTECTION_PLAYREADY_SCHEME_ID: | 
| 211 |  | -					cp = new(PlayreadyContentProtection) | 
| 212 |  | -				case CONTENT_PROTECTION_WIDEVINE_SCHEME_ID: | 
| 213 |  | -					cp = new(WidevineContentProtection) | 
| 214 |  | -				default: | 
| 215 |  | -					cp = new(ContentProtection) | 
| 216 |  | -				} | 
| 217 |  | - | 
| 218 |  | -				err = d.DecodeElement(cp, &tt) | 
| 219 |  | -				if err != nil { | 
| 220 |  | -					return err | 
| 221 |  | -				} | 
| 222 |  | -				contentProtectionTags = append(contentProtectionTags, cp) | 
| 223 |  | -			case "Role": | 
| 224 |  | -				rl := new(Role) | 
| 225 |  | -				err = d.DecodeElement(rl, &tt) | 
| 226 |  | -				if err != nil { | 
| 227 |  | -					return err | 
| 228 |  | -				} | 
| 229 |  | -				roles = append(roles, rl) | 
| 230 |  | -			case "SegmentBase": | 
| 231 |  | -				sb := new(SegmentBase) | 
| 232 |  | -				err = d.DecodeElement(sb, &tt) | 
| 233 |  | -				if err != nil { | 
| 234 |  | -					return err | 
| 235 |  | -				} | 
| 236 |  | -				segmentBase = sb | 
| 237 |  | -			case "SegmentList": | 
| 238 |  | -				sl := new(SegmentList) | 
| 239 |  | -				err = d.DecodeElement(sl, &tt) | 
| 240 |  | -				if err != nil { | 
| 241 |  | -					return err | 
| 242 |  | -				} | 
| 243 |  | -				segmentList = sl | 
| 244 |  | -			case "SegmentTemplate": | 
| 245 |  | -				st := new(SegmentTemplate) | 
| 246 |  | -				err = d.DecodeElement(st, &tt) | 
| 247 |  | -				if err != nil { | 
| 248 |  | -					return err | 
| 249 |  | -				} | 
| 250 |  | -				segmentTemplate = st | 
| 251 |  | -			case "Representation": | 
| 252 |  | -				rp := new(Representation) | 
| 253 |  | -				err = d.DecodeElement(rp, &tt) | 
| 254 |  | -				if err != nil { | 
| 255 |  | -					return err | 
| 256 |  | -				} | 
| 257 |  | -				representations = append(representations, rp) | 
| 258 |  | -			case "Accessibility": | 
| 259 |  | -				var a Accessibility | 
| 260 |  | -				adaptationSet.AccessibilityElems = append(adaptationSet.AccessibilityElems, &a) | 
| 261 |  | -				if err = d.DecodeElement(&a, &tt); err != nil { | 
| 262 |  | -					return err | 
| 263 |  | -				} | 
| 264 |  | -			case "AudioChannelConfiguration": | 
| 265 |  | -				var dt DescriptorType | 
| 266 |  | -				if err = d.DecodeElement(&dt, &tt); err != nil { | 
| 267 |  | -					return err | 
| 268 |  | -				} | 
| 269 |  | -				adaptationSet.AudioChannelConfiguration = append(adaptationSet.AudioChannelConfiguration, dt) | 
| 270 |  | -			case "SupplementalProperty": | 
| 271 |  | -				var dt DescriptorType | 
| 272 |  | -				if err = d.DecodeElement(&dt, &tt); err != nil { | 
| 273 |  | -					return err | 
| 274 |  | -				} | 
| 275 |  | -				adaptationSet.SupplementalProperty = append(adaptationSet.SupplementalProperty, dt) | 
| 276 |  | -			default: | 
| 277 |  | -				return fmt.Errorf("unrecognized element in AdaptationSet %q", tt.Name.Local) | 
| 278 |  | -			} | 
| 279 |  | -		case xml.EndElement: | 
| 280 |  | -			if tt == start.End() { | 
| 281 |  | -				_ = d.DecodeElement(&adaptationSet, &start) | 
| 282 |  | -				*as = adaptationSet | 
| 283 |  | -				as.ContentProtection = contentProtectionTags | 
| 284 |  | -				as.Roles = roles | 
| 285 |  | -				as.SegmentBase = segmentBase | 
| 286 |  | -				as.SegmentList = segmentList | 
| 287 |  | -				as.SegmentTemplate = segmentTemplate | 
| 288 |  | -				as.Representations = representations | 
| 289 |  | -				return nil | 
| 290 |  | -			} | 
| 291 |  | -		} | 
| 292 |  | - | 
|  | 192 | +	var n dtoAdaptationSet | 
|  | 193 | +	if err := d.DecodeElement(&n, &start); err != nil { | 
|  | 194 | +		return err | 
| 293 | 195 | 	} | 
|  | 196 | +	*as = AdaptationSet(n.wrappedAdaptationSet) | 
|  | 197 | +	as.ContentProtection = make([]ContentProtectioner, len(n.ContentProtection)) | 
|  | 198 | +	for i := range n.ContentProtection { | 
|  | 199 | +		as.ContentProtection[i] = n.ContentProtection[i] | 
|  | 200 | +	} | 
|  | 201 | +	return nil | 
| 294 | 202 | } | 
| 295 | 203 | 
 | 
| 296 | 204 | // Constants for DRM / ContentProtection | 
|  | 
0 commit comments