Forum Discussion

RubaAbudia's avatar
RubaAbudia
Community Member
24 days ago
Solved

Disable Seeking in Storyline Videos

Hello, 

Can someone help me with this:

I have managed to find a way to hide the seeking bar and the playback button in Storyline videos (Please see the JavaScript triggers on slide 2 in the attached file). Also, I have added a variable and a condition so that when the user revisits the slide, they would be able to seek/speed up the video. 

Now, I want the user to be able to seek/speed up the video when rewatching it while they are still on the same slide (without revisiting the slide).

In other words, I want to replicate the exact same behavior for video seeking as the one in Rise 360 videos. I want the user to be able to seek only backwards the 1st time they're watching the video and to be able to seek freely the 2nd time watching the video even without leaving the slide. 

  • I recall seeing a similar approach shared on LinkedIn post some time ago by Malik, preventing users from skipping both ahead and backward in the video timeline which I don’t think is what you’re really looking for. You may want to review his code and adapt parts of his implementation to fit your specific use case.

    From a technical standpoint, I would recommend disabling Storyline’s native video controls and instead building custom video controls using HTML/CSS/JavaScript on top of the <video> element. Storyline’s internal video engine offers limited control and is difficult to intercept reliably, especially when you need fine-grained control over seeking, scrubbing, and user interaction.

    Below are a few examples that demonstrate both:

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

3 Replies

  • Nedim's avatar
    Nedim
    Community Member

    I recall seeing a similar approach shared on LinkedIn post some time ago by Malik, preventing users from skipping both ahead and backward in the video timeline which I don’t think is what you’re really looking for. You may want to review his code and adapt parts of his implementation to fit your specific use case.

    From a technical standpoint, I would recommend disabling Storyline’s native video controls and instead building custom video controls using HTML/CSS/JavaScript on top of the <video> element. Storyline’s internal video engine offers limited control and is difficult to intercept reliably, especially when you need fine-grained control over seeking, scrubbing, and user interaction.

    Below are a few examples that demonstrate both:

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • RubaAbudia's avatar
    RubaAbudia
    Community Member

    Thank you Nedim​ That worked! 

    I followed the steps in the LinkedIn post and used this JavaScript code instead to prevent the forward skipping, which produced a similar behavior to Rise video controls. 

    restrictVideoForwardSeekWithToast("INTRO.mp4");
    
    function restrictVideoForwardSeekWithToast(videoAccText) {
    
      const video = document.querySelector(
        `[data-acc-text="${videoAccText}"] video`
      );
    
      if (!video) {
        console.warn("Video not found. Check accessibility text.");
        return;
      }
    
      let maxTimeWatched = 0;
      let firstWatchCompleted = false;
      let lastToastTime = 0;
    
      const storageKey = `videoCompleted_${videoAccText}`;
      firstWatchCompleted = sessionStorage.getItem(storageKey) === "true";
    
      // ---------- TOAST ----------
      function showToast(message) {
    
        const now = Date.now();
        if (now - lastToastTime < 3000) return; // rate limit (3s)
        lastToastTime = now;
    
        let toast = document.getElementById("storyline-toast");
    
        if (!toast) {
          toast = document.createElement("div");
          toast.id = "storyline-toast";
          toast.innerText = message;
    
          Object.assign(toast.style, {
            position: "fixed",
            bottom: "40px",
            left: "50%",
            transform: "translateX(-50%)",
            background: "rgba(0,0,0,0.85)",
            color: "#fff",
            padding: "12px 18px",
            borderRadius: "6px",
            fontSize: "14px",
            zIndex: 9999,
            opacity: 0,
            transition: "opacity 0.3s ease"
          });
    
          document.body.appendChild(toast);
        }
    
        toast.style.opacity = "1";
    
        clearTimeout(toast.hideTimer);
        toast.hideTimer = setTimeout(() => {
          toast.style.opacity = "0";
        }, 2500);
      }
      // ---------- END TOAST ----------
    
      video.addEventListener("timeupdate", () => {
        if (!video.seeking && !firstWatchCompleted) {
          maxTimeWatched = Math.max(maxTimeWatched, video.currentTime);
        }
      });
    
      video.addEventListener("seeking", () => {
        if (!firstWatchCompleted && video.currentTime > maxTimeWatched + 0.25) {
          video.currentTime = maxTimeWatched;
          showToast("You can rewind, but you need to finish the video before skipping ahead.");
        }
      });
    
      video.addEventListener("ended", () => {
        firstWatchCompleted = true;
        sessionStorage.setItem(storageKey, "true");
      });
    }