xgplayer-mp4 1.2.4 → 2.0.2

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.
Files changed (84) hide show
  1. package/browser/index.js +1 -1
  2. package/browser/index.js.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/package.json +5 -4
  6. package/src/constants.js +14 -0
  7. package/src/fmp4/buffer.js +6 -0
  8. package/src/fmp4/mp4.js +181 -84
  9. package/src/gap_jump.js +151 -0
  10. package/src/index.js +550 -315
  11. package/src/media/mse.js +77 -22
  12. package/src/media/task.js +68 -17
  13. package/src/mp4.js +284 -268
  14. package/src/parse/box/MP4DecConfigDescrTag.js +3 -0
  15. package/src/parse/box/MP4DecSpecificDescrTag.js +4 -0
  16. package/src/parse/box/avcC.js +4 -1
  17. package/src/parse/box/elst.js +0 -13
  18. package/src/parse/box/esds.js +9 -4
  19. package/src/parse/box/frma.js +10 -0
  20. package/src/parse/box/golomb.js +88 -0
  21. package/src/parse/box/hvc1.js +30 -0
  22. package/src/parse/box/hvcC.js +55 -0
  23. package/src/parse/box/pasp.js +2 -3
  24. package/src/parse/box/schm.js +18 -0
  25. package/src/parse/box/sps.js +286 -0
  26. package/src/parse/box/stsz.js +6 -1
  27. package/src/parse/box/tfhd.js +43 -0
  28. package/src/parse/box.js +5 -1
  29. package/src/parse/stream.js +4 -0
  30. package/src/util/getHeaders.js +18 -0
  31. package/src/util/index.js +138 -20
  32. package/src/util/intervalTimer.js +36 -0
  33. package/src/util/isSupport.js +20 -0
  34. package/src/util/proxyPromise.js +27 -0
  35. package/src/util/timer.js +46 -0
  36. package/src/util/xhr.js +46 -0
  37. package/version.json +1 -1
  38. package/webpack.config.js +45 -39
  39. package/src/util/download.js +0 -13
  40. package/src/write/box/MP4DecConfigDescrTag.js +0 -21
  41. package/src/write/box/MP4DecSpecificDescrTag.js +0 -19
  42. package/src/write/box/MP4ESDescrTag.js +0 -19
  43. package/src/write/box/SLConfigDescriptor.js +0 -16
  44. package/src/write/box/avc1.js +0 -33
  45. package/src/write/box/avcC.js +0 -32
  46. package/src/write/box/btrt.js +0 -14
  47. package/src/write/box/co64.js +0 -17
  48. package/src/write/box/ctts.js +0 -19
  49. package/src/write/box/dref.js +0 -25
  50. package/src/write/box/elst.js +0 -27
  51. package/src/write/box/esds.js +0 -11
  52. package/src/write/box/ftyp.js +0 -17
  53. package/src/write/box/hdlr.js +0 -15
  54. package/src/write/box/iods.js +0 -14
  55. package/src/write/box/mdat.js +0 -5
  56. package/src/write/box/mdhd.js +0 -27
  57. package/src/write/box/mehd.js +0 -12
  58. package/src/write/box/mfhd.js +0 -12
  59. package/src/write/box/mfro.js +0 -14
  60. package/src/write/box/mp4a.js +0 -26
  61. package/src/write/box/mvhd.js +0 -34
  62. package/src/write/box/pasp.js +0 -10
  63. package/src/write/box/smhd.js +0 -17
  64. package/src/write/box/stco.js +0 -17
  65. package/src/write/box/stsc.js +0 -19
  66. package/src/write/box/stsd.js +0 -23
  67. package/src/write/box/stss.js +0 -17
  68. package/src/write/box/stsz.js +0 -18
  69. package/src/write/box/stts.js +0 -18
  70. package/src/write/box/tfdt.js +0 -16
  71. package/src/write/box/tfhd.js +0 -18
  72. package/src/write/box/tfra.js +0 -29
  73. package/src/write/box/tkhd.js +0 -44
  74. package/src/write/box/trex.js +0 -16
  75. package/src/write/box/trun.js +0 -40
  76. package/src/write/box/udta.js +0 -5
  77. package/src/write/box/url.js +0 -16
  78. package/src/write/box/vmhd.js +0 -19
  79. package/src/write/box/wide.js +0 -12
  80. package/src/write/box.js +0 -37
  81. package/src/write/buffer.js +0 -12
  82. package/src/write/index.js +0 -33
  83. package/src/write/stream.js +0 -99
  84. package/webpack.config.test.js +0 -8
@@ -5,6 +5,9 @@ Box.MP4DecConfigDescrTag = function (stream) {
5
5
  let box = new Box()
6
6
  let size
7
7
  box.type = stream.readUint8()
8
+ if (box.type !== 4) {
9
+ return box
10
+ }
8
11
  size = stream.readUint8()
9
12
  if (size === 0x80) {
10
13
  box.extend = true
@@ -4,6 +4,10 @@ Box.MP4DecSpecificDescrTag = function (stream) {
4
4
  let box = new Box()
5
5
  let size, dataSize
6
6
  box.type = stream.readUint8()
7
+ if (box.type !== 5) {
8
+ stream.position = stream.position - 1
9
+ return box
10
+ }
7
11
  size = stream.readUint8()
8
12
  if (size === 0x80) {
9
13
  box.extend = true
@@ -1,5 +1,7 @@
1
1
  import Box from '../box'
2
2
  import Stream from '../stream'
3
+ import SpsParser from './sps'
4
+
3
5
  Box.avcC = function () {
4
6
  let stream = new Stream(this.data)
5
7
  this.configVersion = stream.readUint8()
@@ -12,8 +14,9 @@ Box.avcC = function () {
12
14
  this.sequenceLength = sequenceLength
13
15
  let sequence = []
14
16
  for (let i = 0; i < sequenceLength; i++) {
15
- sequence.push(Number(stream.readUint8()).toString(16))
17
+ sequence.push(stream.readUint8())
16
18
  }
19
+ this.spsInfo = SpsParser.parseSPS(new Uint8Array(sequence))
17
20
  this.ppsCount = stream.readUint8()
18
21
  let ppsLength = stream.readUint16()
19
22
  this.ppsLength = ppsLength
@@ -7,9 +7,6 @@ Box.elst = function () {
7
7
  this.flag = Stream.readByte(stream.dataview, 3)
8
8
  let entries = []
9
9
  let entry_count = stream.readUint32()
10
- this.empty_duration = 0; // empty duration of the first edit list entry
11
- this.start_time = 0; // start time of the media
12
- let edit_start_index = 0;
13
10
  this.entries = entries
14
11
  for (let i = 0; i < entry_count; i++) {
15
12
  let entry = {}
@@ -23,17 +20,7 @@ Box.elst = function () {
23
20
  }
24
21
  entry.media_rate_integer = stream.readInt16()
25
22
  entry.media_rate_fraction = stream.readInt16()
26
-
27
- if (i === 0 && entry.media_time === -1) {
28
- /* if empty, the first entry is the start time of the stream
29
- * relative to the presentation itself */
30
- this.empty_duration = entry.segment_duration;
31
- edit_start_index = 1;
32
- } else if (i === edit_start_index && entry.media_time >= 0) {
33
- this.start_time = entry.media_time;
34
- }
35
23
  }
36
-
37
24
  delete this.subBox
38
25
  delete this.data
39
26
  stream = null
@@ -5,8 +5,13 @@ Box.esds = function () {
5
5
  let stream = new Stream(this.data)
6
6
  this.version = stream.readUint8()
7
7
  this.flag = Stream.readByte(stream.dataview, 3)
8
- let box = Box.MP4ESDescrTag(stream)
9
- this.subBox.push(box)
10
- delete this.data
11
- stream = null
8
+ try {
9
+ let box = Box.MP4ESDescrTag(stream)
10
+ this.subBox.push(box)
11
+ delete this.data
12
+ stream = null
13
+ }catch(e) {
14
+ console.error(e)
15
+ }
16
+
12
17
  }
@@ -0,0 +1,10 @@
1
+ import Box from '../box'
2
+ import Stream from '../stream'
3
+
4
+ Box.frma = function () {
5
+ let stream = new Stream(this.data)
6
+ this.data_format = '';
7
+ for (var i = 0; i < 4; i++) {
8
+ this.data_format += String.fromCharCode(stream.readUint8());
9
+ }
10
+ }
@@ -0,0 +1,88 @@
1
+ class Golomb {
2
+ constructor (uint8array) {
3
+ this.TAG = 'Golomb'
4
+ this._buffer = uint8array
5
+ this._bufferIndex = 0
6
+ this._totalBytes = uint8array.byteLength
7
+ this._totalBits = uint8array.byteLength * 8
8
+ this._currentWord = 0
9
+ this._currentWordBitsLeft = 0
10
+ }
11
+
12
+ destroy () {
13
+ this._buffer = null
14
+ }
15
+
16
+ _fillCurrentWord () {
17
+ let bufferBytesLeft = this._totalBytes - this._bufferIndex
18
+ if (bufferBytesLeft <= 0) {
19
+ // TODO 异常处理
20
+ }
21
+
22
+ let bytesRead = Math.min(4, bufferBytesLeft)
23
+ let word = new Uint8Array(4)
24
+ word.set(this._buffer.subarray(this._bufferIndex, this._bufferIndex + bytesRead))
25
+ this._currentWord = new DataView(word.buffer).getUint32(0)
26
+
27
+ this._bufferIndex += bytesRead
28
+ this._currentWordBitsLeft = bytesRead * 8
29
+ }
30
+
31
+ readBits (size) {
32
+ let bits = Math.min(this._currentWordBitsLeft, size);// :uint
33
+ let valu = this._currentWord >>> (32 - bits);
34
+ if (size > 32) {
35
+ throw new Error('Cannot read more than 32 bits at a time');
36
+ }
37
+ this._currentWordBitsLeft -= bits;
38
+ if (this._currentWordBitsLeft > 0) {
39
+ this._currentWord <<= bits;
40
+ } else if (this._totalBytes - this._bufferIndex > 0) {
41
+ this._fillCurrentWord();
42
+ }
43
+
44
+ bits = size - bits;
45
+ if (bits > 0 && this._currentWordBitsLeft) {
46
+ return valu << bits | this.readBits(bits);
47
+ } else {
48
+ return valu;
49
+ }
50
+ }
51
+
52
+ readBool () {
53
+ return this.readBits(1) === 1
54
+ }
55
+
56
+ readByte () {
57
+ return this.readBits(8)
58
+ }
59
+
60
+ _skipLeadingZero () {
61
+ let zeroCount
62
+ for (zeroCount = 0; zeroCount < this._currentWordBitsLeft; zeroCount++) {
63
+ if ((this._currentWord & (0x80000000 >>> zeroCount)) !== 0) {
64
+ this._currentWord <<= zeroCount
65
+ this._currentWordBitsLeft -= zeroCount
66
+ return zeroCount
67
+ }
68
+ }
69
+ this._fillCurrentWord()
70
+ return zeroCount + this._skipLeadingZero()
71
+ }
72
+
73
+ readUEG () { // unsigned exponential golomb
74
+ let leadingZeros = this._skipLeadingZero()
75
+ return this.readBits(leadingZeros + 1) - 1
76
+ }
77
+
78
+ readSEG () { // signed exponential golomb
79
+ let value = this.readUEG()
80
+ if (value & 0x01) {
81
+ return (value + 1) >>> 1
82
+ } else {
83
+ return -1 * (value >>> 1)
84
+ }
85
+ }
86
+ }
87
+
88
+ export default Golomb
@@ -0,0 +1,30 @@
1
+ import Box from '../box'
2
+ import Stream from '../stream'
3
+
4
+ Box.hvc1 = function () {
5
+ let stream = new Stream(this.data)
6
+ let self = this
7
+ stream.skip(6)
8
+ this.dataReferenceIndex = stream.readUint16()
9
+ stream.skip(16)
10
+ this.width = stream.readUint16()
11
+ this.height = stream.readUint16()
12
+ this.horizresolution = stream.readUint32()
13
+ this.vertresolution = stream.readUint32()
14
+ stream.skip(4)
15
+ this.frameCount = stream.readUint16()
16
+ stream.skip(1)
17
+ for (let i = 0; i < 31; i++) {
18
+ String.fromCharCode(stream.readUint8())
19
+ }
20
+ this.depth = stream.readUint16()
21
+ stream.skip(2)
22
+ while (stream.position < stream.buffer.byteLength) {
23
+ let box = new Box()
24
+ box.readHeader(stream)
25
+ self.subBox.push(box)
26
+ box.readBody(stream)
27
+ }
28
+ // delete this.data
29
+ stream = null
30
+ }
@@ -0,0 +1,55 @@
1
+ import Box from '../box'
2
+ import Stream from '../stream'
3
+ import SpsParser from './sps'
4
+
5
+ Box.hvcC = function () {
6
+ let stream = new Stream(this.data)
7
+ this.configVersion = stream.readUint8()
8
+ this.profile = stream.readUint8()
9
+ this.profileCompatibility = stream.readUint32()
10
+ this.constraintIndicatorFlags = []
11
+ for (let i = 0; i < 6; i++) {
12
+ this.constraintIndicatorFlags.push(Number(stream.readUint8()).toString(16))
13
+ }
14
+ this.levelIdc = stream.readUint8()
15
+ this.profileCompatibilityIndications = stream.readUint32()
16
+ this.bitDepthLumaMinus8 = stream.readUint8()
17
+ this.bitDepthChromaMinus8 = stream.readUint8()
18
+ this.avgFrameRate = stream.readUint16()
19
+ this.constantFrameRate = stream.readUint8()
20
+ this.numOfArrays = stream.readUint8()
21
+
22
+ this.vpsHeader = stream.readUint24()
23
+ this.vpsLength = stream.readUint16()
24
+ let vps = []
25
+ for (let i = 0; i < this.vpsLength; i++) {
26
+ vps.push(Number(stream.readUint8()).toString(16))
27
+ }
28
+ this.vps = vps
29
+
30
+ this.spsHeader = stream.readUint24()
31
+ this.spsLength = stream.readUint16()
32
+ let sps = []
33
+ for (let i = 0; i < this.spsLength; i++) {
34
+ sps.push(Number(stream.readUint8()).toString(16))
35
+ }
36
+ // this.spsInfo = SpsParser.parseSPS(new Uint8Array(sps))
37
+ this.sequence = sps
38
+
39
+ this.ppsHeader = stream.readUint24()
40
+ this.ppsLength = stream.readUint16()
41
+ let pps = []
42
+ for (let i = 0; i < this.ppsLength; i++) {
43
+ pps.push(Number(stream.readUint8()).toString(16))
44
+ }
45
+ this.pps = pps
46
+
47
+ let last = []; let dataviewLength = stream.dataview.byteLength
48
+ while (stream.position < dataviewLength) {
49
+ last.push(stream.readUint8())
50
+ }
51
+ this.last = last
52
+ delete this.subBox
53
+ // delete this.data
54
+ stream = null
55
+ }
@@ -2,8 +2,7 @@ import Box from '../box'
2
2
  import Stream from '../stream'
3
3
  Box.pasp = function () {
4
4
  let stream = new Stream(this.data)
5
- this.content = stream.buffer.slice(0, this.size - 8)
6
- delete this.subBox
7
- delete this.data
5
+ this.hSpacing = stream.readUint32();
6
+ this.vSpacing = stream.readUint32();
8
7
  stream = null
9
8
  }
@@ -0,0 +1,18 @@
1
+ import Box from '../box'
2
+ import Stream from '../stream'
3
+
4
+
5
+ Box.schm = function () {
6
+ let stream = new Stream(this.data)
7
+ this.scheme_version = stream.readUint32();
8
+ this.scheme_type = '';
9
+ for (var i = 0; i < 4; i++) {
10
+ this.scheme_type += String.fromCharCode(stream.readUint8());
11
+ }
12
+ if (this.flags & 0x000001) {
13
+ this.scheme_uri = '';
14
+ for (var i = 0; i < this.size - this.hdr_size - 8; i++) {
15
+ this.scheme_uri += String.fromCharCode(stream.readUint8());
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,286 @@
1
+ /* eslint-disable camelcase */
2
+ /* eslint-disable one-var */
3
+ import Golomb from './golomb'
4
+
5
+ class SPSParser {
6
+ static _ebsp2rbsp (uint8array) {
7
+ let src = uint8array
8
+ let srcLength = src.byteLength
9
+ let dst = new Uint8Array(srcLength)
10
+ let dstIdx = 0
11
+
12
+ for (let i = 0; i < srcLength; i++) {
13
+ if (i >= 2) {
14
+ if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {
15
+ continue
16
+ }
17
+ }
18
+ dst[dstIdx] = src[i]
19
+ dstIdx++
20
+ }
21
+
22
+ return new Uint8Array(dst.buffer, 0, dstIdx)
23
+ }
24
+
25
+ static parseSPS (uint8array) {
26
+ let rbsp = SPSParser._ebsp2rbsp(uint8array)
27
+ let gb = new Golomb(rbsp)
28
+
29
+ gb.readByte()
30
+ let profileIdc = gb.readByte()
31
+ gb.readByte()
32
+ let levelIdc = gb.readByte()
33
+ gb.readUEG()
34
+
35
+ let profile_string = SPSParser.getProfileString(profileIdc)
36
+ let level_string = SPSParser.getLevelString(levelIdc)
37
+ let chroma_format_idc = 1
38
+ let chroma_format = 420
39
+ let chroma_format_table = [0, 420, 422, 444]
40
+ let bit_depth = 8
41
+
42
+ if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 ||
43
+ profileIdc === 244 || profileIdc === 44 || profileIdc === 83 ||
44
+ profileIdc === 86 || profileIdc === 118 || profileIdc === 128 ||
45
+ profileIdc === 138 || profileIdc === 144) {
46
+ chroma_format_idc = gb.readUEG()
47
+ if (chroma_format_idc === 3) {
48
+ gb.readBits(1)
49
+ }
50
+ if (chroma_format_idc <= 3) {
51
+ chroma_format = chroma_format_table[chroma_format_idc]
52
+ }
53
+
54
+ bit_depth = gb.readUEG() + 8
55
+ gb.readUEG()
56
+ gb.readBits(1)
57
+ if (gb.readBool()) {
58
+ let scaling_list_count = (chroma_format_idc !== 3) ? 8 : 12
59
+ for (let i = 0; i < scaling_list_count; i++) {
60
+ if (gb.readBool()) {
61
+ if (i < 6) {
62
+ SPSParser._skipScalingList(gb, 16)
63
+ } else {
64
+ SPSParser._skipScalingList(gb, 64)
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+ gb.readUEG()
71
+ let pic_order_cnt_type = gb.readUEG()
72
+ if (pic_order_cnt_type === 0) {
73
+ gb.readUEG()
74
+ } else if (pic_order_cnt_type === 1) {
75
+ gb.readBits(1)
76
+ gb.readSEG()
77
+ gb.readSEG()
78
+ let num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG()
79
+ for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {
80
+ gb.readSEG()
81
+ }
82
+ }
83
+ gb.readUEG()
84
+ gb.readBits(1)
85
+
86
+ let pic_width_in_mbs_minus1 = gb.readUEG()
87
+ let pic_height_in_map_units_minus1 = gb.readUEG()
88
+
89
+ let frame_mbs_only_flag = gb.readBits(1)
90
+ if (frame_mbs_only_flag === 0) {
91
+ gb.readBits(1)
92
+ }
93
+ gb.readBits(1)
94
+
95
+ let frame_crop_left_offset = 0
96
+ let frame_crop_right_offset = 0
97
+ let frame_crop_top_offset = 0
98
+ let frame_crop_bottom_offset = 0
99
+
100
+ let frame_cropping_flag = gb.readBool()
101
+ if (frame_cropping_flag) {
102
+ frame_crop_left_offset = gb.readUEG()
103
+ frame_crop_right_offset = gb.readUEG()
104
+ frame_crop_top_offset = gb.readUEG()
105
+ frame_crop_bottom_offset = gb.readUEG()
106
+ }
107
+
108
+ let par_width = 1, par_height = 1
109
+ let fps = 0, fps_fixed = true, fps_num = 0, fps_den = 0
110
+
111
+ let vui_parameters_present_flag = gb.readBool()
112
+ if (vui_parameters_present_flag) {
113
+ if (gb.readBool()) { // aspect_ratio_info_present_flag
114
+ let aspect_ratio_idc = gb.readByte()
115
+ let par_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2]
116
+ let par_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1]
117
+
118
+ if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
119
+ par_width = par_w_table[aspect_ratio_idc - 1]
120
+ par_height = par_h_table[aspect_ratio_idc - 1]
121
+ } else if (aspect_ratio_idc === 255) {
122
+ par_width = gb.readByte() << 8 | gb.readByte()
123
+ par_height = gb.readByte() << 8 | gb.readByte()
124
+ }
125
+ }
126
+
127
+ if (gb.readBool()) {
128
+ gb.readBool()
129
+ }
130
+ if (gb.readBool()) {
131
+ gb.readBits(4)
132
+ if (gb.readBool()) {
133
+ gb.readBits(24)
134
+ }
135
+ }
136
+ if (gb.readBool()) {
137
+ gb.readUEG()
138
+ gb.readUEG()
139
+ }
140
+ if (gb.readBool()) {
141
+ let num_units_in_tick = gb.readBits(32)
142
+ let time_scale = gb.readBits(32)
143
+ fps_fixed = gb.readBool()
144
+
145
+ fps_num = time_scale
146
+ fps_den = num_units_in_tick * 2
147
+ fps = fps_num / fps_den
148
+ }
149
+ }
150
+
151
+ let parScale = 1
152
+ if (par_width !== 1 || par_height !== 1) {
153
+ parScale = par_width / par_height
154
+ }
155
+
156
+ let crop_unit_x = 0, crop_unit_y = 0
157
+ if (chroma_format_idc === 0) {
158
+ crop_unit_x = 1
159
+ crop_unit_y = 2 - frame_mbs_only_flag
160
+ } else {
161
+ let sub_wc = (chroma_format_idc === 3) ? 1 : 2
162
+ let sub_hc = (chroma_format_idc === 1) ? 2 : 1
163
+ crop_unit_x = sub_wc
164
+ crop_unit_y = sub_hc * (2 - frame_mbs_only_flag)
165
+ }
166
+
167
+ let codec_width = (pic_width_in_mbs_minus1 + 1) * 16
168
+ let codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16)
169
+
170
+ codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x
171
+ codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y
172
+
173
+ let present_width = Math.ceil(codec_width * parScale)
174
+
175
+ gb.destroy()
176
+ gb = null
177
+
178
+ return {
179
+ profile_string: profile_string,
180
+ level_string: level_string,
181
+ bit_depth: bit_depth,
182
+ chroma_format: chroma_format,
183
+ chroma_format_string: SPSParser.getChromaFormatString(chroma_format),
184
+
185
+ frame_rate: {
186
+ fixed: fps_fixed,
187
+ fps: fps,
188
+ fps_den: fps_den,
189
+ fps_num: fps_num
190
+ },
191
+
192
+ par_ratio: {
193
+ width: par_width,
194
+ height: par_height
195
+ },
196
+
197
+ codec_size: {
198
+ width: codec_width,
199
+ height: codec_height
200
+ },
201
+
202
+ present_size: {
203
+ width: present_width,
204
+ height: codec_height
205
+ }
206
+ }
207
+ }
208
+
209
+ static _skipScalingList (gb, count) {
210
+ let last_scale = 8, next_scale = 8
211
+ let delta_scale = 0
212
+ for (let i = 0; i < count; i++) {
213
+ if (next_scale !== 0) {
214
+ delta_scale = gb.readSEG()
215
+ next_scale = (last_scale + delta_scale + 256) % 256
216
+ }
217
+ last_scale = (next_scale === 0) ? last_scale : next_scale
218
+ }
219
+ }
220
+
221
+ static getProfileString (profileIdc) {
222
+ switch (profileIdc) {
223
+ case 66:
224
+ return 'Baseline'
225
+ case 77:
226
+ return 'Main'
227
+ case 88:
228
+ return 'Extended'
229
+ case 100:
230
+ return 'High'
231
+ case 110:
232
+ return 'High10'
233
+ case 122:
234
+ return 'High422'
235
+ case 244:
236
+ return 'High444'
237
+ default:
238
+ return 'Unknown'
239
+ }
240
+ }
241
+
242
+ static getLevelString (levelIdc) {
243
+ return (levelIdc / 10).toFixed(1)
244
+ }
245
+
246
+ static getChromaFormatString (chroma) {
247
+ switch (chroma) {
248
+ case 420:
249
+ return '4:2:0'
250
+ case 422:
251
+ return '4:2:2'
252
+ case 444:
253
+ return '4:4:4'
254
+ default:
255
+ return 'Unknown'
256
+ }
257
+ }
258
+
259
+ static toVideoMeta (spsConfig) {
260
+ let meta = {}
261
+ if (spsConfig && spsConfig.codec_size) {
262
+ meta.codecWidth = spsConfig.codec_size.width
263
+ meta.codecHeight = spsConfig.codec_size.height
264
+ meta.presentWidth = spsConfig.present_size.width
265
+ meta.presentHeight = spsConfig.present_size.height
266
+ }
267
+
268
+ meta.profile = spsConfig.profile_string
269
+ meta.level = spsConfig.level_string
270
+ meta.bitDepth = spsConfig.bit_depth
271
+ meta.chromaFormat = spsConfig.chroma_format
272
+
273
+ meta.parRatio = {
274
+ width: spsConfig.par_ratio.width,
275
+ height: spsConfig.par_ratio.height
276
+ }
277
+
278
+ meta.frameRate = spsConfig.frame_rate
279
+
280
+ let fpsDen = meta.frameRate.fps_den
281
+ let fpsNum = meta.frameRate.fps_num
282
+ meta.refSampleDuration = Math.floor(meta.timescale * (fpsDen / fpsNum))
283
+ }
284
+ }
285
+
286
+ export default SPSParser
@@ -10,7 +10,12 @@ Box.stsz = function () {
10
10
  let entries = []
11
11
  this.entries = entries
12
12
  for (let i = 0, count = this.count; i < count; i++) {
13
- entries.push(stream.readUint32())
13
+ if (this.sampleSize) {
14
+ entries.push(this.sampleSize)
15
+ }
16
+ else {
17
+ entries.push(stream.readUint32())
18
+ }
14
19
  }
15
20
  delete this.subBox
16
21
  delete this.data
@@ -0,0 +1,43 @@
1
+ import Box from '../box'
2
+ import Stream from '../stream'
3
+
4
+ Box.tfhd = function () {
5
+ let stream = new Stream(this.data)
6
+ this.version = stream.readUint8()
7
+ this.flag = Stream.readByte(stream.dataview, 3)
8
+
9
+ // trackId: view.getUint32(4)
10
+ this.track_id = stream.readUint32();
11
+
12
+ let baseDataOffsetPresent = (this.flag & 0xff) & 0x01;
13
+ let sampleDescriptionIndexPresent = (this.flag & 0xff) & 0x02;
14
+ let defaultSampleDurationPresent = (this.flag & 0xff) & 0x08;
15
+ let defaultSampleSizePresent = (this.flag & 0xff) & 0x10;
16
+ let defaultSampleFlagsPresent = (this.flag & 0xff) & 0x20;
17
+
18
+ let i = 8;
19
+ if (baseDataOffsetPresent) {
20
+ i += 4; // truncate top 4 bytes
21
+ this.baseDataOffset = stream.readUint32();
22
+ i += 4;
23
+ }
24
+ if (sampleDescriptionIndexPresent) {
25
+ this.sampleDescriptionIndex = stream.readUint32();
26
+ i += 4;
27
+ }
28
+ if (defaultSampleDurationPresent) {
29
+ this.defaultSampleDuration = stream.readUint32();
30
+ i += 4;
31
+ }
32
+ if (defaultSampleSizePresent) {
33
+ this.defaultSampleSize = stream.readUint32();
34
+ i += 4;
35
+ }
36
+ if (defaultSampleFlagsPresent) {
37
+ this.defaultSampleFlags = stream.readUint32();
38
+ }
39
+
40
+ delete this.subBox
41
+ delete this.data
42
+ stream = null
43
+ }
package/src/parse/box.js CHANGED
@@ -25,6 +25,10 @@ class Box {
25
25
  uuid.push(stream.readUint8())
26
26
  }
27
27
  }
28
+ if (this.type === 'pssh') {
29
+ this.version = stream.readUint8();
30
+ this.flags = stream.readUint8();
31
+ }
28
32
  }
29
33
  readBody (stream) {
30
34
  let end = this.size - stream.position + this.start
@@ -61,6 +65,6 @@ class Box {
61
65
  }
62
66
  }
63
67
 
64
- Box.containerBox = ['moov', 'trak', 'edts', 'mdia', 'minf', 'dinf', 'stbl', 'mvex', 'moof', 'traf', 'mfra']
68
+ Box.containerBox = ['moov', 'trak', 'edts', 'mdia', 'minf', 'dinf', 'stbl', 'mvex', 'moof', 'traf', 'mfra', 'sinf', 'schi']
65
69
 
66
70
  export default Box
@@ -90,6 +90,10 @@ class Stream {
90
90
  readUint16 () {
91
91
  return Stream.readByte(this.dataview, 2)
92
92
  }
93
+
94
+ readUint24 () {
95
+ return Stream.readByte(this.dataview, 3)
96
+ }
93
97
 
94
98
  readUint32 () {
95
99
  return Stream.readByte(this.dataview, 4)