www.webdeveloper.com
Results 1 to 6 of 6

Thread: [RESOLVED] Accessing Video Clip Time Mark During Play for Slideshow

  1. #1
    Join Date
    Jul 2010
    Posts
    66

    resolved [RESOLVED] Accessing Video Clip Time Mark During Play for Slideshow

    Can scripting be used to access the time mark during play so that images can be rolled next to it to make a slideshow?

  2. #2
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    741
    While this can be done, you won't have full cross-browser compatibility (for some older versions of IE and some mobile browsers).

    Through the use of the HTML5 <video> tag you can play the video on your page and access its time mark location through javascript.
    HTML Code:
    <video id="vidElem" width="640" height="480">
      <source src="movie.webm" type="video/webm" />
      <source src="movie.mp4" type="video/mp4">
      <source src="movie.ogg" type="video/ogg">
      Your browser does not support the video tag.
    </video>
    Code:
    var $video = document.getElementById('vidElem');
    $video.addEventListener("canplay", _InitSync, false);
    
    function _InitSync() {
      $video.addEventListener("timeupdate", _SyncSlides, false);
    }
    function _SyncSlides() {
      $curTime = $video.currentTime;
    }
    To be honest I haven't tested this code personally, but all of it should be valid. In the end you will have a variable with the current time mark of the video that will be updated as the video plays. Also I'm not even sure the '_InitSync()' function was a necessary step but I added it more or less to be safe. Basically this will wait for the video element to be ready and then once it is, it will add an event that fires every time the video changes it time marker. In this final function you would simply add some code that would change your slides based on the value of $curTime.

    Let me know if this resolves your issue or not.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  3. #3
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    that's going to add a new watcher every time the video loads, when it only needs to happen once.
    not sure if it will break the simple demo, but it's something to watch for.

  4. #4
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    741
    The _InitSync() does really only need to happen once and that's why I said it probably wasn't really even necessary. There are certainly better ways to set that up. You would just need to make sure it sets the timeupdate event watcher after the video is ready and loaded. The timeupdate event part is fine though; it's typically used for displaying the video time in a custom interface/custom controls and seems to fit well for this situation.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  5. #5
    Join Date
    Jul 2010
    Posts
    66
    Quote Originally Posted by Sup3rkirby View Post
    Let me know if this resolves your issue or not.
    Okay, this code seems to be working, although I will be doing more optimizing to get the right features.

    After reading about the media object (Audio, Video elements) interface at MSDN and elsewhere to learn
    more about object properties, methods, and the events affecting them (thanks to your guidance),
    I have slightly modified your functions. The modifications basically use anonymous functions to define
    the handlers and pass on arguments into the event handlers themselves.

    Global scope script variables are initialized in that scope, namely array of numbers (in seconds)
    for the time marks at which I want an image to change in the slideshow document block (a P element,
    in this case). Images are basically rotated in and out using DOM methods ( replaceChild() ).
    The initialize() function is used after the body is loaded to intiailize the rest of the global variables
    that are DOM document nodes. Images for the slideshow are also pre-loaded into an array. Many of
    the numerical constants (e.g., "500px") worked for my presentation, and should be altered for another's
    particular document styling/spacing.

    This particular set up does not "go backwards" perhaps in case the user does a backward seek on the
    playback of the control, but that is easy enough to code in.

    The reason I making this slideshow is that it is a ballet show with many dancers in the scene.
    I am pointing out a particular dancer (this is an "Arts Resume" and the web page link will be sent to
    dance instructors) but snapshotting a video instance, putting a simple arrow in Photoshop to
    point out the dancer, it allows the instructors to identify the dancer, whom they have never met.


    HTML Code:
    <head>
    <!--
    .
    .
    -->
    <script type="text/javascript">
    var slidesBlock, // DOM element containing slideshow images
       timeMarks = [ 50, 70, 80, 170, 200, 250 ],
       timeMarkIndex = 0,
       currentTimeMark = timeMarks[timeMarkIndex],
       preloadedImages = [];
    
    function initialize() {
       var i, img, index,
          myVid = document.getElementById("ballet-vid"),
          slidesBlock = document.getElementById("slideshow");
    
       if (typeof myVid.addEventListener == "function")
          myVid.addEventListener("canplay", function () {
                 initSync(myVid, slidesBlock); }, false);
      else if (typeof myVid.attachEvent == "function")
          myVid.attachEvent("oncanplay", function () {
                 initSync(myVid, slidesBlock); } );
      // preload images
      for (i = 0; i < timeMarks.length; i++) {
         img = new Image();
         img.alt = "still #" + (i + 1) + " of My Video";
         index = "0";
         if (i < 9)
           index += i + 1;
         else
           index = i + 1
         img.src = "StillsOfMyVideo-" + index + ".png";
         img.style.width = "500px";
         preloadedImages.push(img);
       }
    }
    
    function initSync(vidClip, slideShowBlock) {
        if (typeof vidClip.addEventListener == "function")
           vidClip.addEventListener("timeupdate", function () {
                    syncSlides(vidClip, slideShowBlock); }, false);
        else if (typeof vidClip.attachEvent == "function")
           vidClip.attachEvent("ontimeupdate", function () {
                   syncSlides(vidClip, slideShowBlock); } );
    }
    
    function syncSlides(vidClip, slideShowBlock) {
        if (vidClip.currentTime > currentTimeMark) {
           slideShowBlock.replaceChild(preloadedImages[timeMarkIndex++], slideShowBlock.firstChild);
           currentTimeMark = timeMarks[timeMarkIndex];
        }
    }
    
    </script>
    </head>
    <body onload="initialize();">
    
    <p style-"margin:0;">
    <video controls preload id="ballet-vid" poster="poster.png"
    style="float:left;margin:0 1.5em 0.5em -10%;border:1px solid lime;">
       style="border:1px solid lime;padding:0;margin:0;">
    	<source src="myvid.mpg" type="video/mpeg">
    	<source src="myvid.mp4" type="video/mp4">
    	<source src="myvid.webm" type="video/webm">
    	<object data="myvid.mpg" type="video/mpeg" width="750" height="600">
    	  <embed src="myvid.mpg" type="video/mpeg" width="750" height="600">
    	</object>
    </video>
    
    <p id="slideshow"><img src="poster.png" alt="initial image of slideshow">
    </body>

  6. #6
    Join Date
    Jul 2010
    Posts
    66
    I am marking this resolved since the solution offered by Sup3rkirby discusses the timeupdate event, and that is the essential answer to the problem.

    I have significantly modified Sup3kirby's original code however.

    For one thing, I have eliminated the canplay event handler as the intermediate invoking the timeupdate event. It is not really necessary. Whenever the canplay handler is called, it would continually attempt code to add the timeupdate event handler, and that is not necessary it seems. I found that removing this intermediate code (the canplay handler) has the same wanted effect.

    As to my timeupdate handler, it is responsible for a number of actions in my slideshow program:

    • It rotates images (as objects) in and out of a DOM block (div or p) element as the first (and only) child of the element, based on the time value continually updated by the timeupdate handler
    • It also "rotates" text to change the caption: in my particular strategy, I have a number of div elements all of whose display is set to "none" during document initialization. As a time mark is reached, a display is set to "" (empty string), as good as displaying the element by its default styling.
    • For a couple of elements, the text is small enough that I do a replaceChild() methods on text nodes, which are created in the handler
    • I have created a seeked handler as well: what if the user changes the playback position control to an earlier or later time? In that case the appropriate slide and explanatory text must be updated. It basically runs a for-loop to look at an array of times (integer values in seconds) to find the correct array index position, and uses that to put up the photos and text.


    Debugging an event handler in general can be a pain. And debugging one where the object generating events is an audio or video playback has proven difficult still:

    For example, I have set a breakpoint inside the timeupdate and seeked handler code because I want to check problems with code logic.

    The CONTINUING PROBLEM is that while the breakpoint is reached, the media object (video) continues playback. I have put a videoObj.pause() just inside the two event handlers at the start, and a video.play() as the last statement in those handlers. But as the debugger reaches the breakpoint in the timeupdate handler, just after executing the videoObj.pause() method, the video playback has not paused at all...it continues!

    I cannot imagine what event is taking over and forcing the media object to execute a .play() method.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles