shaka-player 4.2.4 → 4.3.0
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/sync-labels.yaml +1 -1
- package/.github/workflows/update-issues.yaml +1 -1
- package/AUTHORS +4 -0
- package/CHANGELOG.md +85 -54
- package/CONTRIBUTORS +4 -0
- package/README.md +14 -0
- package/demo/common/assets.js +58 -0
- package/demo/common/message_ids.js +22 -1
- package/demo/config.js +89 -5
- package/demo/demo.less +7 -1
- package/demo/index.html +8 -1
- package/demo/locales/en.json +21 -1
- package/demo/locales/source.json +82 -2
- package/demo/main.js +57 -1
- package/demo/search.js +2 -0
- package/demo/visualizer.js +337 -0
- package/demo/visualizer_button.js +103 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +83 -58
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +83 -58
- package/dist/demo.compiled.map +4 -4
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +16 -9
- package/dist/locales.js +32 -32
- package/dist/receiver.compiled.debug.js +23 -19
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +23 -19
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +173 -26
- package/dist/shaka-player.compiled.debug.d.ts +173 -26
- package/dist/shaka-player.compiled.debug.externs.js +161 -31
- package/dist/shaka-player.compiled.debug.js +464 -401
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +161 -31
- package/dist/shaka-player.compiled.js +897 -862
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +173 -26
- package/dist/shaka-player.ui.debug.d.ts +173 -26
- package/dist/shaka-player.ui.debug.externs.js +161 -31
- package/dist/shaka-player.ui.debug.js +488 -422
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +161 -31
- package/dist/shaka-player.ui.js +1053 -1018
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/lcevc-architecture.png +0 -0
- package/docs/design/lcevc-demo.png +0 -0
- package/docs/design/lcevc-integration.md +72 -0
- package/docs/tutorials/fairplay.md +7 -0
- package/docs/tutorials/faq.md +1 -1
- package/docs/tutorials/ui.md +7 -7
- package/docs/tutorials/upgrade.md +6 -0
- package/externs/ima.js +13 -1
- package/externs/lcevc.js +81 -0
- package/externs/mux.js +1 -42
- package/externs/shaka/ads.js +11 -1
- package/externs/shaka/manifest_parser.js +5 -1
- package/externs/shaka/player.js +178 -15
- package/lib/abr/simple_abr_manager.js +7 -0
- package/lib/ads/ad_manager.js +0 -8
- package/lib/ads/client_side_ad.js +15 -0
- package/lib/ads/client_side_ad_manager.js +21 -8
- package/lib/ads/server_side_ad.js +15 -0
- package/lib/ads/server_side_ad_manager.js +3 -3
- package/lib/cast/cast_utils.js +2 -0
- package/lib/cea/dummy_cea_parser.js +28 -0
- package/lib/cea/i_cea_parser.js +14 -2
- package/lib/cea/mp4_cea_parser.js +87 -5
- package/lib/config/auto_show_text.js +33 -0
- package/lib/dash/dash_parser.js +1 -1
- package/lib/hls/hls_parser.js +790 -374
- package/lib/lcevc/lcevc_dil.js +152 -0
- package/lib/media/closed_caption_parser.js +9 -6
- package/lib/media/drm_engine.js +14 -6
- package/lib/media/media_source_engine.js +106 -26
- package/lib/media/presentation_timeline.js +26 -11
- package/lib/media/segment_reference.js +49 -1
- package/lib/media/streaming_engine.js +142 -12
- package/lib/media/transmuxer.js +73 -18
- package/lib/offline/storage.js +1 -0
- package/lib/player.js +454 -75
- package/lib/polyfill/patchedmediakeys_apple.js +55 -1
- package/lib/text/ui_text_displayer.js +5 -5
- package/lib/text/vtt_text_parser.js +35 -1
- package/lib/util/dom_utils.js +0 -1
- package/lib/util/error.js +17 -0
- package/lib/util/fake_event.js +2 -0
- package/lib/util/id3_utils.js +300 -0
- package/lib/util/mime_utils.js +3 -6
- package/lib/util/mp4_box_parsers.js +15 -5
- package/lib/util/platform.js +9 -1
- package/lib/util/player_configuration.js +23 -1
- package/lib/util/ts_parser.js +499 -0
- package/maintained-branches.md +2 -2
- package/package.json +4 -1
- package/roadmap.md +5 -3
- package/test/ads/ad_manager_unit.js +180 -29
- package/test/cast/cast_utils_unit.js +3 -1
- package/test/dash/dash_parser_content_protection_unit.js +1 -0
- package/test/dash/dash_parser_live_unit.js +1 -0
- package/test/dash/dash_parser_manifest_unit.js +93 -1
- package/test/dash/dash_parser_segment_base_unit.js +1 -0
- package/test/dash/dash_parser_segment_list_unit.js +1 -0
- package/test/dash/dash_parser_segment_template_unit.js +1 -0
- package/test/demo/demo_unit.js +2 -1
- package/test/hls/hls_live_unit.js +253 -19
- package/test/hls/hls_parser_unit.js +500 -12
- package/test/media/closed_caption_parser_unit.js +2 -1
- package/test/media/drm_engine_integration.js +3 -1
- package/test/media/media_source_engine_integration.js +71 -6
- package/test/media/media_source_engine_unit.js +10 -5
- package/test/media/streaming_engine_integration.js +4 -1
- package/test/media/streaming_engine_unit.js +144 -1
- package/test/media/transmuxer_integration.js +21 -10
- package/test/player_integration.js +224 -82
- package/test/player_unit.js +5 -2
- package/test/polyfill/patchedmediakeys_apple_unit.js +124 -0
- package/test/test/assets/id3-metadata.aac +0 -0
- package/test/test/assets/id3-metadata.ts +0 -0
- package/test/test/assets/thumbnails-sprites.vtt +10 -0
- package/test/test/assets/thumbnails.vtt +10 -0
- package/test/test/util/dash_parser_util.js +2 -0
- package/test/test/util/fake_ad.js +21 -0
- package/test/test/util/fake_media_source_engine.js +7 -0
- package/test/test/util/id3_generator.js +100 -0
- package/test/test/util/manifest_generator.js +3 -6
- package/test/test/util/simple_fakes.js +4 -0
- package/test/test/util/stream_generator.js +38 -0
- package/test/test/util/test_scheme.js +43 -14
- package/test/text/vtt_text_parser_unit.js +11 -0
- package/test/ui/text_displayer_layout_unit.js +14 -0
- package/test/util/id3_utils_unit.js +116 -0
- package/test/util/ts_parser_unit.js +77 -0
- package/ui/less/containers.less +7 -0
- package/ui/ui.js +43 -4
|
@@ -24,6 +24,7 @@ goog.require('shaka.util.Destroyer');
|
|
|
24
24
|
goog.require('shaka.util.Error');
|
|
25
25
|
goog.require('shaka.util.FakeEvent');
|
|
26
26
|
goog.require('shaka.util.IDestroyable');
|
|
27
|
+
goog.require('shaka.util.Id3Utils');
|
|
27
28
|
goog.require('shaka.util.ManifestParserUtils');
|
|
28
29
|
goog.require('shaka.util.MimeUtils');
|
|
29
30
|
goog.require('shaka.util.Mp4Parser');
|
|
@@ -77,6 +78,9 @@ shaka.media.StreamingEngine = class {
|
|
|
77
78
|
/** @private {?shaka.extern.Stream} */
|
|
78
79
|
this.currentTextStream_ = null;
|
|
79
80
|
|
|
81
|
+
/** @private {boolean} */
|
|
82
|
+
this.parsedPrftEventRaised_ = false;
|
|
83
|
+
|
|
80
84
|
/**
|
|
81
85
|
* Maps a content type, e.g., 'audio', 'video', or 'text', to a MediaState.
|
|
82
86
|
*
|
|
@@ -780,9 +784,9 @@ shaka.media.StreamingEngine = class {
|
|
|
780
784
|
|
|
781
785
|
// Init MediaSourceEngine.
|
|
782
786
|
const mediaSourceEngine = this.playerInterface_.mediaSourceEngine;
|
|
783
|
-
const
|
|
787
|
+
const forceTransmux = this.config_.forceTransmux;
|
|
784
788
|
|
|
785
|
-
await mediaSourceEngine.init(streamsByType,
|
|
789
|
+
await mediaSourceEngine.init(streamsByType, forceTransmux,
|
|
786
790
|
this.manifest_.sequenceMode);
|
|
787
791
|
this.destroyer_.ensureNotDestroyed();
|
|
788
792
|
|
|
@@ -1370,7 +1374,8 @@ shaka.media.StreamingEngine = class {
|
|
|
1370
1374
|
JSON.stringify(buffered));
|
|
1371
1375
|
|
|
1372
1376
|
if (!mediaState.waitingToClearBuffer) {
|
|
1373
|
-
this.playerInterface_.onSegmentAppended(
|
|
1377
|
+
this.playerInterface_.onSegmentAppended(
|
|
1378
|
+
reference.startTime, reference.endTime, mediaState.type);
|
|
1374
1379
|
}
|
|
1375
1380
|
|
|
1376
1381
|
// Update right away.
|
|
@@ -1626,6 +1631,17 @@ shaka.media.StreamingEngine = class {
|
|
|
1626
1631
|
try {
|
|
1627
1632
|
const initSegment = await fetchInit;
|
|
1628
1633
|
this.destroyer_.ensureNotDestroyed();
|
|
1634
|
+
|
|
1635
|
+
const parser = new shaka.util.Mp4Parser();
|
|
1636
|
+
const Mp4Parser = shaka.util.Mp4Parser;
|
|
1637
|
+
parser.box('moov', Mp4Parser.children)
|
|
1638
|
+
.box('trak', Mp4Parser.children)
|
|
1639
|
+
.box('mdia', Mp4Parser.children)
|
|
1640
|
+
.fullBox('mdhd', (box) => {
|
|
1641
|
+
this.parseMDHD_(reference, box);
|
|
1642
|
+
})
|
|
1643
|
+
.parse(initSegment);
|
|
1644
|
+
|
|
1629
1645
|
shaka.log.v1(logPrefix, 'appending init segment');
|
|
1630
1646
|
const hasClosedCaptions = mediaState.stream.closedCaptions &&
|
|
1631
1647
|
mediaState.stream.closedCaptions.size > 0;
|
|
@@ -1665,15 +1681,36 @@ shaka.media.StreamingEngine = class {
|
|
|
1665
1681
|
|
|
1666
1682
|
const hasClosedCaptions = stream.closedCaptions &&
|
|
1667
1683
|
stream.closedCaptions.size > 0;
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1684
|
+
|
|
1685
|
+
let parser;
|
|
1686
|
+
const hasEmsg = ((stream.emsgSchemeIdUris != null &&
|
|
1687
|
+
stream.emsgSchemeIdUris.length > 0) ||
|
|
1688
|
+
this.config_.dispatchAllEmsgBoxes);
|
|
1689
|
+
const shouldParsePrftBox =
|
|
1690
|
+
(this.config_.parsePrftBox && !this.parsedPrftEventRaised_);
|
|
1691
|
+
|
|
1692
|
+
if (hasEmsg || shouldParsePrftBox) {
|
|
1693
|
+
parser = new shaka.util.Mp4Parser();
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
if (hasEmsg) {
|
|
1697
|
+
parser
|
|
1672
1698
|
.fullBox(
|
|
1673
1699
|
'emsg',
|
|
1674
1700
|
(box) => this.parseEMSG_(
|
|
1675
|
-
reference, stream.emsgSchemeIdUris, box))
|
|
1676
|
-
|
|
1701
|
+
reference, stream.emsgSchemeIdUris, box));
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
if (shouldParsePrftBox) {
|
|
1705
|
+
parser
|
|
1706
|
+
.fullBox(
|
|
1707
|
+
'prft',
|
|
1708
|
+
(box) => this.parsePrft_(
|
|
1709
|
+
reference, box));
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
if (hasEmsg || shouldParsePrftBox) {
|
|
1713
|
+
parser.parse(segment);
|
|
1677
1714
|
}
|
|
1678
1715
|
|
|
1679
1716
|
await this.evict_(mediaState, presentationTime);
|
|
@@ -1769,6 +1806,21 @@ shaka.media.StreamingEngine = class {
|
|
|
1769
1806
|
// A special scheme in DASH used to signal manifest updates.
|
|
1770
1807
|
if (schemeId == 'urn:mpeg:dash:event:2012') {
|
|
1771
1808
|
this.playerInterface_.onManifestUpdate();
|
|
1809
|
+
} else if (schemeId == 'https://aomedia.org/emsg/ID3') {
|
|
1810
|
+
// See https://aomediacodec.github.io/id3-emsg/
|
|
1811
|
+
const frames = shaka.util.Id3Utils.getID3Frames(messageData);
|
|
1812
|
+
if (frames.length && reference) {
|
|
1813
|
+
/** @private {shaka.extern.ID3Metadata} */
|
|
1814
|
+
const metadata = {
|
|
1815
|
+
cueTime: reference.startTime,
|
|
1816
|
+
data: messageData,
|
|
1817
|
+
frames: frames,
|
|
1818
|
+
dts: reference.startTime,
|
|
1819
|
+
pts: reference.startTime,
|
|
1820
|
+
};
|
|
1821
|
+
this.playerInterface_.onMetadata(
|
|
1822
|
+
[metadata], /* offset= */ 0, reference.endTime);
|
|
1823
|
+
}
|
|
1772
1824
|
} else {
|
|
1773
1825
|
/** @type {shaka.extern.EmsgInfo} */
|
|
1774
1826
|
const emsg = {
|
|
@@ -1792,6 +1844,77 @@ shaka.media.StreamingEngine = class {
|
|
|
1792
1844
|
}
|
|
1793
1845
|
}
|
|
1794
1846
|
|
|
1847
|
+
/**
|
|
1848
|
+
* Parse MDHD box.
|
|
1849
|
+
* @param {!shaka.media.SegmentReference} reference
|
|
1850
|
+
* @param {!shaka.extern.ParsedBox} box
|
|
1851
|
+
* @private
|
|
1852
|
+
*/
|
|
1853
|
+
parseMDHD_(reference, box) {
|
|
1854
|
+
const parsedMDHDBox = shaka.util.Mp4BoxParsers.parseMDHD(
|
|
1855
|
+
box.reader || 0, box.version || 0);
|
|
1856
|
+
reference.initSegmentReference.timescale = parsedMDHDBox.timescale;
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
/**
|
|
1860
|
+
* Parse PRFT box.
|
|
1861
|
+
* @param {!shaka.media.SegmentReference} reference
|
|
1862
|
+
* @param {!shaka.extern.ParsedBox} box
|
|
1863
|
+
* @private
|
|
1864
|
+
*/
|
|
1865
|
+
parsePrft_(reference, box) {
|
|
1866
|
+
if (this.parsedPrftEventRaised_ ||
|
|
1867
|
+
!reference.initSegmentReference.timescale) {
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
box.reader.readUint32(); // Ignore referenceTrackId
|
|
1871
|
+
const ntpTimestampSec = box.reader.readUint32();
|
|
1872
|
+
const ntpTimestampFrac = box.reader.readUint32();
|
|
1873
|
+
const ntpTimestamp = ntpTimestampSec * 1000 +
|
|
1874
|
+
ntpTimestampFrac / 2**32 * 1000;
|
|
1875
|
+
|
|
1876
|
+
let mediaTime;
|
|
1877
|
+
if (box.version === 0) {
|
|
1878
|
+
mediaTime = box.reader.readUint32();
|
|
1879
|
+
} else {
|
|
1880
|
+
try {
|
|
1881
|
+
mediaTime = box.reader.readUint64();
|
|
1882
|
+
} catch (e) {
|
|
1883
|
+
shaka.log.warning('parsePrft_: parsing mediatime resulted in a '+
|
|
1884
|
+
'MEDIA.JS_INTEGER_OVERFLOW exception');
|
|
1885
|
+
this.parsedPrftEventRaised_ = true;
|
|
1886
|
+
return;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
const timescale = reference.initSegmentReference.timescale;
|
|
1891
|
+
const wallClockTime = this.convertNtp(ntpTimestamp);
|
|
1892
|
+
const programStartDate = new Date(wallClockTime -
|
|
1893
|
+
(mediaTime / timescale) * 1000);
|
|
1894
|
+
const prftInfo = {
|
|
1895
|
+
wallClockTime,
|
|
1896
|
+
programStartDate,
|
|
1897
|
+
};
|
|
1898
|
+
|
|
1899
|
+
const eventName = shaka.util.FakeEvent.EventName.Prft;
|
|
1900
|
+
const data = (new Map()).set('detail', prftInfo);
|
|
1901
|
+
const event = new shaka.util.FakeEvent(
|
|
1902
|
+
eventName, data);
|
|
1903
|
+
this.playerInterface_.onEvent(event);
|
|
1904
|
+
this.parsedPrftEventRaised_ = true;
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
|
|
1908
|
+
/**
|
|
1909
|
+
* Convert Ntp ntpTimeStamp to UTC Time
|
|
1910
|
+
*
|
|
1911
|
+
* @param {number} ntpTimeStamp
|
|
1912
|
+
* @return {number} utcTime
|
|
1913
|
+
*/
|
|
1914
|
+
convertNtp(ntpTimeStamp) {
|
|
1915
|
+
const start = new Date(Date.UTC(1900, 0, 1, 0, 0, 0));
|
|
1916
|
+
return new Date(start.getTime() + ntpTimeStamp).getTime();
|
|
1917
|
+
}
|
|
1795
1918
|
|
|
1796
1919
|
/**
|
|
1797
1920
|
* Evicts media to meet the max buffer behind limit.
|
|
@@ -2071,10 +2194,12 @@ shaka.media.StreamingEngine = class {
|
|
|
2071
2194
|
* onError: function(!shaka.util.Error),
|
|
2072
2195
|
* onEvent: function(!Event),
|
|
2073
2196
|
* onManifestUpdate: function(),
|
|
2074
|
-
* onSegmentAppended: function(
|
|
2197
|
+
* onSegmentAppended: function(number, number,
|
|
2198
|
+
* !shaka.util.ManifestParserUtils.ContentType),
|
|
2075
2199
|
* onInitSegmentAppended: function(!number,!shaka.media.InitSegmentReference),
|
|
2076
2200
|
* beforeAppendSegment: function(
|
|
2077
|
-
* shaka.util.ManifestParserUtils.ContentType,!BufferSource):Promise
|
|
2201
|
+
* shaka.util.ManifestParserUtils.ContentType,!BufferSource):Promise,
|
|
2202
|
+
* onMetadata: !function(!Array.<shaka.extern.ID3Metadata>, number, ?number)
|
|
2078
2203
|
* }}
|
|
2079
2204
|
*
|
|
2080
2205
|
* @property {function():number} getPresentationTime
|
|
@@ -2097,14 +2222,19 @@ shaka.media.StreamingEngine = class {
|
|
|
2097
2222
|
* Called when an event occurs that should be sent to the app.
|
|
2098
2223
|
* @property {function()} onManifestUpdate
|
|
2099
2224
|
* Called when an embedded 'emsg' box should trigger a manifest update.
|
|
2100
|
-
* @property {function(
|
|
2225
|
+
* @property {function(number, number,
|
|
2226
|
+
* !shaka.util.ManifestParserUtils.ContentType)} onSegmentAppended
|
|
2101
2227
|
* Called after a segment is successfully appended to a MediaSource.
|
|
2228
|
+
* The parameters are the start and end time.
|
|
2102
2229
|
* @property
|
|
2103
2230
|
* {function(!number, !shaka.media.InitSegmentReference)} onInitSegmentAppended
|
|
2104
2231
|
* Called when an init segment is appended to a MediaSource.
|
|
2105
2232
|
* @property {!function(shaka.util.ManifestParserUtils.ContentType,
|
|
2106
2233
|
* !BufferSource):Promise} beforeAppendSegment
|
|
2107
2234
|
* A function called just before appending to the source buffer.
|
|
2235
|
+
* @property
|
|
2236
|
+
* {!function(!Array.<shaka.extern.ID3Metadata>, number, ?number)} onMetadata
|
|
2237
|
+
* Called when an ID3 is found in a EMSG.
|
|
2108
2238
|
*/
|
|
2109
2239
|
shaka.media.StreamingEngine.PlayerInterface;
|
|
2110
2240
|
|
package/lib/media/transmuxer.js
CHANGED
|
@@ -18,13 +18,18 @@ goog.require('shaka.dependencies');
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Transmuxer provides all operations for transmuxing from Transport
|
|
21
|
-
* Stream to MP4.
|
|
21
|
+
* Stream or AAC to MP4.
|
|
22
22
|
*
|
|
23
23
|
* @implements {shaka.util.IDestroyable}
|
|
24
24
|
*/
|
|
25
25
|
shaka.media.Transmuxer = class {
|
|
26
|
-
/**
|
|
27
|
-
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} mimeType
|
|
28
|
+
*/
|
|
29
|
+
constructor(mimeType) {
|
|
30
|
+
/** @private {string} */
|
|
31
|
+
this.originalMimeType_ = mimeType;
|
|
32
|
+
|
|
28
33
|
/** @private {?muxjs} */
|
|
29
34
|
this.muxjs_ = shaka.dependencies.muxjs();
|
|
30
35
|
|
|
@@ -42,9 +47,6 @@ shaka.media.Transmuxer = class {
|
|
|
42
47
|
/** @private {!Array.<muxjs.mp4.ClosedCaption>} */
|
|
43
48
|
this.captions_ = [];
|
|
44
49
|
|
|
45
|
-
/** @private {!Array.<muxjs.mp4.Metadata>} */
|
|
46
|
-
this.metadata_ = [];
|
|
47
|
-
|
|
48
50
|
/** @private {boolean} */
|
|
49
51
|
this.isTransmuxing_ = false;
|
|
50
52
|
|
|
@@ -64,7 +66,8 @@ shaka.media.Transmuxer = class {
|
|
|
64
66
|
|
|
65
67
|
|
|
66
68
|
/**
|
|
67
|
-
* Check if the content type is Transport Stream, and if muxjs is
|
|
69
|
+
* Check if the content type is Transport Stream or AAC, and if muxjs is
|
|
70
|
+
* loaded.
|
|
68
71
|
* @param {string} mimeType
|
|
69
72
|
* @param {string=} contentType
|
|
70
73
|
* @return {boolean}
|
|
@@ -72,41 +75,88 @@ shaka.media.Transmuxer = class {
|
|
|
72
75
|
static isSupported(mimeType, contentType) {
|
|
73
76
|
const Transmuxer = shaka.media.Transmuxer;
|
|
74
77
|
|
|
75
|
-
|
|
78
|
+
const isTs = Transmuxer.isTsContainer_(mimeType);
|
|
79
|
+
const isAac = Transmuxer.isAacContainer_(mimeType);
|
|
80
|
+
|
|
81
|
+
if (!shaka.dependencies.muxjs() || (!isTs && !isAac)) {
|
|
76
82
|
return false;
|
|
77
83
|
}
|
|
78
84
|
|
|
85
|
+
if (isAac) {
|
|
86
|
+
return MediaSource.isTypeSupported(Transmuxer.convertAacCodecs_());
|
|
87
|
+
}
|
|
88
|
+
|
|
79
89
|
if (contentType) {
|
|
80
90
|
return MediaSource.isTypeSupported(
|
|
81
|
-
Transmuxer.
|
|
91
|
+
Transmuxer.convertTsCodecs_(contentType, mimeType));
|
|
82
92
|
}
|
|
83
93
|
|
|
84
94
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
85
95
|
|
|
86
|
-
const audioMime = Transmuxer.
|
|
87
|
-
const videoMime = Transmuxer.
|
|
96
|
+
const audioMime = Transmuxer.convertTsCodecs_(ContentType.AUDIO, mimeType);
|
|
97
|
+
const videoMime = Transmuxer.convertTsCodecs_(ContentType.VIDEO, mimeType);
|
|
88
98
|
return MediaSource.isTypeSupported(audioMime) ||
|
|
89
99
|
MediaSource.isTypeSupported(videoMime);
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Check if the mimetype is 'audio/aac'.
|
|
105
|
+
* @param {string} mimeType
|
|
106
|
+
* @return {boolean}
|
|
107
|
+
* @private
|
|
108
|
+
*/
|
|
109
|
+
static isAacContainer_(mimeType) {
|
|
110
|
+
return mimeType.toLowerCase().split(';')[0] == 'audio/aac';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
93
114
|
/**
|
|
94
115
|
* Check if the mimetype contains 'mp2t'.
|
|
95
116
|
* @param {string} mimeType
|
|
96
117
|
* @return {boolean}
|
|
118
|
+
* @private
|
|
97
119
|
*/
|
|
98
|
-
static
|
|
120
|
+
static isTsContainer_(mimeType) {
|
|
99
121
|
return mimeType.toLowerCase().split(';')[0].split('/')[1] == 'mp2t';
|
|
100
122
|
}
|
|
101
123
|
|
|
102
124
|
|
|
125
|
+
/**
|
|
126
|
+
* For any stream, convert its codecs to MP4 codecs.
|
|
127
|
+
* @param {string} contentType
|
|
128
|
+
* @param {string} mimeType
|
|
129
|
+
* @return {string}
|
|
130
|
+
*/
|
|
131
|
+
static convertCodecs(contentType, mimeType) {
|
|
132
|
+
const Transmuxer = shaka.media.Transmuxer;
|
|
133
|
+
if (Transmuxer.isAacContainer_(mimeType)) {
|
|
134
|
+
return Transmuxer.convertAacCodecs_();
|
|
135
|
+
} else if (Transmuxer.isTsContainer_(mimeType)) {
|
|
136
|
+
return Transmuxer.convertTsCodecs_(contentType, mimeType);
|
|
137
|
+
}
|
|
138
|
+
return mimeType;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* For aac stream, convert its codecs to MP4 codecs.
|
|
144
|
+
* @return {string}
|
|
145
|
+
* @private
|
|
146
|
+
*/
|
|
147
|
+
static convertAacCodecs_() {
|
|
148
|
+
return 'audio/mp4; codecs="mp4a.40.2"';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
103
152
|
/**
|
|
104
153
|
* For transport stream, convert its codecs to MP4 codecs.
|
|
105
154
|
* @param {string} contentType
|
|
106
155
|
* @param {string} tsMimeType
|
|
107
156
|
* @return {string}
|
|
157
|
+
* @private
|
|
108
158
|
*/
|
|
109
|
-
static
|
|
159
|
+
static convertTsCodecs_(contentType, tsMimeType) {
|
|
110
160
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
111
161
|
let mp4MimeType = tsMimeType.replace(/mp2t/i, 'mp4');
|
|
112
162
|
if (contentType == ContentType.AUDIO) {
|
|
@@ -148,12 +198,20 @@ shaka.media.Transmuxer = class {
|
|
|
148
198
|
}
|
|
149
199
|
|
|
150
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Returns the original mimetype of the transmuxer.
|
|
203
|
+
* @return {string}
|
|
204
|
+
*/
|
|
205
|
+
getOrginalMimeType() {
|
|
206
|
+
return this.originalMimeType_;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
151
210
|
/**
|
|
152
211
|
* Transmux from Transport stream to MP4, using the mux.js library.
|
|
153
212
|
* @param {BufferSource} data
|
|
154
213
|
* @return {!Promise.<{data: !Uint8Array,
|
|
155
|
-
* captions: !Array.<!muxjs.mp4.ClosedCaption
|
|
156
|
-
* metadata: !Array.<!Object>}>}
|
|
214
|
+
* captions: !Array.<!muxjs.mp4.ClosedCaption>}>}
|
|
157
215
|
*/
|
|
158
216
|
transmux(data) {
|
|
159
217
|
goog.asserts.assert(!this.isTransmuxing_,
|
|
@@ -162,7 +220,6 @@ shaka.media.Transmuxer = class {
|
|
|
162
220
|
this.transmuxPromise_ = new shaka.util.PublicPromise();
|
|
163
221
|
this.transmuxedData_ = [];
|
|
164
222
|
this.captions_ = [];
|
|
165
|
-
this.metadata_ = [];
|
|
166
223
|
|
|
167
224
|
const dataArray = shaka.util.BufferUtils.toUint8(data);
|
|
168
225
|
this.muxTransmuxer_.push(dataArray);
|
|
@@ -200,7 +257,6 @@ shaka.media.Transmuxer = class {
|
|
|
200
257
|
*/
|
|
201
258
|
onTransmuxed_(segment) {
|
|
202
259
|
this.captions_ = segment.captions;
|
|
203
|
-
this.metadata_ = segment.metadata;
|
|
204
260
|
this.transmuxedData_.push(
|
|
205
261
|
shaka.util.Uint8ArrayUtils.concat(segment.initSegment, segment.data));
|
|
206
262
|
}
|
|
@@ -215,7 +271,6 @@ shaka.media.Transmuxer = class {
|
|
|
215
271
|
const output = {
|
|
216
272
|
data: shaka.util.Uint8ArrayUtils.concat(...this.transmuxedData_),
|
|
217
273
|
captions: this.captions_,
|
|
218
|
-
metadata: this.metadata_,
|
|
219
274
|
};
|
|
220
275
|
|
|
221
276
|
this.transmuxPromise_.resolve(output);
|
package/lib/offline/storage.js
CHANGED