-
Notifications
You must be signed in to change notification settings - Fork 28
/
playback.js
378 lines (336 loc) · 8.89 KB
/
playback.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
import { extend } from '@/utils'
import UIObject from '@/base/ui_object'
import ErrorMixin from '@/base/error_mixin'
import $ from 'clappr-zepto'
/**
* An object representing a single audio track.
* @typedef {Object} AudioTrack
* @property {string} id - A unique identifier for the track. Used to identify it among the others.
* @property {string} language - The language of the track (e.g., 'en', 'pt-BR').
* @property {string} [label] - An optional label to be used in the UI to describe the track.
* @property {('main'|'description')} kind - The category the audio track belongs to.
* The kind 'description' is applied to audio tracks that narrate or describe the visual content.
*/
/**
* An abstraction to represent a generic playback, it's like an interface to be implemented by subclasses.
* @class Playback
* @constructor
* @extends UIObject
* @module base
*/
export default class Playback extends UIObject {
/**
* Determine if the playback does not contain video/has video but video should be ignored.
* @property isAudioOnly
* @type Boolean
*/
get isAudioOnly() {
return false
}
get isAdaptive() {
return false
}
/**
* Determine if the playback has ended.
* @property ended
* @type Boolean
*/
get ended() {
return false
}
/**
* The internationalization plugin.
* @property i18n
* @type {Strings}
*/
get i18n() {
return this._i18n
}
/**
* Determine if the playback is having to buffer in order for
* playback to be smooth.
* (i.e if a live stream is playing smoothly, this will be false)
* @property buffering
* @type Boolean
*/
get buffering() {
return false
}
/**
* The estimated time (in seconds) of a video's live edge plus time sync playlist advanced.
* (i.e if first playlist hasn't been loaded, will return 0)
* @property latency
* @type {Number}
*/
get latency() {
return null
}
/**
* The datetime value relative for a video's active level Program Date Time, if present.
* (i.e if first playlist hasn't been loaded, will return null)
* @property currentProgramDateTime
* @return {Date}
*/
get currentProgramDateTime() {
return null
}
/**
* checks if picture in picture mode is active.
* @property isPiPActive
* @type {Boolean} `true` if the current playback is in picture in picture mode, otherwise `false`
*/
get isPiPActive() {
return false
}
/**
* @method constructor
* @param {Object} options the options object
* @param {Strings} i18n the internationalization component
*/
constructor(options, i18n, playerError) {
super(options)
this.settings = {}
this._i18n = i18n
this.playerError = playerError
this._consented = false
}
/**
* Gives user consent to playback (mobile devices).
* @method consent
* @param {Function} callback function called when playback is consented
*/
consent(cb) { typeof cb === 'function' && cb() }
/**
* plays the playback.
* @method play
*/
play() {}
/**
* pauses the playback.
* @method pause
*/
pause() {}
/**
* stops the playback.
* @method stop
*/
stop() {}
/**
* enter in picture in picture mode
* @method enterPiP
*/
enterPiP() {}
/**
* exit from picture in picture mode
* @method exitPiP
*/
exitPiP() {}
/**
* seeks the playback to a given `time` in seconds
* @method seek
* @param {Number} time should be a number between 0 and the video duration
*/
seek(time) {} // eslint-disable-line no-unused-vars
/**
* seeks the playback to a given `percentage` in percentage
* @method seekPercentage
* @param {Number} time should be a number between 0 and 100
*/
seekPercentage(percentage) {} // eslint-disable-line no-unused-vars
/**
* The time that "0" now represents relative to when playback started.
* For a stream with a sliding window this will increase as content is
* removed from the beginning.
* @method getStartTimeOffset
* @return {Number} time (in seconds) that time "0" represents.
*/
getStartTimeOffset() { return 0 }
/**
* gets the duration in seconds
* @method getDuration
* @return {Number} duration (in seconds) of the current source
*/
getDuration() { return 0 }
/**
* checks if the playback is playing.
* @method isPlaying
* @return {Boolean} `true` if the current playback is playing, otherwise `false`
*/
isPlaying() {
return false
}
/**
* checks if the playback is ready.
* @property isReady
* @type {Boolean} `true` if the current playback is ready, otherwise `false`
*/
get isReady() {
return false
}
/**
* checks if the playback has closed caption tracks.
* @property hasClosedCaptionsTracks
* @type {Boolean}
*/
get hasClosedCaptionsTracks() {
return this.closedCaptionsTracks.length > 0
}
/**
* gets the playback available closed caption tracks.
* @property closedCaptionsTracks
* @type {Array} an array of objects with at least 'id' and 'name' properties
*/
get closedCaptionsTracks() {
return []
}
/**
* gets the selected closed caption track index. (-1 is disabled)
* @property closedCaptionsTrackId
* @type {Number}
*/
get closedCaptionsTrackId() {
return -1
}
/**
* sets the selected closed caption track index. (-1 is disabled)
* @property closedCaptionsTrackId
* @type {Number}
*/
set closedCaptionsTrackId(trackId) {} // eslint-disable-line no-unused-vars
/**
* returns a list of the available audio tracks for the playback.
* @type {AudioTrack[]} audio tracks
*/
get audioTracks() { return [] }
/**
* returns the audio track currently in use by the playback.
* @type {AudioTrack} audio track
*/
get currentAudioTrack() { return null }
/**
* switches the current audio track used by the playback.
* @param {string} id - id of the audio track to be set.
*/
switchAudioTrack(id) {} // eslint-disable-line no-unused-vars
/**
* gets the playback type (`'vod', 'live', 'aod'`)
* @method getPlaybackType
* @return {String} you should write the playback type otherwise it'll assume `'no_op'`
* @example
* ```javascript
* html5VideoPlayback.getPlaybackType() //vod
* html5AudioPlayback.getPlaybackType() //aod
* html5VideoPlayback.getPlaybackType() //live
* flashHlsPlayback.getPlaybackType() //live
* ```
*/
getPlaybackType() {
return Playback.NO_OP
}
/**
* checks if the playback is in HD.
* @method isHighDefinitionInUse
* @return {Boolean} `true` if the playback is playing in HD, otherwise `false`
*/
isHighDefinitionInUse() {
return false
}
/**
* mutes the playback
* @method mute
*/
mute() {}
/**
* restores the playback volume
* @method unmute
*/
unmute() {}
/**
* sets the volume for the playback
* @method volume
* @param {Number} value a number between 0 (`muted`) to 100 (`max`)
*/
volume(value) {} // eslint-disable-line no-unused-vars
/**
* enables to configure the playback after its creation
* @method configure
* @param {Object} options all the options to change in form of a javascript object
*/
configure(options) {
this._options = $.extend(true, this._options, options)
}
/**
* attempt to autoplays the playback.
* @method attemptAutoPlay
*/
attemptAutoPlay() {
this.canAutoPlay((result, error) => { // eslint-disable-line no-unused-vars
result && this.play()
})
}
/**
* checks if the playback can autoplay.
* @method canAutoPlay
* @param {Function} callback function where first param is Boolean and second param is playback Error or null
*/
canAutoPlay(cb) {
cb(true, null) // Assume playback can autoplay by default
}
}
Object.assign(Playback.prototype, ErrorMixin)
Playback.extend = function(properties) {
return extend(Playback, properties)
}
/**
* checks if the playback can play a given `source`
* If a mimeType is provided then this will be used instead of inferring the mimetype
* from the source extension.
* @method canPlay
* @static
* @param {String} source the given source ex: `http://example.com/play.mp4`
* @param {String} [mimeType] the given mime type, ex: `'application/vnd.apple.mpegurl'`
* @return {Boolean} `true` if the playback is playable, otherwise `false`
*/
Playback.canPlay = (source, mimeType) => { // eslint-disable-line no-unused-vars
return false
}
/**
* a playback type for video on demand
*
* @property VOD
* @static
* @type String
*/
Playback.VOD = 'vod'
/**
* a playback type for audio on demand
*
* @property AOD
* @static
* @type String
*/
Playback.AOD = 'aod'
/**
* a playback type for live video
*
* @property LIVE
* @static
* @type String
*/
Playback.LIVE = 'live'
/**
* a default playback type
*
* @property NO_OP
* @static
* @type String
*/
Playback.NO_OP = 'no_op'
/**
* the plugin type
*
* @property type
* @static
* @type String
*/
Playback.type = 'playback'