@@ -15,8 +15,11 @@ var parseType = require('../mp4/parse-type.js');
15
15
var parseTfhd = require ( '../tools/parse-tfhd.js' ) ;
16
16
var parseTrun = require ( '../tools/parse-trun.js' ) ;
17
17
var parseTfdt = require ( '../tools/parse-tfdt.js' ) ;
18
+ var getUint64 = require ( '../utils/numbers.js' ) . getUint64 ;
18
19
var timescale , startTime , compositionStartTime , getVideoTrackIds , getTracks ,
19
20
getTimescaleFromMediaHeader ;
21
+ var window = require ( 'global/window' ) ;
22
+
20
23
21
24
/**
22
25
* Parses an MP4 initialization segment and extracts the timescale
@@ -87,52 +90,55 @@ timescale = function(init) {
87
90
* fragment, in seconds
88
91
*/
89
92
startTime = function ( timescale , fragment ) {
90
- var trafs , baseTimes , result ;
93
+ var trafs , result ;
91
94
92
95
// we need info from two childrend of each track fragment box
93
96
trafs = findBox ( fragment , [ 'moof' , 'traf' ] ) ;
94
97
95
98
// determine the start times for each track
96
- baseTimes = [ ] . concat . apply ( [ ] , trafs . map ( function ( traf ) {
97
- return findBox ( traf , [ 'tfhd' ] ) . map ( function ( tfhd ) {
98
- var id , scale , baseTime ;
99
-
100
- // get the track id from the tfhd
101
- id = toUnsigned ( tfhd [ 4 ] << 24 |
102
- tfhd [ 5 ] << 16 |
103
- tfhd [ 6 ] << 8 |
104
- tfhd [ 7 ] ) ;
105
- // assume a 90kHz clock if no timescale was specified
106
- scale = timescale [ id ] || 90e3 ;
107
-
108
- // get the base media decode time from the tfdt
109
- baseTime = findBox ( traf , [ 'tfdt' ] ) . map ( function ( tfdt ) {
110
- var version , result ;
111
-
112
- version = tfdt [ 0 ] ;
113
- result = toUnsigned ( tfdt [ 4 ] << 24 |
114
- tfdt [ 5 ] << 16 |
115
- tfdt [ 6 ] << 8 |
116
- tfdt [ 7 ] ) ;
117
- if ( version === 1 ) {
118
- result *= Math . pow ( 2 , 32 ) ;
119
- result += toUnsigned ( tfdt [ 8 ] << 24 |
120
- tfdt [ 9 ] << 16 |
121
- tfdt [ 10 ] << 8 |
122
- tfdt [ 11 ] ) ;
123
- }
124
- return result ;
125
- } ) [ 0 ] ;
126
- baseTime = typeof baseTime === 'number' && ! isNaN ( baseTime ) ? baseTime : Infinity ;
99
+ var lowestTime = trafs . reduce ( function ( acc , traf ) {
100
+ var tfhd = findBox ( traf , [ 'tfhd' ] ) [ 0 ] ;
101
+
102
+ // get the track id from the tfhd
103
+ var id = toUnsigned ( tfhd [ 4 ] << 24 |
104
+ tfhd [ 5 ] << 16 |
105
+ tfhd [ 6 ] << 8 |
106
+ tfhd [ 7 ] ) ;
107
+ // assume a 90kHz clock if no timescale was specified
108
+ var scale = timescale [ id ] || 90e3 ;
109
+
110
+ // get the base media decode time from the tfdt
111
+ var tfdt = findBox ( traf , [ 'tfdt' ] ) [ 0 ] ;
112
+ var dv = new DataView ( tfdt . buffer , tfdt . byteOffset , tfdt . byteLength ) ;
113
+ var baseTime ;
114
+
115
+ // version 1 is 64 bit
116
+ if ( tfdt [ 0 ] === 1 ) {
117
+ baseTime = getUint64 ( tfdt . subarray ( 4 , 12 ) ) ;
118
+ } else {
119
+ baseTime = dv . getUint32 ( 4 ) ;
120
+ }
127
121
128
- // convert base time to seconds
129
- return baseTime / scale ;
130
- } ) ;
131
- } ) ) ;
122
+ // convert base time to seconds if it is a valid number.
123
+ let seconds ;
124
+ if ( typeof baseTime === 'bigint' ) {
125
+ seconds = baseTime / window . BigInt ( scale ) ;
126
+ } else if ( typeof baseTime === 'number' && ! isNaN ( baseTime ) ) {
127
+ seconds = baseTime / scale ;
128
+ }
129
+
130
+ if ( seconds < Number . MAX_SAFE_INTEGER ) {
131
+ seconds = Number ( seconds ) ;
132
+ }
132
133
133
- // return the minimum
134
- result = Math . min . apply ( null , baseTimes ) ;
135
- return isFinite ( result ) ? result : 0 ;
134
+ if ( seconds < acc ) {
135
+ acc = seconds ;
136
+ }
137
+
138
+ return acc ;
139
+ } , Infinity ) ;
140
+
141
+ return typeof lowestTime === 'bigint' || isFinite ( lowestTime ) ? lowestTime : 0 ;
136
142
} ;
137
143
138
144
/**
@@ -194,7 +200,18 @@ compositionStartTime = function(timescales, fragment) {
194
200
var timescale = timescales [ trackId ] || 90e3 ;
195
201
196
202
// return the composition start time, in seconds
197
- return ( baseMediaDecodeTime + compositionTimeOffset ) / timescale ;
203
+ if ( typeof baseMediaDecodeTime === 'bigint' ) {
204
+ compositionTimeOffset = window . BigInt ( compositionTimeOffset ) ;
205
+ timescale = window . BigInt ( timescale ) ;
206
+ }
207
+
208
+ var result = ( baseMediaDecodeTime + compositionTimeOffset ) / timescale ;
209
+
210
+ if ( typeof result === 'bigint' && result < Number . MAX_SAFE_INTEGER ) {
211
+ result = Number ( result ) ;
212
+ }
213
+
214
+ return result ;
198
215
} ;
199
216
200
217
/**
0 commit comments