mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-13 15:46:46 +03:00
feat: Allow override subtitle position (#9522)
Close https://github.com/shaka-project/shaka-player/issues/9521 --------- Co-authored-by: Wojciech Tyczyński <tykus160@gmail.com>
This commit is contained in:
committed by
GitHub
parent
94abc9c4fb
commit
c6e6082bc2
+22
-8
@@ -344,15 +344,29 @@ shaka.text.Cue = class {
|
||||
clone() {
|
||||
const clone = new shaka.text.Cue(0, 0, '');
|
||||
|
||||
for (const k in this) {
|
||||
clone[k] = this[k];
|
||||
|
||||
// Make copies of array fields, but only one level deep. That way, if we
|
||||
// change, for instance, textDecoration on the clone, we don't affect the
|
||||
// original.
|
||||
if (Array.isArray(clone[k])) {
|
||||
clone[k] = /** @type {!Array} */(clone[k]).slice();
|
||||
/**
|
||||
* Deep clone helper
|
||||
* @param {*} value
|
||||
* @return {*}
|
||||
*/
|
||||
const deepClone = (value) => {
|
||||
if (value === null || typeof value !== 'object') {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(deepClone);
|
||||
}
|
||||
|
||||
const result = {};
|
||||
for (const key in value) {
|
||||
result[key] = deepClone(value[key]);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
for (const k in this) {
|
||||
clone[k] = deepClone(this[k]);
|
||||
}
|
||||
|
||||
return clone;
|
||||
|
||||
@@ -425,4 +425,36 @@ shaka.text.Utils = class {
|
||||
texTrack.mode = 'disabled';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all positioning-related properties of a cue, including all nested
|
||||
* cues.
|
||||
*
|
||||
* @param {!shaka.text.Cue} cue
|
||||
*/
|
||||
static resetCuePositioning(cue) {
|
||||
// Cue dummy to obtain the real default values
|
||||
const defaultCue = new shaka.text.Cue(0, 0, '');
|
||||
|
||||
/**
|
||||
* Copy default positioning values recursively
|
||||
*
|
||||
* @param {!shaka.text.Cue} target
|
||||
*/
|
||||
const reset = (target) => {
|
||||
target.line = defaultCue.line;
|
||||
target.lineAlign = defaultCue.lineAlign;
|
||||
target.position = defaultCue.position;
|
||||
target.positionAlign = defaultCue.positionAlign;
|
||||
target.size = defaultCue.size;
|
||||
target.displayAlign = defaultCue.displayAlign;
|
||||
target.region = defaultCue.region;
|
||||
|
||||
for (const nested of target.nestedCues) {
|
||||
reset(nested);
|
||||
}
|
||||
};
|
||||
|
||||
reset(cue);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
goog.provide('shaka.text.UITextDisplayer');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('shaka.config.PositionArea');
|
||||
goog.require('shaka.text.Cue');
|
||||
goog.require('shaka.text.CueRegion');
|
||||
goog.require('shaka.text.Utils');
|
||||
goog.require('shaka.util.Dom');
|
||||
goog.require('shaka.util.EventManager');
|
||||
goog.require('shaka.util.Lazy');
|
||||
goog.require('shaka.util.Timer');
|
||||
goog.requireType('shaka.Player');
|
||||
|
||||
@@ -331,7 +333,18 @@ shaka.text.UITextDisplayer = class {
|
||||
for (const cue of cues) {
|
||||
parents.push(cue);
|
||||
|
||||
let cueKey = cue;
|
||||
|
||||
let cueRegistry = this.currentCuesMap_.get(cue);
|
||||
if (!cueRegistry && this.config_ &&
|
||||
this.config_.positionArea != shaka.config.PositionArea.DEFAULT) {
|
||||
for (const key of this.currentCuesMap_.keys()) {
|
||||
if (shaka.text.Cue.equal(cue, key)) {
|
||||
cueKey = key;
|
||||
cueRegistry = this.currentCuesMap_.get(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
const shouldBeDisplayed =
|
||||
cue.startTime <= currentTime && cue.endTime > currentTime;
|
||||
let wrapper = cueRegistry ? cueRegistry.wrapper : null;
|
||||
@@ -350,7 +363,7 @@ shaka.text.UITextDisplayer = class {
|
||||
if (!shouldBeDisplayed) {
|
||||
// Since something has to be removed, we will need to update the DOM.
|
||||
updateDOM = true;
|
||||
this.currentCuesMap_.delete(cue);
|
||||
this.currentCuesMap_.delete(cueKey);
|
||||
cueRegistry = null;
|
||||
}
|
||||
}
|
||||
@@ -360,7 +373,7 @@ shaka.text.UITextDisplayer = class {
|
||||
if (!cueRegistry) {
|
||||
// The cue has to be made!
|
||||
this.createCue_(cue, parents);
|
||||
cueRegistry = this.currentCuesMap_.get(cue);
|
||||
cueRegistry = this.currentCuesMap_.get(cueKey);
|
||||
wrapper = cueRegistry.wrapper;
|
||||
updateDOM = true;
|
||||
} else if (!this.isElementUnderTextContainer_(wrapper)) {
|
||||
@@ -399,7 +412,15 @@ shaka.text.UITextDisplayer = class {
|
||||
}
|
||||
});
|
||||
for (const cue of toPlant) {
|
||||
const cueRegistry = this.currentCuesMap_.get(cue);
|
||||
let cueRegistry = this.currentCuesMap_.get(cue);
|
||||
if (!cueRegistry &&
|
||||
this.config_.positionArea != shaka.config.PositionArea.DEFAULT) {
|
||||
for (const key of this.currentCuesMap_.keys()) {
|
||||
if (shaka.text.Cue.equal(cue, key)) {
|
||||
cueRegistry = this.currentCuesMap_.get(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
goog.asserts.assert(cueRegistry, 'cueRegistry should exist.');
|
||||
if (cueRegistry.regionElement) {
|
||||
if (cueRegistry.regionElement.contains(container)) {
|
||||
@@ -445,9 +466,15 @@ shaka.text.UITextDisplayer = class {
|
||||
}
|
||||
}
|
||||
|
||||
let cues = this.cues_;
|
||||
if (this.config_ &&
|
||||
this.config_.positionArea != shaka.config.PositionArea.DEFAULT) {
|
||||
cues = cues.map((cue) => this.processCueStyle_(cue));
|
||||
}
|
||||
|
||||
// Update the cues.
|
||||
this.updateCuesRecursive_(
|
||||
this.cues_, this.textContainer_, currentTime, /* parents= */ []);
|
||||
cues, this.textContainer_, currentTime, /* parents= */ []);
|
||||
|
||||
if (goog.DEBUG) {
|
||||
// Previously, we had an issue (#2076) where cues sometimes were not
|
||||
@@ -466,6 +493,55 @@ shaka.text.UITextDisplayer = class {
|
||||
}
|
||||
}
|
||||
|
||||
/** @private */
|
||||
processCueStyle_(cue) {
|
||||
goog.asserts.assert(
|
||||
this.config_.positionArea !== shaka.config.PositionArea.DEFAULT,
|
||||
'processCueStyle_ is intended to use on non default positioning');
|
||||
const modifiedCue = cue.clone();
|
||||
shaka.text.Utils.resetCuePositioning(modifiedCue);
|
||||
modifiedCue.region = shaka.text.UITextDisplayer.CustomRegion_.value();
|
||||
switch (this.config_.positionArea) {
|
||||
case shaka.config.PositionArea.TOP_LEFT:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.LEFT;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.BEFORE;
|
||||
break;
|
||||
case shaka.config.PositionArea.TOP_CENTER:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.CENTER;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.BEFORE;
|
||||
break;
|
||||
case shaka.config.PositionArea.TOP_RIGHT:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.RIGHT;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.BEFORE;
|
||||
break;
|
||||
case shaka.config.PositionArea.CENTER_LEFT:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.LEFT;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.CENTER;
|
||||
break;
|
||||
case shaka.config.PositionArea.CENTER:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.CENTER;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.CENTER;
|
||||
break;
|
||||
case shaka.config.PositionArea.CENTER_RIGHT:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.RIGHT;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.CENTER;
|
||||
break;
|
||||
case shaka.config.PositionArea.BOTTOM_LEFT:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.LEFT;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.AFTER;
|
||||
break;
|
||||
case shaka.config.PositionArea.BOTTOM_CENTER:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.CENTER;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.AFTER;
|
||||
break;
|
||||
case shaka.config.PositionArea.BOTTOM_RIGHT:
|
||||
modifiedCue.textAlign = shaka.text.Cue.textAlign.RIGHT;
|
||||
modifiedCue.displayAlign = shaka.text.Cue.displayAlign.AFTER;
|
||||
break;
|
||||
}
|
||||
return modifiedCue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a unique internal id:
|
||||
* Regions can reuse the id but have different dimensions, we need to
|
||||
@@ -1037,3 +1113,16 @@ shaka.text.UITextDisplayer = class {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private {!shaka.util.Lazy<!shaka.text.CueRegion>}
|
||||
*/
|
||||
shaka.text.UITextDisplayer.CustomRegion_ = new shaka.util.Lazy(() => {
|
||||
const region = new shaka.text.CueRegion();
|
||||
region.id = 'shaka-custom-region';
|
||||
region.height = 90;
|
||||
region.width = 90;
|
||||
region.viewportAnchorX = 5;
|
||||
region.viewportAnchorY = 5;
|
||||
return region;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user