Skip to content

Commit f4f9b05

Browse files
authored
feat: Parse TS frameRate (#6998)
1 parent 7fcc72c commit f4f9b05

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

lib/hls/hls_parser.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,6 +2473,7 @@ shaka.hls.HlsParser = class {
24732473
stream.height = stream.height || realStream.height;
24742474
stream.hdr = stream.hdr || realStream.hdr;
24752475
stream.colorGamut = stream.colorGamut || realStream.colorGamut;
2476+
stream.frameRate = stream.frameRate || realStream.frameRate;
24762477
if (stream.language == 'und' && realStream.language != 'und') {
24772478
stream.language = realStream.language;
24782479
}
@@ -2790,6 +2791,7 @@ shaka.hls.HlsParser = class {
27902791
let height = null;
27912792
let videoRange = null;
27922793
let colorGamut = null;
2794+
let frameRate = null;
27932795
if (segments.length > 0 && requestBasicInfo) {
27942796
const basicInfo = await this.getBasicInfoFromSegments_(segments);
27952797

@@ -2803,6 +2805,7 @@ shaka.hls.HlsParser = class {
28032805
width = basicInfo.width;
28042806
videoRange = basicInfo.videoRange;
28052807
colorGamut = basicInfo.colorGamut;
2808+
frameRate = basicInfo.frameRate;
28062809

28072810
if (allowOverrideMimeType) {
28082811
mimeType = basicInfo.mimeType;
@@ -2839,8 +2842,7 @@ shaka.hls.HlsParser = class {
28392842
if (type == shaka.util.ManifestParserUtils.ContentType.VIDEO &&
28402843
(width || height || videoRange || colorGamut)) {
28412844
this.addVideoAttributes_(stream, width, height,
2842-
/* frameRate= */ null, videoRange, /* videoLayout= */ null,
2843-
colorGamut);
2845+
frameRate, videoRange, /* videoLayout= */ null, colorGamut);
28442846
}
28452847

28462848
// This new calculation is necessary for Low Latency streams.

lib/media/segment_utils.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ shaka.media.SegmentUtils = class {
4242
closedCaptions: new Map(),
4343
videoRange: null,
4444
colorGamut: null,
45+
frameRate: null,
4546
};
4647
}
4748

@@ -127,6 +128,7 @@ shaka.media.SegmentUtils = class {
127128
closedCaptions: closedCaptions,
128129
videoRange: null,
129130
colorGamut: null,
131+
frameRate: videoInfo.frameRate,
130132
};
131133
}
132134

@@ -204,6 +206,8 @@ shaka.media.SegmentUtils = class {
204206
let realVideoRange = null;
205207
/** @type {?string} */
206208
let realColorGamut = null;
209+
/** @type {?string} */
210+
const realFrameRate = null;
207211

208212
/** @type {?string} */
209213
let baseBox;
@@ -432,6 +436,7 @@ shaka.media.SegmentUtils = class {
432436
closedCaptions: closedCaptions,
433437
videoRange: realVideoRange,
434438
colorGamut: realColorGamut,
439+
frameRate: realFrameRate,
435440
};
436441
}
437442

@@ -549,7 +554,8 @@ shaka.media.SegmentUtils = class {
549554
* sampleRate: ?number,
550555
* closedCaptions: Map.<string, string>,
551556
* videoRange: ?string,
552-
* colorGamut: ?string
557+
* colorGamut: ?string,
558+
* frameRate: ?string
553559
* }}
554560
*
555561
* @property {string} type
@@ -563,5 +569,6 @@ shaka.media.SegmentUtils = class {
563569
* @property {Map.<string, string>} closedCaptions
564570
* @property {?string} videoRange
565571
* @property {?string} colorGamut
572+
* @property {?string} frameRate
566573
*/
567574
shaka.media.SegmentUtils.BasicInfo;

lib/util/ts_parser.js

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
goog.provide('shaka.util.TsParser');
88

9+
goog.require('goog.asserts');
910
goog.require('shaka.Deprecate');
1011
goog.require('shaka.log');
1112
goog.require('shaka.util.ExpGolomb');
@@ -862,7 +863,8 @@ shaka.util.TsParser = class {
862863
/**
863864
* Return the video information
864865
*
865-
* @return {{height: ?string, width: ?string, codec: ?string}}
866+
* @return {{height: ?string, width: ?string, codec: ?string,
867+
* frameRate: ?string}}
866868
* @export
867869
*/
868870
getVideoInfo() {
@@ -872,10 +874,32 @@ shaka.util.TsParser = class {
872874
return this.getAvcInfo_();
873875
}
874876

877+
/**
878+
* @return {?string}
879+
* @private
880+
*/
881+
getFrameRate_() {
882+
const timescale = shaka.util.TsParser.Timescale;
883+
const videoData = this.getVideoData();
884+
if (videoData.length > 1) {
885+
const firstPts = videoData[0].pts;
886+
goog.asserts.assert(typeof(firstPts) == 'number',
887+
'Should be an number!');
888+
const secondPts = videoData[1].pts;
889+
goog.asserts.assert(typeof(secondPts) == 'number',
890+
'Should be an number!');
891+
if (!isNaN(secondPts - firstPts)) {
892+
return String(1 / (secondPts - firstPts) * timescale);
893+
}
894+
}
895+
return null;
896+
}
897+
875898
/**
876899
* Return the video information for AVC
877900
*
878-
* @return {{height: ?string, width: ?string, codec: ?string}}
901+
* @return {{height: ?string, width: ?string, codec: ?string,
902+
* frameRate: ?string}}
879903
* @private
880904
*/
881905
getAvcInfo_() {
@@ -884,6 +908,7 @@ shaka.util.TsParser = class {
884908
height: null,
885909
width: null,
886910
codec: null,
911+
frameRate: null,
887912
};
888913
const videoNalus = this.getVideoNalus();
889914
if (!videoNalus.length) {
@@ -995,14 +1020,16 @@ shaka.util.TsParser = class {
9951020
frameCropLeftOffset * 2 - frameCropRightOffset * 2);
9961021
videoInfo.codec = 'avc1.' + this.byteToHex_(profileIdc) +
9971022
this.byteToHex_(profileCompatibility) + this.byteToHex_(levelIdc);
1023+
videoInfo.frameRate = this.getFrameRate_();
9981024

9991025
return videoInfo;
10001026
}
10011027

10021028
/**
10031029
* Return the video information for HVC
10041030
*
1005-
* @return {{height: ?string, width: ?string, codec: ?string}}
1031+
* @return {{height: ?string, width: ?string, codec: ?string,
1032+
* frameRate: ?string}}
10061033
* @private
10071034
*/
10081035
getHvcInfo_() {
@@ -1011,6 +1038,7 @@ shaka.util.TsParser = class {
10111038
height: null,
10121039
width: null,
10131040
codec: null,
1041+
frameRate: null,
10141042
};
10151043
const videoNalus = this.getVideoNalus();
10161044
if (!videoNalus.length) {
@@ -1135,6 +1163,7 @@ shaka.util.TsParser = class {
11351163
generalConstraintIndicatorFlags1.toString(16).toUpperCase();
11361164
}
11371165
videoInfo.codec = codec;
1166+
videoInfo.frameRate = this.getFrameRate_();
11381167

11391168
return videoInfo;
11401169
}

0 commit comments

Comments
 (0)