shaka-player 4.4.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release-please.yaml +21 -13
- package/.github/workflows/report-incremental-coverage.yaml +2 -2
- package/.github/workflows/shaka-bot-commands/command-help.sh +27 -0
- package/.github/workflows/shaka-bot-commands/command-test.sh +56 -0
- package/.github/workflows/shaka-bot-commands/lib.sh +83 -0
- package/.github/workflows/shaka-bot-commands/main.sh +51 -0
- package/.github/workflows/talk-to-shaka-bot.yaml +29 -0
- package/.github/workflows/update-issues.yaml +2 -1
- package/.github/workflows/validate-pr-title.yaml +3 -11
- package/CHANGELOG.md +13 -0
- package/dist/deps.js +1 -1
- package/dist/locales.js +32 -32
- package/dist/shaka-player.compiled.d.ts +297 -297
- package/dist/shaka-player.compiled.debug.d.ts +297 -297
- package/dist/shaka-player.compiled.debug.externs.js +1 -1
- package/dist/shaka-player.compiled.debug.js +221 -222
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +1 -1
- package/dist/shaka-player.compiled.js +947 -946
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +341 -341
- package/dist/shaka-player.ui.debug.d.ts +341 -341
- package/dist/shaka-player.ui.debug.externs.js +1 -1
- package/dist/shaka-player.ui.debug.js +282 -283
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +1 -1
- package/dist/shaka-player.ui.js +566 -564
- package/dist/shaka-player.ui.map +3 -3
- package/externs/shaka/namespace.js +2 -2
- package/externs/shaka/transmuxer.js +2 -1
- package/lib/hls/hls_parser.js +1 -0
- package/lib/media/media_source_engine.js +22 -2
- package/lib/mss/mss_parser.js +1 -0
- package/lib/player.js +1 -1
- package/lib/text/simple_text_displayer.js +0 -1
- package/lib/transmuxer/aac_transmuxer.js +1 -1
- package/lib/transmuxer/ac3_transmuxer.js +1 -0
- package/lib/transmuxer/ec3_transmuxer.js +1 -0
- package/lib/transmuxer/mp3_transmuxer.js +1 -0
- package/lib/transmuxer/ts_transmuxer.js +54 -71
- package/lib/util/mp4_generator.js +27 -20
- package/lib/util/ts_parser.js +73 -110
- package/package.json +1 -1
- package/test/hls/hls_parser_unit.js +12 -13
- package/test/media/media_source_engine_integration.js +2 -2
- package/test/mss/mss_player_integration.js +1 -1
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @externs
|
|
9
|
-
* @suppress {duplicate} To prevent compiler errors with the
|
|
10
|
-
* being declared both here and by goog.provide in the library.
|
|
9
|
+
* @suppress {constantProperty, duplicate} To prevent compiler errors with the
|
|
10
|
+
* namespace being declared both here and by goog.provide in the library.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/** @namespace */
|
|
@@ -46,9 +46,10 @@ shaka.extern.Transmuxer = class {
|
|
|
46
46
|
* @param {?shaka.media.SegmentReference} reference The segment reference, or
|
|
47
47
|
* null for init segments
|
|
48
48
|
* @param {number} duration
|
|
49
|
+
* @param {string} contentType
|
|
49
50
|
* @return {!Promise.<!Uint8Array>}
|
|
50
51
|
*/
|
|
51
|
-
transmux(data, stream, reference, duration) {}
|
|
52
|
+
transmux(data, stream, reference, duration, contentType) {}
|
|
52
53
|
};
|
|
53
54
|
|
|
54
55
|
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -1466,6 +1466,7 @@ shaka.hls.HlsParser = class {
|
|
|
1466
1466
|
// and no video codec, so it should be audio.
|
|
1467
1467
|
type = ContentType.AUDIO;
|
|
1468
1468
|
shaka.log.debug('Guessing audio-only.');
|
|
1469
|
+
ignoreStream = res.audio.length > 0;
|
|
1469
1470
|
} else if (!streamInfos.length && audioCodecs && videoCodecs) {
|
|
1470
1471
|
// There are both audio and video codecs, so assume multiplexed content.
|
|
1471
1472
|
// Note that the default used when CODECS is missing assumes multiple
|
|
@@ -821,7 +821,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
821
821
|
|
|
822
822
|
if (this.transmuxers_[contentType]) {
|
|
823
823
|
data = await this.transmuxers_[contentType].transmux(
|
|
824
|
-
data, stream, reference, this.mediaSource_.duration);
|
|
824
|
+
data, stream, reference, this.mediaSource_.duration, contentType);
|
|
825
825
|
}
|
|
826
826
|
|
|
827
827
|
data = this.workAroundBrokenPlatforms_(
|
|
@@ -1562,16 +1562,34 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1562
1562
|
* @private
|
|
1563
1563
|
*/
|
|
1564
1564
|
async reset_(streamsByType) {
|
|
1565
|
+
const Functional = shaka.util.Functional;
|
|
1565
1566
|
this.reloadingMediaSource_ = true;
|
|
1566
1567
|
const currentTime = this.video_.currentTime;
|
|
1567
1568
|
try {
|
|
1568
1569
|
this.eventManager_.removeAll();
|
|
1569
|
-
this.sourceBuffers_ = {};
|
|
1570
1570
|
|
|
1571
1571
|
const cleanup = [];
|
|
1572
1572
|
for (const contentType in this.transmuxers_) {
|
|
1573
1573
|
cleanup.push(this.transmuxers_[contentType].destroy());
|
|
1574
1574
|
}
|
|
1575
|
+
for (const contentType in this.queues_) {
|
|
1576
|
+
// Make a local copy of the queue and the first item.
|
|
1577
|
+
const q = this.queues_[contentType];
|
|
1578
|
+
const inProgress = q[0];
|
|
1579
|
+
|
|
1580
|
+
// Drop everything else out of the original queue.
|
|
1581
|
+
this.queues_[contentType] = q.slice(0, 1);
|
|
1582
|
+
|
|
1583
|
+
// We will wait for this item to complete/fail.
|
|
1584
|
+
if (inProgress) {
|
|
1585
|
+
cleanup.push(inProgress.p.catch(Functional.noop));
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
// The rest will be rejected silently if possible.
|
|
1589
|
+
for (const item of q.slice(1)) {
|
|
1590
|
+
item.p.reject(shaka.util.Destroyer.destroyedError());
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1575
1593
|
for (const contentType in this.sourceBuffers_) {
|
|
1576
1594
|
const sourceBuffer = this.sourceBuffers_[contentType];
|
|
1577
1595
|
try {
|
|
@@ -1580,6 +1598,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1580
1598
|
}
|
|
1581
1599
|
await Promise.all(cleanup);
|
|
1582
1600
|
this.transmuxers_ = {};
|
|
1601
|
+
this.queues_ = {};
|
|
1602
|
+
this.sourceBuffers_ = {};
|
|
1583
1603
|
|
|
1584
1604
|
const previousDuration = this.mediaSource_.duration;
|
|
1585
1605
|
this.mediaSourceOpen_ = new shaka.util.PublicPromise();
|
package/lib/mss/mss_parser.js
CHANGED
package/lib/player.js
CHANGED
|
@@ -7224,7 +7224,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7224
7224
|
* @define {string} A version number taken from git at compile time.
|
|
7225
7225
|
* @export
|
|
7226
7226
|
*/
|
|
7227
|
-
shaka.Player.version = 'v4.4.
|
|
7227
|
+
shaka.Player.version = 'v4.4.1-uncompiled';
|
|
7228
7228
|
|
|
7229
7229
|
// Initialize the deprecation system using the version string we just set
|
|
7230
7230
|
// on the player.
|
|
@@ -145,7 +145,6 @@ shaka.transmuxer.AacTransmuxer = class {
|
|
|
145
145
|
}
|
|
146
146
|
stream.audioSamplingRate = info.sampleRate;
|
|
147
147
|
stream.channelsCount = info.channelCount;
|
|
148
|
-
stream.codecs = info.codec;
|
|
149
148
|
|
|
150
149
|
/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
|
|
151
150
|
const samples = [];
|
|
@@ -189,6 +188,7 @@ shaka.transmuxer.AacTransmuxer = class {
|
|
|
189
188
|
const streamInfo = {
|
|
190
189
|
id: stream.id,
|
|
191
190
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
191
|
+
codecs: info.codec,
|
|
192
192
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
193
193
|
timescale: sampleRate,
|
|
194
194
|
duration: duration,
|
|
@@ -177,6 +177,7 @@ shaka.transmuxer.Ac3Transmuxer = class {
|
|
|
177
177
|
const streamInfo = {
|
|
178
178
|
id: stream.id,
|
|
179
179
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
180
|
+
codecs: 'ac-3',
|
|
180
181
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
181
182
|
timescale: sampleRate,
|
|
182
183
|
duration: duration,
|
|
@@ -177,6 +177,7 @@ shaka.transmuxer.Ec3Transmuxer = class {
|
|
|
177
177
|
const streamInfo = {
|
|
178
178
|
id: stream.id,
|
|
179
179
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
180
|
+
codecs: 'ec-3',
|
|
180
181
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
181
182
|
timescale: sampleRate,
|
|
182
183
|
duration: duration,
|
|
@@ -169,6 +169,7 @@ shaka.transmuxer.Mp3Transmuxer = class {
|
|
|
169
169
|
const streamInfo = {
|
|
170
170
|
id: stream.id,
|
|
171
171
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
172
|
+
codecs: 'mp3',
|
|
172
173
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
173
174
|
timescale: sampleRate,
|
|
174
175
|
duration: duration,
|
|
@@ -159,7 +159,8 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
159
159
|
* @override
|
|
160
160
|
* @export
|
|
161
161
|
*/
|
|
162
|
-
transmux(data, stream, reference, duration) {
|
|
162
|
+
transmux(data, stream, reference, duration, contentType) {
|
|
163
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
163
164
|
if (!this.tsParser_) {
|
|
164
165
|
this.tsParser_ = new shaka.util.TsParser();
|
|
165
166
|
} else {
|
|
@@ -184,42 +185,46 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
184
185
|
const codecs = tsParser.getCodecs();
|
|
185
186
|
try {
|
|
186
187
|
let streamInfo = null;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
streamInfo
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
case 'aac':
|
|
200
|
-
streamInfo =
|
|
201
|
-
this.getAacStreamInfo_(
|
|
202
|
-
tsParser, timestamp, stream, duration, isMuxed);
|
|
203
|
-
break;
|
|
204
|
-
case 'ac3':
|
|
205
|
-
streamInfo =
|
|
206
|
-
this.getAc3StreamInfo_(
|
|
207
|
-
tsParser, timestamp, stream, duration, isMuxed);
|
|
208
|
-
break;
|
|
209
|
-
case 'ec3':
|
|
210
|
-
streamInfo =
|
|
211
|
-
this.getEc3StreamInfo_(
|
|
212
|
-
tsParser, timestamp, stream, duration, isMuxed);
|
|
213
|
-
break;
|
|
214
|
-
case 'mp3':
|
|
215
|
-
streamInfo =
|
|
216
|
-
this.getMp3StreamInfo_(
|
|
217
|
-
tsParser, timestamp, stream, duration, isMuxed);
|
|
218
|
-
break;
|
|
188
|
+
if (contentType == ContentType.VIDEO) {
|
|
189
|
+
switch (codecs.video) {
|
|
190
|
+
case 'avc':
|
|
191
|
+
streamInfo =
|
|
192
|
+
this.getAvcStreamInfo_(
|
|
193
|
+
tsParser, timestamp, stream, duration);
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
if (streamInfo) {
|
|
197
|
+
streamInfos.push(streamInfo);
|
|
198
|
+
streamInfo = null;
|
|
199
|
+
}
|
|
219
200
|
}
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
201
|
+
if (contentType == ContentType.AUDIO) {
|
|
202
|
+
switch (codecs.audio) {
|
|
203
|
+
case 'aac':
|
|
204
|
+
streamInfo =
|
|
205
|
+
this.getAacStreamInfo_(
|
|
206
|
+
tsParser, timestamp, stream, duration);
|
|
207
|
+
break;
|
|
208
|
+
case 'ac3':
|
|
209
|
+
streamInfo =
|
|
210
|
+
this.getAc3StreamInfo_(
|
|
211
|
+
tsParser, timestamp, stream, duration);
|
|
212
|
+
break;
|
|
213
|
+
case 'ec3':
|
|
214
|
+
streamInfo =
|
|
215
|
+
this.getEc3StreamInfo_(
|
|
216
|
+
tsParser, timestamp, stream, duration);
|
|
217
|
+
break;
|
|
218
|
+
case 'mp3':
|
|
219
|
+
streamInfo =
|
|
220
|
+
this.getMp3StreamInfo_(
|
|
221
|
+
tsParser, timestamp, stream, duration);
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
if (streamInfo) {
|
|
225
|
+
streamInfos.push(streamInfo);
|
|
226
|
+
streamInfo = null;
|
|
227
|
+
}
|
|
223
228
|
}
|
|
224
229
|
} catch (e) {
|
|
225
230
|
return Promise.reject(e);
|
|
@@ -253,11 +258,10 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
253
258
|
* @param {number} timestamp
|
|
254
259
|
* @param {shaka.extern.Stream} stream
|
|
255
260
|
* @param {number} duration
|
|
256
|
-
* @param {boolean} isMuxed
|
|
257
261
|
* @return {shaka.util.Mp4Generator.StreamInfo}
|
|
258
262
|
* @private
|
|
259
263
|
*/
|
|
260
|
-
getAacStreamInfo_(tsParser, timestamp, stream, duration
|
|
264
|
+
getAacStreamInfo_(tsParser, timestamp, stream, duration) {
|
|
261
265
|
const ADTS = shaka.transmuxer.ADTS;
|
|
262
266
|
|
|
263
267
|
/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
|
|
@@ -280,7 +284,6 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
280
284
|
}
|
|
281
285
|
stream.audioSamplingRate = info.sampleRate;
|
|
282
286
|
stream.channelsCount = info.channelCount;
|
|
283
|
-
stream.codecs = info.codec;
|
|
284
287
|
|
|
285
288
|
while (offset < data.length) {
|
|
286
289
|
const header = ADTS.parseHeader(data, offset);
|
|
@@ -325,13 +328,10 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
325
328
|
/** @type {number} */
|
|
326
329
|
const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);
|
|
327
330
|
|
|
328
|
-
let id = stream.id;
|
|
329
|
-
if (isMuxed) {
|
|
330
|
-
id += shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_;
|
|
331
|
-
}
|
|
332
331
|
return {
|
|
333
|
-
id: id,
|
|
332
|
+
id: stream.id,
|
|
334
333
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
334
|
+
codecs: info.codec,
|
|
335
335
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
336
336
|
timescale: sampleRate,
|
|
337
337
|
duration: duration,
|
|
@@ -353,11 +353,10 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
353
353
|
* @param {number} timestamp
|
|
354
354
|
* @param {shaka.extern.Stream} stream
|
|
355
355
|
* @param {number} duration
|
|
356
|
-
* @param {boolean} isMuxed
|
|
357
356
|
* @return {shaka.util.Mp4Generator.StreamInfo}
|
|
358
357
|
* @private
|
|
359
358
|
*/
|
|
360
|
-
getAc3StreamInfo_(tsParser, timestamp, stream, duration
|
|
359
|
+
getAc3StreamInfo_(tsParser, timestamp, stream, duration) {
|
|
361
360
|
const Ac3 = shaka.transmuxer.Ac3;
|
|
362
361
|
|
|
363
362
|
/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
|
|
@@ -415,13 +414,10 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
415
414
|
/** @type {number} */
|
|
416
415
|
const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);
|
|
417
416
|
|
|
418
|
-
let id = stream.id;
|
|
419
|
-
if (isMuxed) {
|
|
420
|
-
id += shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_;
|
|
421
|
-
}
|
|
422
417
|
return {
|
|
423
|
-
id: id,
|
|
418
|
+
id: stream.id,
|
|
424
419
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
420
|
+
codecs: 'ac-3',
|
|
425
421
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
426
422
|
timescale: sampleRate,
|
|
427
423
|
duration: duration,
|
|
@@ -443,11 +439,10 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
443
439
|
* @param {number} timestamp
|
|
444
440
|
* @param {shaka.extern.Stream} stream
|
|
445
441
|
* @param {number} duration
|
|
446
|
-
* @param {boolean} isMuxed
|
|
447
442
|
* @return {shaka.util.Mp4Generator.StreamInfo}
|
|
448
443
|
* @private
|
|
449
444
|
*/
|
|
450
|
-
getEc3StreamInfo_(tsParser, timestamp, stream, duration
|
|
445
|
+
getEc3StreamInfo_(tsParser, timestamp, stream, duration) {
|
|
451
446
|
const Ec3 = shaka.transmuxer.Ec3;
|
|
452
447
|
|
|
453
448
|
/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
|
|
@@ -505,13 +500,10 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
505
500
|
/** @type {number} */
|
|
506
501
|
const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);
|
|
507
502
|
|
|
508
|
-
let id = stream.id;
|
|
509
|
-
if (isMuxed) {
|
|
510
|
-
id += shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_;
|
|
511
|
-
}
|
|
512
503
|
return {
|
|
513
|
-
id: id,
|
|
504
|
+
id: stream.id,
|
|
514
505
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
506
|
+
codecs: 'ec-3',
|
|
515
507
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
516
508
|
timescale: sampleRate,
|
|
517
509
|
duration: duration,
|
|
@@ -533,11 +525,10 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
533
525
|
* @param {number} timestamp
|
|
534
526
|
* @param {shaka.extern.Stream} stream
|
|
535
527
|
* @param {number} duration
|
|
536
|
-
* @param {boolean} isMuxed
|
|
537
528
|
* @return {shaka.util.Mp4Generator.StreamInfo}
|
|
538
529
|
* @private
|
|
539
530
|
*/
|
|
540
|
-
getMp3StreamInfo_(tsParser, timestamp, stream, duration
|
|
531
|
+
getMp3StreamInfo_(tsParser, timestamp, stream, duration) {
|
|
541
532
|
const MpegAudio = shaka.transmuxer.MpegAudio;
|
|
542
533
|
|
|
543
534
|
/** @type {!Array.<shaka.util.Mp4Generator.Mp4Sample>} */
|
|
@@ -590,13 +581,10 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
590
581
|
/** @type {number} */
|
|
591
582
|
const baseMediaDecodeTime = Math.floor(timestamp * sampleRate / 1000);
|
|
592
583
|
|
|
593
|
-
let id = stream.id;
|
|
594
|
-
if (isMuxed) {
|
|
595
|
-
id += shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_;
|
|
596
|
-
}
|
|
597
584
|
return {
|
|
598
|
-
id: id,
|
|
585
|
+
id: stream.id,
|
|
599
586
|
type: shaka.util.ManifestParserUtils.ContentType.AUDIO,
|
|
587
|
+
codecs: 'mp3',
|
|
600
588
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
601
589
|
timescale: sampleRate,
|
|
602
590
|
duration: duration,
|
|
@@ -686,6 +674,7 @@ shaka.transmuxer.TsTransmuxer = class {
|
|
|
686
674
|
return {
|
|
687
675
|
id: stream.id,
|
|
688
676
|
type: shaka.util.ManifestParserUtils.ContentType.VIDEO,
|
|
677
|
+
codecs: 'avc1',
|
|
689
678
|
encrypted: stream.encrypted && stream.drmInfos.length > 0,
|
|
690
679
|
timescale: timescale,
|
|
691
680
|
duration: duration,
|
|
@@ -725,12 +714,6 @@ shaka.transmuxer.TsTransmuxer.SUPPORTED_VIDEO_CODECS_ = [
|
|
|
725
714
|
'avc',
|
|
726
715
|
];
|
|
727
716
|
|
|
728
|
-
/**
|
|
729
|
-
* @private
|
|
730
|
-
* @const {number}
|
|
731
|
-
*/
|
|
732
|
-
shaka.transmuxer.TsTransmuxer.START_ID_FOR_MUXED_CONTENT_ = 128;
|
|
733
|
-
|
|
734
717
|
|
|
735
718
|
shaka.transmuxer.TransmuxerEngine.registerTransmuxer(
|
|
736
719
|
'video/mp2t',
|
|
@@ -55,7 +55,7 @@ shaka.util.Mp4Generator = class {
|
|
|
55
55
|
return Mp4Generator.box('moov',
|
|
56
56
|
this.mvhd_(firstStreamInfo),
|
|
57
57
|
traks,
|
|
58
|
-
this.mvex_(
|
|
58
|
+
this.mvex_(),
|
|
59
59
|
this.pssh_(firstStreamInfo));
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -130,9 +130,14 @@ shaka.util.Mp4Generator = class {
|
|
|
130
130
|
*/
|
|
131
131
|
tkhd_(streamInfo) {
|
|
132
132
|
const Mp4Generator = shaka.util.Mp4Generator;
|
|
133
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
133
134
|
const id = streamInfo.id + 1;
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
let width = streamInfo.stream.width || 0;
|
|
136
|
+
let height = streamInfo.stream.height || 0;
|
|
137
|
+
if (streamInfo.type == ContentType.AUDIO) {
|
|
138
|
+
width = 0;
|
|
139
|
+
height = 0;
|
|
140
|
+
}
|
|
136
141
|
const duration = streamInfo.duration * streamInfo.timescale;
|
|
137
142
|
const upperWordDuration =
|
|
138
143
|
Math.floor(duration / (Mp4Generator.UINT32_MAX_ + 1));
|
|
@@ -295,24 +300,18 @@ shaka.util.Mp4Generator = class {
|
|
|
295
300
|
let bytes = new Uint8Array([]);
|
|
296
301
|
switch (streamInfo.type) {
|
|
297
302
|
case ContentType.VIDEO:
|
|
298
|
-
if (streamInfo.
|
|
299
|
-
streamInfo.stream.codecs.includes('avc3.')) {
|
|
303
|
+
if (streamInfo.codecs.includes('avc1')) {
|
|
300
304
|
bytes = this.avc1_(streamInfo);
|
|
301
|
-
} else if (streamInfo.
|
|
302
|
-
streamInfo.stream.codecs.includes('hvc1.')) {
|
|
305
|
+
} else if (streamInfo.codecs.includes('hvc1')) {
|
|
303
306
|
bytes = this.hvc1_(streamInfo);
|
|
304
307
|
}
|
|
305
308
|
break;
|
|
306
309
|
case ContentType.AUDIO:
|
|
307
|
-
if (streamInfo.
|
|
308
|
-
streamInfo.stream.codecs.includes('mp3') ||
|
|
309
|
-
streamInfo.stream.codecs.includes('mp4a.40.34')) {
|
|
310
|
+
if (streamInfo.codecs.includes('mp3')) {
|
|
310
311
|
bytes = this.mp3_(streamInfo);
|
|
311
|
-
} else if (streamInfo.
|
|
312
|
-
streamInfo.stream.codecs.includes('ac-3')) {
|
|
312
|
+
} else if (streamInfo.codecs.includes('ac-3')) {
|
|
313
313
|
bytes = this.ac3_(streamInfo);
|
|
314
|
-
} else if (streamInfo.
|
|
315
|
-
streamInfo.stream.codecs.includes('ec-3')) {
|
|
314
|
+
} else if (streamInfo.codecs.includes('ec-3')) {
|
|
316
315
|
bytes = this.ec3_(streamInfo);
|
|
317
316
|
} else {
|
|
318
317
|
bytes = this.mp4a_(streamInfo);
|
|
@@ -630,7 +629,7 @@ shaka.util.Mp4Generator = class {
|
|
|
630
629
|
const audioSamplingRate = streamInfo.stream.audioSamplingRate || 44100;
|
|
631
630
|
|
|
632
631
|
const audioCodec = shaka.util.ManifestParserUtils.guessCodecs(
|
|
633
|
-
ContentType.AUDIO, streamInfo.
|
|
632
|
+
ContentType.AUDIO, streamInfo.codecs.split(','));
|
|
634
633
|
|
|
635
634
|
const samplingFrequencyIndex = {
|
|
636
635
|
96000: 0x0,
|
|
@@ -689,13 +688,16 @@ shaka.util.Mp4Generator = class {
|
|
|
689
688
|
/**
|
|
690
689
|
* Generate a MVEX box
|
|
691
690
|
*
|
|
692
|
-
* @param {shaka.util.Mp4Generator.StreamInfo} streamInfo
|
|
693
691
|
* @return {!Uint8Array}
|
|
694
692
|
* @private
|
|
695
693
|
*/
|
|
696
|
-
mvex_(
|
|
694
|
+
mvex_() {
|
|
697
695
|
const Mp4Generator = shaka.util.Mp4Generator;
|
|
698
|
-
|
|
696
|
+
let trexs = new Uint8Array([]);
|
|
697
|
+
for (const streamInfo of this.streamInfos_) {
|
|
698
|
+
trexs = shaka.util.Uint8ArrayUtils.concat(trexs, this.trex_(streamInfo));
|
|
699
|
+
}
|
|
700
|
+
return Mp4Generator.box('mvex', trexs);
|
|
699
701
|
}
|
|
700
702
|
|
|
701
703
|
/**
|
|
@@ -765,8 +767,8 @@ shaka.util.Mp4Generator = class {
|
|
|
765
767
|
* @private
|
|
766
768
|
*/
|
|
767
769
|
frma_(streamInfo) {
|
|
768
|
-
const codec = streamInfo.
|
|
769
|
-
0, streamInfo.
|
|
770
|
+
const codec = streamInfo.codecs.substring(
|
|
771
|
+
0, streamInfo.codecs.indexOf('.'));
|
|
770
772
|
const Mp4Generator = shaka.util.Mp4Generator;
|
|
771
773
|
const codecNumber = this.stringToCharCode_(codec);
|
|
772
774
|
const bytes = new Uint8Array([
|
|
@@ -1290,6 +1292,7 @@ shaka.util.Mp4Generator.DINF_ = new Uint8Array([]);
|
|
|
1290
1292
|
* @typedef {{
|
|
1291
1293
|
* id: number,
|
|
1292
1294
|
* type: string,
|
|
1295
|
+
* codecs: string,
|
|
1293
1296
|
* encrypted: boolean,
|
|
1294
1297
|
* timescale: number,
|
|
1295
1298
|
* duration: number,
|
|
@@ -1304,6 +1307,10 @@ shaka.util.Mp4Generator.DINF_ = new Uint8Array([]);
|
|
|
1304
1307
|
* A unique ID
|
|
1305
1308
|
* @property {string} type
|
|
1306
1309
|
* Indicate the content type: 'video' or 'audio'.
|
|
1310
|
+
* @property {string} codecs
|
|
1311
|
+
* <i>Defaults to '' (i.e., unknown / not needed).</i> <br>
|
|
1312
|
+
* The Stream's codecs, e.g., 'avc1.4d4015' or 'vp9'<br>
|
|
1313
|
+
* See {@link https://tools.ietf.org/html/rfc6381}
|
|
1307
1314
|
* @property {boolean} encrypted
|
|
1308
1315
|
* Indicate if the stream is encrypted.
|
|
1309
1316
|
* @property {number} timescale
|