1
0
mirror of https://github.com/psychopy/psychojs.git synced 2025-05-10 18:50:54 +00:00

Added proper coverage for cases with multiple movie stims try to access youtube. Proper positioning and volume applications.

This commit is contained in:
lightest 2023-08-11 18:00:16 +01:00
parent 6e03ccfea9
commit ebf71cea18
2 changed files with 30 additions and 9 deletions

View File

@ -300,9 +300,14 @@ export class MovieStim extends VisualStim
} }
} }
// If the html5Video is available and loaded enough, use information from it to convert NaN to proper values.
if (this._movie !== undefined && this._movie.readyState >= this._movie.HAVE_FUTURE_DATA)
{
size = this._ensureNaNSizeConversion(size, this._movie);
}
if (this._texture !== undefined) if (this._texture !== undefined)
{ {
size = this._ensureNaNSizeConversion(size, this._texture);
this._applySizeToPixi(size); this._applySizeToPixi(size);
} }
@ -329,7 +334,8 @@ export class MovieStim extends VisualStim
setPos(pos, log = false) setPos(pos, log = false)
{ {
super.setPos(pos); super.setPos(pos);
if (this._youtubePlayer !== undefined && this._ytPlayerIsReady) // if (this._youtubePlayer !== undefined && this._ytPlayerIsReady)
if (this._youtubePlayer !== undefined)
{ {
const pos_px = util.to_px(pos, this._units, this._win, false); const pos_px = util.to_px(pos, this._units, this._win, false);
pos_px[1] *= this._win._rootContainer.scale.y; pos_px[1] *= this._win._rootContainer.scale.y;
@ -398,6 +404,8 @@ export class MovieStim extends VisualStim
const ytPlayerBCR = this._youtubePlayer.getIframe().getBoundingClientRect(); const ytPlayerBCR = this._youtubePlayer.getIframe().getBoundingClientRect();
this._setAttribute("size", util.to_unit([ ytPlayerBCR.width, ytPlayerBCR.height ], "pix", this._win, this._units), true); this._setAttribute("size", util.to_unit([ ytPlayerBCR.width, ytPlayerBCR.height ], "pix", this._win, this._units), true);
} }
this.setVolume(this._volume, true);
} }
/** /**
@ -480,16 +488,16 @@ export class MovieStim extends VisualStim
} }
const urlObj = new URL(urlString); const urlObj = new URL(urlString);
if (this._youtubePlayer === undefined) if (this._youtubePlayer === undefined)
{ {
const vidSizePx = util.to_unit(this._size, this.units, this.win, "pix"); const vidSizePx = util.to_unit(this._size, this.units, this.win, "pix");
await YoutubeIframeAPIHandler.init(); await YoutubeIframeAPIHandler.init();
this._youtubePlayer = YoutubeIframeAPIHandler.createPlayer({ this._youtubePlayer = YoutubeIframeAPIHandler.createPlayer({
videoId: urlObj.searchParams.get("v"), videoId: urlObj.searchParams.get("v"),
width: vidSizePx[0], width: vidSizePx[0],
height: vidSizePx[1], height: vidSizePx[ 1 ],
playerVars: { playerVars: {
"rel": 0, "rel": 0,
"playsinline": 1, "playsinline": 1,
@ -508,6 +516,9 @@ export class MovieStim extends VisualStim
// "onApiChange": // "onApiChange":
} }
}); });
// At this point youtube player is added to the page. Invoking position setter to ensure html element is placed as expected.
this.pos = this._pos;
} }
else else
{ {
@ -693,19 +704,19 @@ export class MovieStim extends VisualStim
* *
* @param {Array} size * @param {Array} size
*/ */
_ensureNaNSizeConversion(size, pixiTex) _ensureNaNSizeConversion(size, html5Video)
{ {
if (Number.isNaN(size[0]) && Number.isNaN(size[1])) if (Number.isNaN(size[0]) && Number.isNaN(size[1]))
{ {
size = util.to_unit([pixiTex.width, pixiTex.height], "pix", this._win, this._units); size = util.to_unit([html5Video.videoWidth, html5Video.videoHeight], "pix", this._win, this._units);
} }
else if (Number.isNaN(size[0])) else if (Number.isNaN(size[0]))
{ {
size[0] = size[1] * (pixiTex.width / pixiTex.height); size[0] = size[1] * (html5Video.videoWidth / html5Video.videoHeight);
} }
else if (Number.isNaN(size[1])) else if (Number.isNaN(size[1]))
{ {
size[1] = size[0] / (pixiTex.width / pixiTex.height); size[1] = size[0] / (html5Video.videoWidth / html5Video.videoHeight);
} }
return size; return size;

View File

@ -16,6 +16,7 @@ class YoutubeIframeAPI
{ {
this.isReady = false; this.isReady = false;
this._initResolver = undefined; this._initResolver = undefined;
this._initPromise = undefined;
} }
_onYoutubeIframeAPIReady () _onYoutubeIframeAPIReady ()
@ -31,6 +32,13 @@ class YoutubeIframeAPI
return Promise.resolve(); return Promise.resolve();
} }
// If init is in progress but not done yet, return the promise.
// This is the case when multiple movie stims are created simultaneously.
if (this._initPromise)
{
return this._initPromise;
}
// Called by Youtube script. // Called by Youtube script.
window.onYouTubeIframeAPIReady = this._onYoutubeIframeAPIReady.bind(this); window.onYouTubeIframeAPIReady = this._onYoutubeIframeAPIReady.bind(this);
@ -39,9 +47,11 @@ class YoutubeIframeAPI
let firstScriptTag = document.getElementsByTagName("script")[0]; let firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(el, firstScriptTag); firstScriptTag.parentNode.insertBefore(el, firstScriptTag);
return new Promise((res, rej) => { this._initPromise = new Promise((res, rej) => {
this._initResolver = res; this._initResolver = res;
}); });
return this._initPromise;
} }
createPlayer (params = {}) createPlayer (params = {})