Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: prefetch audio languages. #6139

Merged
merged 14 commits into from
Jan 29, 2024
46 changes: 28 additions & 18 deletions demo/config.js
Expand Up @@ -424,7 +424,19 @@ shakaDemo.Config = class {
.addBoolInput_('Parse PRFT box',
'streaming.parsePrftBox')
.addNumberInput_('Segment Prefetch Limit',
'streaming.segmentPrefetchLimit')
'streaming.segmentPrefetchLimit',
/* canBeDecimal= */ false,
/* canBeZero= */ true,
/* canBeUnset= */ true)
.addCustomTextInput_('Prefetch audio languages', (input) => {
shakaDemoMain.configure(
'streaming.prefetchAudioLanguages',
input.value.split(',').filter(Boolean));
})
.addBoolInput_('Disable Audio Prefetch',
'streaming.disableAudioPrefetch')
.addBoolInput_('Disable Video Prefetch',
'streaming.disableVideoPrefetch')
.addBoolInput_('Live Sync', 'streaming.liveSync')
.addNumberInput_('Max latency for live sync',
'streaming.liveSyncMaxLatency',
Expand Down Expand Up @@ -752,27 +764,25 @@ shakaDemo.Config = class {
addNumberInput_(name, valueName, canBeDecimal = false, canBeZero = true,
canBeUnset = false, tooltipMessage) {
const onChange = (input) => {
shakaDemoMain.resetConfiguration(valueName);
shakaDemoMain.remakeHash();
if (input.value == 'Infinity') {
shakaDemoMain.configure(valueName, Infinity);
shakaDemoMain.remakeHash();
return;
}
if (input.value == '' && canBeUnset) {
return;
}
const valueAsNumber = Number(input.value);
if (valueAsNumber == 0 && !canBeZero) {
return;
}
if (!isNaN(valueAsNumber)) {
if (Math.floor(valueAsNumber) != valueAsNumber && !canBeDecimal) {
return;
} else if (input.value == '' && canBeUnset) {
shakaDemoMain.resetConfiguration(valueName);
} else {
const valueAsNumber = Number(input.value);
if (valueAsNumber == 0 && !canBeZero) {
shakaDemoMain.resetConfiguration(valueName);
} else if (isNaN(valueAsNumber)) {
shakaDemoMain.resetConfiguration(valueName);
} else {
if (Math.floor(valueAsNumber) != valueAsNumber && !canBeDecimal) {
shakaDemoMain.resetConfiguration(valueName);
} else {
shakaDemoMain.configure(valueName, valueAsNumber);
}
}
shakaDemoMain.configure(valueName, valueAsNumber);
shakaDemoMain.remakeHash();
}
shakaDemoMain.remakeHash();
};
this.createRow_(name, tooltipMessage);
this.latestInput_ = new shakaDemo.NumberInput(
Expand Down
16 changes: 15 additions & 1 deletion externs/shaka/player.js
Expand Up @@ -1137,6 +1137,9 @@ shaka.extern.ManifestConfiguration;
* maxDisabledTime: number,
* parsePrftBox: boolean,
* segmentPrefetchLimit: number,
* prefetchAudioLanguages: !Array<string>,
* disableAudioPrefetch: boolean,
* disableVideoPrefetch: boolean,
* liveSync: boolean,
* liveSyncMaxLatency: number,
* liveSyncPlaybackRate: number,
Expand Down Expand Up @@ -1255,11 +1258,22 @@ shaka.extern.ManifestConfiguration;
* start date will not change, and would save parsing the segment multiple
* times needlessly.
* Defaults to <code>false</code>.
* @property {boolean} segmentPrefetchLimit
* @property {number} segmentPrefetchLimit
avelad marked this conversation as resolved.
Show resolved Hide resolved
* The maximum number of segments for each active stream to be prefetched
* ahead of playhead in parallel.
* If <code>0</code>, the segments will be fetched sequentially.
* Defaults to <code>0</code>.
* @property {!Array<string>} prefetchAudioLanguages
* The audio languages to prefetch.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching is a lot faster if rebufferingGoal is set to a low value. Is this something worth noting here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think it's necessary

* Defaults to an empty array.
* @property {boolean} disableAudioPrefetch
* If set and prefetch limit is defined, it will prevent from prefetching data
* for audio.
* Defaults to <code>false</code>.
* @property {boolean} disableVideoPrefetch
* If set and prefetch limit is defined, it will prevent from prefetching data
* for video.
* Defaults to <code>false</code>.
* @property {boolean} liveSync
* Enable the live stream sync against the live edge by changing the playback
* rate. Defaults to <code>false</code>.
Expand Down
21 changes: 12 additions & 9 deletions lib/media/segment_index.js
Expand Up @@ -434,10 +434,11 @@ shaka.media.SegmentIndex = class {
* Playlist will contain at least one independent frame."
*
* @param {number} time
* @param {boolean=} allowNonIndepedent
* @return {?shaka.media.SegmentIterator}
* @export
*/
getIteratorForTime(time) {
getIteratorForTime(time, allowNonIndepedent = false) {
let index = this.find(time);
if (index == null) {
return null;
Expand All @@ -455,14 +456,16 @@ shaka.media.SegmentIndex = class {
let r = ref.partialReferences[i];
// Note that a segment ends immediately before the end time.
if ((time >= r.startTime) && (time < r.endTime)) {
// Find an independent partial segment by moving backwards.
while (i && !r.isIndependent()) {
i--;
r = ref.partialReferences[i];
}
if (!r.isIndependent()) {
shaka.log.alwaysError('No independent partial segment found!');
return null;
if (!allowNonIndepedent) {
// Find an independent partial segment by moving backwards.
while (i && (!r.isIndependent())) {
i--;
r = ref.partialReferences[i];
}
if (!r.isIndependent()) {
shaka.log.alwaysError('No independent partial segment found!');
return null;
}
}
// Call to next() should move the partial segment, not the full
// segment.
Expand Down