Skip to content

Commit

Permalink
refactor: drop support for the partial muxer and handlePartial (#1119)
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey committed Apr 26, 2021
1 parent b8a5aa5 commit ab305f8
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 1,392 deletions.
4 changes: 0 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,6 @@ <h3>Options</h3>
<input id=autoplay type="checkbox">
Autoplay
</label>
<label>
<input id=partial type="checkbox">
Handle Partial (reloads player)
</label>
<label>
<input id=llhls type="checkbox">
[EXPERIMENTAL] Enables support for ll-hls (reloads player)
Expand Down
18 changes: 1 addition & 17 deletions scripts/create-test-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@ const base64ToUint8Array = function(base64) {
return uint8Array;
};

const utf16CharCodesToString = (typedArray) => {
let val = '';

Array.prototype.forEach.call(typedArray, (x) => {
val += String.fromCharCode(x);
});

return val;
};

const getManifests = () => (fs.readdirSync(manifestsDir) || [])
.filter((f) => ((/\.(m3u8|mpd)/).test(path.extname(f))))
.map((f) => path.resolve(manifestsDir, f));
Expand Down Expand Up @@ -75,19 +65,13 @@ const buildSegmentString = function() {
dest.set(cache.${key});
return dest;
};`);
// strings can be used to fake responseText in progress events
// when testing partial appends of data
acc.push(`export const ${key}String = () => {
cache.${key}String = cache.${key}String || utf16CharCodesToString(${key}());
return cache.${key}String;
};`);

return acc;
}, []);

const segmentsFile =
'const cache = {};\n' +
`const base64ToUint8Array = ${base64ToUint8Array.toString()};\n` +
`const utf16CharCodesToString = ${utf16CharCodesToString.toString()};\n` +
segmentDataExportStrings.join('\n');

return segmentsFile;
Expand Down
9 changes: 0 additions & 9 deletions scripts/index-demo-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@
'minified',
'sync-workers',
'liveui',
'partial',
'llhls',
'url',
'type',
Expand Down Expand Up @@ -308,13 +307,6 @@
stateEls.minified.dispatchEvent(newEvent('change'));
});

stateEls.partial.addEventListener('change', function(event) {
saveState();

// reload the player and scripts
stateEls.minified.dispatchEvent(newEvent('change'));
});

stateEls['buffer-water'].addEventListener('change', function(event) {
saveState();

Expand Down Expand Up @@ -384,7 +376,6 @@
html5: {
vhs: {
overrideNative: getInputValue(stateEls['override-native']),
handlePartialData: getInputValue(stateEls.partial),
experimentalBufferBasedABR: getInputValue(stateEls['buffer-water']),
experimentalLLHLS: getInputValue(stateEls.llhls)
}
Expand Down
2 changes: 0 additions & 2 deletions src/master-playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ export class MasterPlaylistController extends videojs.EventTarget {
enableLowInitialPlaylist,
sourceType,
cacheEncryptionKeys,
handlePartialData,
experimentalBufferBasedABR
} = options;

Expand Down Expand Up @@ -223,7 +222,6 @@ export class MasterPlaylistController extends videojs.EventTarget {
sourceType: this.sourceType_,
inbandTextTracks: this.inbandTextTracks_,
cacheEncryptionKeys,
handlePartialData,
sourceUpdater: this.sourceUpdater_,
timelineChangeController: this.timelineChangeController_
};
Expand Down
140 changes: 37 additions & 103 deletions src/media-segment-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ const handleSegmentResponse = ({
const transmuxAndNotify = ({
segment,
bytes,
isPartial,
trackInfoFn,
timingInfoFn,
videoSegmentTimingInfoFn,
Expand Down Expand Up @@ -295,7 +294,6 @@ const transmuxAndNotify = ({
transmuxer: segment.transmuxer,
audioAppendStart: segment.audioAppendStart,
gopsToAlignWith: segment.gopsToAlignWith,
isPartial,
remux: isMuxed,
onData: (result) => {
result.type = result.type === 'combined' ? 'video' : result.type;
Expand Down Expand Up @@ -343,70 +341,58 @@ const transmuxAndNotify = ({
onCaptions: (captions) => {
captionsFn(segment, [captions]);
},
// if this is a partial transmux, the end of the timeline has not yet been reached
// until the last part of the segment is processed (at which point isPartial will
// be false)
isEndOfTimeline: isEndOfTimeline && !isPartial,
isEndOfTimeline,
onEndedTimeline: () => {
endedTimelineFn();
},
onDone: (result) => {
// To handle partial appends, there won't be a done function passed in (since
// there's still, potentially, more segment to process), so there's nothing to do.
if (!doneFn || isPartial) {
if (!doneFn) {
return;
}
result.type = result.type === 'combined' ? 'video' : result.type;
doneFn(null, segment, result);
}
});

// Check to see if we are appending a full segment.
if (!isPartial && !segment.lastReachedChar) {
// In the full segment transmuxer, we don't yet have the ability to extract a "proper"
// start time. Meaning cached frame data may corrupt our notion of where this segment
// really starts. To get around this, full segment appends should probe for the info
// needed.
workerCallback({
action: 'probeTs',
transmuxer: segment.transmuxer,
data: bytes,
baseStartTime: segment.baseStartTime,
callback: (data) => {
segment.bytes = bytes = data.data;

const probeResult = data.result;

if (probeResult) {
trackInfoFn(segment, {
hasAudio: probeResult.hasAudio,
hasVideo: probeResult.hasVideo,
isMuxed
});
trackInfoFn = null;

if (probeResult.hasAudio && !isMuxed) {
audioStartFn(probeResult.audioStart);
}
if (probeResult.hasVideo) {
videoStartFn(probeResult.videoStart);
}
audioStartFn = null;
videoStartFn = null;
}
// In the transmuxer, we don't yet have the ability to extract a "proper" start time.
// Meaning cached frame data may corrupt our notion of where this segment
// really starts. To get around this, probe for the info needed.
workerCallback({
action: 'probeTs',
transmuxer: segment.transmuxer,
data: bytes,
baseStartTime: segment.baseStartTime,
callback: (data) => {
segment.bytes = bytes = data.data;

const probeResult = data.result;

if (probeResult) {
trackInfoFn(segment, {
hasAudio: probeResult.hasAudio,
hasVideo: probeResult.hasVideo,
isMuxed
});
trackInfoFn = null;

finish();
if (probeResult.hasAudio && !isMuxed) {
audioStartFn(probeResult.audioStart);
}
if (probeResult.hasVideo) {
videoStartFn(probeResult.videoStart);
}
audioStartFn = null;
videoStartFn = null;
}
});
} else {
finish();
}

finish();
}
});
};

const handleSegmentBytes = ({
segment,
bytes,
isPartial,
trackInfoFn,
timingInfoFn,
videoSegmentTimingInfoFn,
Expand Down Expand Up @@ -539,7 +525,6 @@ const handleSegmentBytes = ({
transmuxAndNotify({
segment,
bytes,
isPartial,
trackInfoFn,
timingInfoFn,
videoSegmentTimingInfoFn,
Expand Down Expand Up @@ -605,7 +590,6 @@ const decryptSegment = ({
handleSegmentBytes({
segment,
bytes: segment.bytes,
isPartial: false,
trackInfoFn,
timingInfoFn,
videoSegmentTimingInfoFn,
Expand Down Expand Up @@ -739,7 +723,6 @@ const waitForCompletion = ({
handleSegmentBytes({
segment,
bytes: segment.bytes,
isPartial: false,
trackInfoFn,
timingInfoFn,
videoSegmentTimingInfoFn,
Expand Down Expand Up @@ -807,50 +790,14 @@ const handleProgress = ({
captionsFn,
isEndOfTimeline,
endedTimelineFn,
dataFn,
handlePartialData
dataFn
}) => (event) => {
const request = event.target;

if (request.aborted) {
return;
}

// don't support encrypted segments or fmp4 for now
if (
handlePartialData &&
!segment.key &&
// although responseText "should" exist, this guard serves to prevent an error being
// thrown on the next check for two primary cases:
// 1. the mime type override stops working, or is not implemented for a specific
// browser
// 2. when using mock XHR libraries like sinon that do not allow the override behavior
request.responseText &&
// in order to determine if it's an fmp4 we need at least 8 bytes
request.responseText.length >= 8
) {
const newBytes = stringToArrayBuffer(request.responseText.substring(segment.lastReachedChar || 0));

if (segment.lastReachedChar || !isLikelyFmp4MediaSegment(new Uint8Array(newBytes))) {
segment.lastReachedChar = request.responseText.length;

handleSegmentBytes({
segment,
bytes: newBytes,
isPartial: true,
trackInfoFn,
timingInfoFn,
videoSegmentTimingInfoFn,
audioSegmentTimingInfoFn,
id3Fn,
captionsFn,
isEndOfTimeline,
endedTimelineFn,
dataFn
});
}
}

segment.stats = videojs.mergeOptions(segment.stats, getProgressStats(event));

// record the time that we receive the first byte of data
Expand Down Expand Up @@ -945,8 +892,7 @@ export const mediaSegmentRequest = ({
isEndOfTimeline,
endedTimelineFn,
dataFn,
doneFn,
handlePartialData
doneFn
}) => {
const activeXhrs = [];
const finishProcessingFn = waitForCompletion({
Expand Down Expand Up @@ -998,17 +944,6 @@ export const mediaSegmentRequest = ({
headers: segmentXhrHeaders(segment)
});

if (handlePartialData) {
// setting to text is required for partial responses
// conversion to ArrayBuffer happens later
segmentRequestOptions.responseType = 'text';
segmentRequestOptions.beforeSend = (xhrObject) => {
// XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
// makes the browser pass through the "text" unparsed
xhrObject.overrideMimeType('text/plain; charset=x-user-defined');
};
}

const segmentRequestCallback = handleSegmentResponse({
segment,
finishProcessingFn,
Expand All @@ -1029,8 +964,7 @@ export const mediaSegmentRequest = ({
captionsFn,
isEndOfTimeline,
endedTimelineFn,
dataFn,
handlePartialData
dataFn
})
);
activeXhrs.push(segmentXhr);
Expand Down
Loading

0 comments on commit ab305f8

Please sign in to comment.