@@ -26,11 +26,6 @@ shaka.ads.Utils = class {
26
26
/** @type {!Array.<shaka.extern.AdInterstitial> } */
27
27
const interstitials = [ ] ;
28
28
29
- let startTime = 0 ;
30
- if ( currentTime != null ) {
31
- startTime = currentTime ;
32
- }
33
-
34
29
for ( const ad of TXml . findChildren ( vast , 'Ad' ) ) {
35
30
const inline = TXml . findChild ( ad , 'InLine' ) ;
36
31
if ( ! inline ) {
@@ -42,65 +37,156 @@ shaka.ads.Utils = class {
42
37
}
43
38
for ( const creative of TXml . findChildren ( creatives , 'Creative' ) ) {
44
39
const linear = TXml . findChild ( creative , 'Linear' ) ;
45
- if ( ! linear ) {
46
- continue ;
40
+ if ( linear ) {
41
+ shaka . ads . Utils . processLinearAd_ (
42
+ interstitials , currentTime , linear ) ;
47
43
}
48
- let skipOffset = null ;
49
- if ( linear . attributes [ 'skipoffset' ] ) {
50
- skipOffset = shaka . util . TextParser . parseTime (
51
- linear . attributes [ 'skipoffset' ] ) ;
52
- if ( isNaN ( skipOffset ) ) {
53
- skipOffset = null ;
44
+ const nonLinearAds = TXml . findChild ( creative , 'NonLinearAds' ) ;
45
+ if ( nonLinearAds ) {
46
+ const nonLinears = TXml . findChildren ( nonLinearAds , 'NonLinear' ) ;
47
+ for ( const nonLinear of nonLinears ) {
48
+ shaka . ads . Utils . processNonLinearAd_ (
49
+ interstitials , currentTime , nonLinear ) ;
54
50
}
55
51
}
56
- const mediaFiles = TXml . findChild ( linear , 'MediaFiles' ) ;
57
- if ( ! mediaFiles ) {
58
- continue ;
59
- }
60
- const medias = TXml . findChildren ( mediaFiles , 'MediaFile' ) ;
61
- let checkMedias = medias ;
62
- const streamingMedias = medias . filter ( ( media ) => {
63
- return media . attributes [ 'delivery' ] == 'streaming' ;
64
- } ) ;
65
- if ( streamingMedias . length ) {
66
- checkMedias = streamingMedias ;
67
- }
68
- const sortedMedias = checkMedias . sort ( ( a , b ) => {
69
- const aHeight = parseInt ( a . attributes [ 'height' ] , 10 ) || 0 ;
70
- const bHeight = parseInt ( b . attributes [ 'height' ] , 10 ) || 0 ;
71
- return bHeight - aHeight ;
72
- } ) ;
73
- for ( const media of sortedMedias ) {
74
- const adUrl = TXml . getTextContents ( media ) ;
75
- if ( ! adUrl ) {
76
- continue ;
77
- }
78
- interstitials . push ( {
79
- id : null ,
80
- startTime : startTime ,
81
- endTime : null ,
82
- uri : adUrl ,
83
- mimeType : media . attributes [ 'type' ] || null ,
84
- isSkippable : skipOffset != null ,
85
- skipOffset,
86
- skipFor : null ,
87
- canJump : false ,
88
- resumeOffset : 0 ,
89
- playoutLimit : null ,
90
- once : true ,
91
- pre : currentTime == null ,
92
- post : currentTime == Infinity ,
93
- timelineRange : false ,
94
- loop : false ,
95
- overlay : null ,
96
- } ) ;
97
- break ;
98
- }
99
52
}
100
53
}
101
54
return interstitials ;
102
55
}
103
56
57
+ /**
58
+ * @param {!Array.<shaka.extern.AdInterstitial> } interstitials
59
+ * @param {?number } currentTime
60
+ * @param {!shaka.extern.xml.Node } linear
61
+ * @private
62
+ */
63
+ static processLinearAd_ ( interstitials , currentTime , linear ) {
64
+ const TXml = shaka . util . TXml ;
65
+ let startTime = 0 ;
66
+ if ( currentTime != null ) {
67
+ startTime = currentTime ;
68
+ }
69
+ let skipOffset = null ;
70
+ if ( linear . attributes [ 'skipoffset' ] ) {
71
+ skipOffset = shaka . util . TextParser . parseTime (
72
+ linear . attributes [ 'skipoffset' ] ) ;
73
+ if ( isNaN ( skipOffset ) ) {
74
+ skipOffset = null ;
75
+ }
76
+ }
77
+ const mediaFiles = TXml . findChild ( linear , 'MediaFiles' ) ;
78
+ if ( ! mediaFiles ) {
79
+ return ;
80
+ }
81
+ const medias = TXml . findChildren ( mediaFiles , 'MediaFile' ) ;
82
+ let checkMedias = medias ;
83
+ const streamingMedias = medias . filter ( ( media ) => {
84
+ return media . attributes [ 'delivery' ] == 'streaming' ;
85
+ } ) ;
86
+ if ( streamingMedias . length ) {
87
+ checkMedias = streamingMedias ;
88
+ }
89
+ const sortedMedias = checkMedias . sort ( ( a , b ) => {
90
+ const aHeight = parseInt ( a . attributes [ 'height' ] , 10 ) || 0 ;
91
+ const bHeight = parseInt ( b . attributes [ 'height' ] , 10 ) || 0 ;
92
+ return bHeight - aHeight ;
93
+ } ) ;
94
+ for ( const media of sortedMedias ) {
95
+ if ( media . attributes [ 'apiFramework' ] ) {
96
+ continue ;
97
+ }
98
+ const adUrl = TXml . getContents ( media ) ;
99
+ if ( ! adUrl ) {
100
+ continue ;
101
+ }
102
+ interstitials . push ( {
103
+ id : null ,
104
+ startTime : startTime ,
105
+ endTime : null ,
106
+ uri : adUrl ,
107
+ mimeType : media . attributes [ 'type' ] || null ,
108
+ isSkippable : skipOffset != null ,
109
+ skipOffset,
110
+ skipFor : null ,
111
+ canJump : false ,
112
+ resumeOffset : 0 ,
113
+ playoutLimit : null ,
114
+ once : true ,
115
+ pre : currentTime == null ,
116
+ post : currentTime == Infinity ,
117
+ timelineRange : false ,
118
+ loop : false ,
119
+ overlay : null ,
120
+ } ) ;
121
+ break ;
122
+ }
123
+ }
124
+
125
+ /**
126
+ * @param {!Array.<shaka.extern.AdInterstitial> } interstitials
127
+ * @param {?number } currentTime
128
+ * @param {!shaka.extern.xml.Node } nonLinear
129
+ * @private
130
+ */
131
+ static processNonLinearAd_ ( interstitials , currentTime , nonLinear ) {
132
+ const TXml = shaka . util . TXml ;
133
+ const staticResource = TXml . findChild ( nonLinear , 'StaticResource' ) ;
134
+ if ( ! staticResource ) {
135
+ return ;
136
+ }
137
+ const adUrl = TXml . getContents ( staticResource ) ;
138
+ if ( ! adUrl ) {
139
+ return ;
140
+ }
141
+ const width = TXml . parseAttr ( nonLinear , 'width' , TXml . parseInt ) ;
142
+ const height = TXml . parseAttr ( nonLinear , 'height' , TXml . parseInt ) ;
143
+ if ( ! width || ! height ) {
144
+ return ;
145
+ }
146
+ let playoutLimit = null ;
147
+ const minSuggestedDuration =
148
+ nonLinear . attributes [ 'minSuggestedDuration' ] ;
149
+ if ( minSuggestedDuration ) {
150
+ playoutLimit = shaka . util . TextParser . parseTime ( minSuggestedDuration ) ;
151
+ }
152
+ let startTime = 0 ;
153
+ if ( currentTime != null ) {
154
+ startTime = currentTime ;
155
+ }
156
+ interstitials . push ( {
157
+ id : null ,
158
+ startTime : startTime ,
159
+ endTime : null ,
160
+ uri : adUrl ,
161
+ mimeType : staticResource . attributes [ 'creativeType' ] || null ,
162
+ isSkippable : false ,
163
+ skipOffset : null ,
164
+ skipFor : null ,
165
+ canJump : false ,
166
+ resumeOffset : 0 ,
167
+ playoutLimit,
168
+ once : true ,
169
+ pre : currentTime == null ,
170
+ post : currentTime == Infinity ,
171
+ timelineRange : false ,
172
+ loop : false ,
173
+ overlay : {
174
+ viewport : {
175
+ x : 0 ,
176
+ y : 0 ,
177
+ } ,
178
+ topLeft : {
179
+ x : 0 ,
180
+ y : 0 ,
181
+ } ,
182
+ size : {
183
+ x : width ,
184
+ y : height ,
185
+ } ,
186
+ } ,
187
+ } ) ;
188
+ }
189
+
104
190
/**
105
191
* @param {!shaka.extern.xml.Node } vmap
106
192
* @return {!Array.<{time: ?number, uri: string}> }
0 commit comments