From 8f62151c6b1531223899408a472aa0545869dff3 Mon Sep 17 00:00:00 2001 From: Steve McConnel Date: Mon, 2 Dec 2024 15:25:48 -0700 Subject: [PATCH] fix: Get games to not play embedded videos twice (20241202) Also clean up playAllVideos in narration.ts a bit(which is now used only by Bloom Desktop) --- src/activities/dragActivities/DragToDestination.ts | 6 +++++- src/dragActivityRuntime.ts | 14 +++++++++----- src/narration.ts | 6 +++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/activities/dragActivities/DragToDestination.ts b/src/activities/dragActivities/DragToDestination.ts index 13c275dc..69ce340c 100644 --- a/src/activities/dragActivities/DragToDestination.ts +++ b/src/activities/dragActivities/DragToDestination.ts @@ -29,7 +29,11 @@ class DragToDestinationActivity implements IActivityObject { } public doInitialSoundAndAnimation(activityContext: ActivityContext) { - playInitialElements(activityContext.pageElement); + // As noted by the name of this method, we want to do the sound here not the video. + // Any video on the page has already been played by the time this is called by the + // Video.HandlePageVisible method. In fact, this is triggered by the final video + // ending event handler. + playInitialElements(activityContext.pageElement, false); } // Do just those things that we only want to do once per read of the book. diff --git a/src/dragActivityRuntime.ts b/src/dragActivityRuntime.ts index 14479aae..79650abd 100644 --- a/src/dragActivityRuntime.ts +++ b/src/dragActivityRuntime.ts @@ -358,7 +358,7 @@ function changePageButtonClicked(e: MouseEvent) { currentChangePageAction?.(next); } -export function playInitialElements(page: HTMLElement) { +export function playInitialElements(page: HTMLElement, playVideos: boolean) { const initialFilter = (e) => { const top = e.closest(".bloom-textOverPicture") as HTMLElement; if (!top) { @@ -387,9 +387,6 @@ export function playInitialElements(page: HTMLElement) { } return true; }; - const videoElements = Array.from(page.getElementsByTagName("video")).filter( - initialFilter, - ); const audioElements = getVisibleEditables(page).filter(initialFilter); //Slider: // This is used in drag-word-chooser-slider to mark the text item the user is currently @@ -402,7 +399,14 @@ export function playInitialElements(page: HTMLElement) { // audioElements.push(activeTextBox); // } const playables = getAudioSentences(audioElements); - playAllVideo(videoElements, () => playAllAudio(playables, page)); + if (playVideos) { + const videoElements = Array.from( + page.getElementsByTagName("video"), + ).filter(initialFilter); + playAllVideo(videoElements, () => playAllAudio(playables, page)); + } else { + playAllAudio(playables, page); + } } function getAudioSentences(editables: HTMLElement[]) { diff --git a/src/narration.ts b/src/narration.ts index b9b977ef..ecfc4c8f 100644 --- a/src/narration.ts +++ b/src/narration.ts @@ -1234,7 +1234,7 @@ export function hidingPage() { // Play the specified elements, one after the other. When the last completes (or at once if the array is empty), // perform the 'then' action (typically used to play narration, which we put after videos). // -// Note, there is a very similar function in narration.ts. It would be nice to combine them, but +// Note, there is a very similar function in video.ts. It would be nice to combine them, but // there are various reasons that is difficult at the moment. e.g.: // 1. See comment below about sharing code with Bloom Desktop. // 2. The other version handles play/pause which doesn't apply in BloomDesktop. @@ -1254,7 +1254,7 @@ export function playAllVideo(elements: HTMLVideoElement[], then: () => void) { video.readyState === HTMLMediaElement.HAVE_NOTHING ) { showVideoError(video); - this.playAllVideo(elements.slice(1)); + playAllVideo(elements.slice(1), then); } else { hideVideoError(video); // Review: do we need to do something to let the rest of the world know about this? @@ -1282,7 +1282,7 @@ export function playAllVideo(elements: HTMLVideoElement[], then: () => void) { .catch((reason) => { console.error("Video play failed", reason); showVideoError(video); - this.playAllVideo(elements.slice(1), then); + playAllVideo(elements.slice(1), then); }); } }