From 270f87a7267b625c7ebf8a592059e3dea3c2623a Mon Sep 17 00:00:00 2001 From: Raymond Cheng Date: Fri, 3 Jun 2022 11:20:58 -0700 Subject: [PATCH] fix: Use middle segment when guessing MIME type on HLS (#4269) I have been working with a server which is too aggressive at expiring segments at the left edge of its DVR. As a result of this, when Shaka's HLS manifest parser puts out a HEAD request on the first segment to guess its MIME type, sometimes the segment has already been removed (404). I have filed a bug against the server team and I hope they relax the expiration, but truth be told if you wait long enough, any request against the left edge of DVR will eventually fail. It seems like a simple workaround for now to simply request the middle segment rather than the first segment. --- lib/hls/hls_parser.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/hls/hls_parser.js b/lib/hls/hls_parser.js index 9e0df8da0b..f59bbd8cfa 100644 --- a/lib/hls/hls_parser.js +++ b/lib/hls/hls_parser.js @@ -2267,12 +2267,16 @@ shaka.hls.HlsParser = class { const ContentType = shaka.util.ManifestParserUtils.ContentType; const requestType = shaka.net.NetworkingEngine.RequestType.SEGMENT; + // If you wait long enough, requesting the first segment can fail + // because it has fallen off the left edge of DVR, so to be safer, + // let's request the middle segment. goog.asserts.assert(playlist.segments.length, 'Playlist should have segments!'); - const firstSegmentUri = this.variableSubstitution_( - playlist.segments[0].absoluteUri, variables); + const middleSegmentIdx = Math.trunc((playlist.segments.length - 1) / 2); + const middleSegmentUri = this.variableSubstitution_( + playlist.segments[middleSegmentIdx].absoluteUri, variables); - const parsedUri = new goog.Uri(firstSegmentUri); + const parsedUri = new goog.Uri(middleSegmentUri); const extension = parsedUri.getPath().split('.').pop(); const map = HlsParser.EXTENSION_MAP_BY_CONTENT_TYPE_[contentType]; @@ -2302,7 +2306,7 @@ shaka.hls.HlsParser = class { // If unable to guess mime type, request a segment and try getting it // from the response. const headRequest = shaka.net.NetworkingEngine.makeRequest( - [firstSegmentUri], this.config_.retryParameters); + [middleSegmentUri], this.config_.retryParameters); headRequest.method = 'HEAD'; const response = await this.makeNetworkRequest_(