Order Now AdSolution Sign Up | Login » Bits on the Run Sign Up | Login »

Stop Points: Defining playback duration

64 replies [Last post]

I love the new "chapterizing" capabilities with the 4.0 player! Seeking to a preset time in the track is so powerful when leveraged with playlists, well done! What would really be nice is the ability to define a window/duration for playback to occur.

Take this simple scenario:

You have an educational video that is 1 hour long, so you create chapters to enhance the user experience.

You create the chapter playlist and break the video into 4 chapters:

- chapter 1 starts at the beginning 00:00
- chapter 2 starts at the halfway point 30:00
- chapter 3 starts at forty minutes 40:00
- chapter 4 starts 10 mins before the end 50:00

however, let's say Chapter 2 only has about 5 minutes of relative content and you want to "jump" or "skip" to the next entry in the playlist after the five minutes is up (you would be skipping 35:00-39:59 of the track) Is something like this possible today?

If not, I would love to see the ability to set a "stop" point (as with the "start" parameter) that would effectively stop the video and advance to the next item in the playlist.

Thoughts?

I too would like to see something that allows for chapter stopping.

My integration scenario is that a person is comparing a chapter between 3 different videos. The playlist is setup in order of each video, with their own predetermined start times. After watching 10 secs of the first video, I want it to jump to the next video and play another 10 secs, and so on and so forth.

Help?

I'll investigate it:

http://code.longtailvideo.com/trac/ticket/151

PLEASE don't push this back to 4.3! Is there any way to include it in 4.2 in September?

<crosses fingers />

This could easily be done with a snippet of JavaScript that advanced the player to the next track when the elapsed time (relative) or position (absolute) reached a value that was in the playlist in one of the unused or meta elements.

Interested??? :D

Sure.

Right now I'm simply listening to the TIME event and sending the STOP event if the current time is >= to my end point. Works for now but it's pretty kludgy.

@Nic,

So what is it that you really want to do?

I'm thinking of having a choice of a end or dur (duration) meta element in the playlist that would be used to determine the end or playing time of the media selection. When that event occurred, you could trigger anything, like start the next track, load a different playlist, load a different page, etc.

Anything else?

Sample HTML page and playlist for using an end parameter (absolute time from the beginning of the file) —–OR—– a dur parameter (relative time from the beginning of the chapter/clip).

Select the type here:

    //var advance         = 'end';
      var advance         = 'dur';

Sample playlist with both types of advance:
<?xml version='1.0' encoding='UTF-8'?>
<playlist version='1' xmlns='http://xspf.org/ns/0/'>
  <trackList>
    <track>
      <creator>Stephen King</creator>
      <title>1408-1</title>
      <location>1408</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>0</meta>
      <meta rel='end'>10</meta>
      <meta rel='dur'>10</meta>
      <image>http://my.domain.com/Images/1408-1.jpg</image>
      <annotation>00:00:00-00:00:10 Duration 00:00:10</annotation>
      <info>http://my.domain.com/</info>
    </track>
    <track>
      <creator>Stephen King</creator>
      <title>1408-2</title>
      <location>1408</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>120</meta>
      <meta rel='end'>135</meta>
      <meta rel='dur'>15</meta>
      <image>http://my.domain.com/Images/1408-2.jpg</image>
      <annotation>00:02:00-00:02:15 Duration 00:00:15</annotation>
      <info>http://my.domain.com/</info>
    </track>
    <track>
      <creator>Stephen King</creator>
      <title>1408-3</title>
      <location>1408</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>180</meta>
      <meta rel='end'>200</meta>
      <meta rel='dur'>20</meta>
      <image>http://my.domain.com/Images/1408-3.jpg</image>
      <annotation>00:03:00-00:03:20 Duration 00:00:20</annotation>
      <info>http://my.domain.com/</info>
    </track>
    <track>
      <creator>Stephen King</creator>
      <title>1408-4</title>
      <location>1408</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>300</meta>
      <meta rel='end'>305</meta>
      <meta rel='dur'>5</meta>
      <image>http://my.domain.com/Images/1408-4.jpg</image>
      <annotation>00:05:00-00:05:05 Duration 00:00:05</annotation>
      <info>http://my.domain.com/</info>
    </track>
    <track>
      <creator>Stephen King</creator>
      <title>1408-5</title>
      <location>1408</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>420</meta>
      <meta rel='end'>430</meta>
      <meta rel='dur'>10</meta>
      <image>http://my.domain.com/Images/1408-5.jpg</image>
      <annotation>00:07:00-00:07:10 Duration 00:00:10</annotation>
      <info>http://my.domain.com/</info>
    </track>
    <track>
      <creator>Stephen King</creator>
      <title>1408-6</title>
      <location>1408</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>600</meta>
      <meta rel='end'>615</meta>
      <meta rel='dur'>15</meta>
      <image>http://my.domain.com/Images/1408-6.jpg</image>
      <annotation>00:10:00-00:10:15 Duration 00:00:15</annotation>
      <info>http://my.domain.com/</info>
    </track>
  </trackList>
</playlist>

Sample page to utilize end and dur for chapters:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">

  <head>

    <title>End & Duration for Chapters - JWMP v4</title>

    <script type="text/javascript" src="swfobject-2.1.js"></script>

    <script type="text/javascript">
      var flashvars =
      {
        fullscreen:           'true',
        playlistsize:         '300',
        playlist:             'right',
        repeat:               'list',
        shuffle:              'false',
        skin:                 'snel.swf',
        bufferlength:         'null',
        streamer:             'rtmp://my.domain.com/oflaDemo',
        file:                 'http://my.domain.com/path/playlist_end_duration.xml'
      };

      var params =
      {
        allowscriptaccess:    'always',
        allowfullscreen:      'true',
        bgcolor:              '#FFFFFF'
      };

      var attributes =
      {
        id:                   'playerId',
        name:                 'playerId'
      };

      swfobject.embedSWF('player.swf', 'player', '700', '300', '9.0.124', false, flashvars, params, attributes);
    </script>

    <script type="text/javascript">
      var player          =  null;
      var playList        =  null;
      var currentItem     =     0;
      var previousItem    =    -1;
      var currentPosition =     0;
      var currentStart    =  null;
      var currentEnd      =  null;
      var currentDur      =  null;
      var stopPos         =     0;
    //var advance         = 'end';
      var advance         = 'dur';
      var upDate          = false;

      function playerReady(obj)
      {
        player = document.getElementsByName(obj.id)[0];
        player.addModelListener('TIME', 'timeMonitor');
        player.addControllerListener('ITEM', 'itemMonitor');

        setTimeout("playList = player.getPlaylist()", 100);
      //setTimeout("dumpPlaylist()", 200);
      };

      function timeMonitor(obj)
      {
        currentPosition = obj.position;
        gid('time').innerHTML = 'Time: ' + currentPosition;

        if((currentPosition > currentEnd) && (advance == 'end') && (upDate == true))
        {
//alert('upDate: ' + upDate + '\nCurrent Position: ' + currentPosition + '\nCurrent End: ' + currentEnd + '\nCurrent Start: ' + currentStart + '\nStop Position: ' + currentEnd);
          upDate = false;
          player.sendEvent('NEXT');
        }

        if((currentPosition > stopPos) && (advance == 'dur') && (upDate == true))
        {
//alert('upDate: ' + upDate + '\nCurrent Position: ' + currentPosition + '\nCurrent Dur: ' + currentDur + '\nCurrent Start: ' + currentStart + '\nStop Position: ' + stopPos);
          upDate = false;
          player.sendEvent('NEXT');
        }
      };

      function itemMonitor(obj)
      {
        currentItem = obj.index;
//alert('currentItem: ' + currentItem + '\npreviousItem: ' + previousItem + '\nCurrent Item Start: ' + playList[currentItem]['start']);
        if(currentItem != previousItem)
        {
          previousItem = currentItem;
          // get start, end & dur for the current item
          currentStart = 1 * playList[currentItem]['start'];
          currentEnd   = 1 * playList[currentItem]['end'];
          currentDur   = 1 * playList[currentItem]['dur'];
          stopPos      = currentStart + currentDur;
          gid('item').innerHTML  = 'Item: '  + currentItem;
          gid('start').innerHTML = 'Start: ' + currentStart;
          gid('end').innerHTML   = 'End: '   + currentEnd;
          gid('dur').innerHTML   = 'Dur: '   + currentDur;
          gid('stop').innerHTML  = 'Stop: '  + stopPos;
          upDate = true;
        }
      };

      function dumpPlaylist()
      {
        for(var j in playList)
        {
          var nodes = '<br />';

          for(var k in playList[j])
          {
            nodes += '<li>' + k + ': ' + playList[j][k] + '</li>';
          }
          gid('dump' + j).innerHTML = nodes;
        }
      };

      function gid(name)
      {
        return document.getElementById(name);
      };
    </script>

  </head>

  <body>

    <div id="playercontainer" class="playercontainer">
      <a id="player" class="player" href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Get the Adobe Flash Player to see this video.</a>
    </div>
    <div id="time">
      &nbsp;
    </div>
    <div id="item">
      &nbsp;
    </div>
    <div id="start">
      &nbsp;
    </div>
    <div id="end">
      &nbsp;
    </div>
    <div id="dur">
      &nbsp;
    </div>
    <div id="stop">
      &nbsp;
    </div>
    <div id="dump0">
    </div>
    <div id="dump1">
    </div>
    <div id="dump2">
    </div>
    <div id="dump3">
    </div>
    <div id="dump4">
    </div>
    <div id="dump5">
    </div>

  </body>

</html>
I left most of the development instrumentation code in this post. Delete it when you are done playing with it.

@kLink After I set 'end' for each video they continue playing.. I'm using 4.1.62 What version did you write it for?

Edit: I don't see any of the debug info popping up in the div tags either

First of all, where did you get a v4.1.62 player? I just checked svn and the latest rev. is 4.1.60???

The code was written and tested with v4.1.60.

You can run the demo here: http://willswonders.myip.org:8085/php/End_Dur.html for a limited time.

Did you uncomment end and comment out dur here:

    <script type="text/javascript">
      var player          =  null;
      var playList        =  null;
      var currentItem     =     0;
      var previousItem    =    -1;
      var currentPosition =     0;
      var currentStart    =  null;
      var currentEnd      =  null;
      var currentDur      =  null;
      var stopPos         =     0;
      var advance         = 'end';
    //var advance         = 'dur';
      var upDate          = false;

Edit: Seems there is a v4.1.62 player.swf, still reports itself as v4.1.60. Anyway, that v4.1.62 player works in the demo.

Thanks for the response. Changing which variable was used wasn't the problem. I was doing this locally but soon as I put it up on my server worked fine in conjunction with clearing my cache.

OH!

Yes, the JavaScript API only works online due to Adobe Flash Player security restrictions. :D

Just ran your demo at http://willswonders.myip.org:8085/php/End_Dur.html and saw that it was stuttering and buffering excessively. I also noticed the player version was 4.2.71 - do you think a conflict was introduced that has broken your code? I was about to implement this functionality myself after convincing myself that the documented duration option for files was not intended to be used to stop playback.

So, kLink, does your demo still work ok for you?

@DebFahey,

On a clear sunny day, my upstream is about 256kbps. Since we've been having some thunderstorms, it probably dropped below 100kbps.

Locally, the demo is smooth with v4.2.71, so upload it to your server and all should be well.

GREAT suggestion, will do!

So, thanks to you both, klink and "how"! Test results follow.

With the first flash file (h.264) I tested, it did not play back very well. After I switched to a different flash file (still H.264), I saw better results. Also, in my limited testing, streaming from imediasee.com seemed smoother than streaming from mirror-image.com. If anyone is curious, here are the tests -

Using FMS3 at Mirror-Image.com:
http://www.ccn.tv/myccn/End_Dur.html
http://www.ccn.tv/myccn/JW_42_plain.html

Using Wowza servers at imediasee.com:
http://www.ccn.tv/myccn/IM_End_Dur.html

My flash file was originally created with extension f4v, but I had to rename it to m4v to get it to play at all when using a playlist. If I play it standalone, using the JW player but not in a playlist, then it seems I can play it ONLY if I keep the f4v extension.

@kLink and anyone else interested in kLink's great code sample for stop/duration control as shown in this thread - you may need to replace
setTimeout("playList = player.getPlaylist()", 100);

with
player.addControllerListener("PLAYLIST", "playlistHandler");

and
function playlistHandler()
{
playList = player.getPlaylist();
}

I found that once I changed my code to generate the playlist dynamically, the "if (playList != null)" block of code in itemMonitor was never executing. Adding a listener for PLAYLIST and getting the playlist in that listener function made the code work again. :-)

@DebFahey,

This is a good idea. I am incorporating it into my code anywhere that I need to get a playlist as soon as it is available.

setTimeouts() are never a good idea (except in the try-it-over-and-over-and-over loop), but sometimes I'm lazy (or concentrating on the main thread and just want to get things working — at least that's a good justification :)).

@kLink: gotta weird one here - I seems that the code to advance the item based on start and dur only works properly when I have all my debugging code turned on. I'm guessing that writing the debugging info to the screen (bottom of the page) is slowing processing down just enough for the sendEvent('NEXT') to be detected and acted on. It consistently will advance automatically if debugging is turned on, and but will "play thru" in areas not defiend to the chapters if I have turned debugging off. I have even tried replacing sendEvent('NEXT') with sendEvent('item',currentItem+1) but that did not make a difference.

Have you seen anything like this before? I am testing with streamed flash (FMS3). The javascript code is not too pretty, but it IS largely based on your wonderful example here. You can see what I mean if you go to the two links below. You will be prompted to sign up or log in. You can log in with username=GUEST and password=password

This one, with debugging ON, works fine:
http://www.ccn.tv/myccn/trackPlayer.php?test=yes

To see if fail to advance to the next item, just change test=yes to test=no:
http://www.ccn.tv/myccn/trackPlayer.php?test=no

The first two chapters are VERY short (20 seconds or so) so you won't have to wait long, OR you can use the RESUME/JUMP box to advance closer ot the end of the chapter.

I'm NOT asking you to debug my code, but I AM hoping to pick your brain for ideas. ;-) I'm stumped. THX

Also, I just downloaded the latest JW Player from the Wiki, updated 3 days ago. tested with that version, but no better.

So, I am embarrassed to confess, I found the problem, in MY code of course. No real mystery. :-) I introduced a bug when I added code to conditionally execute javascript code if my testing flag was set. I also conditionally included the html for the logging/debugging DIVs. HOWEVER, I failed to make the debugging code in itemMonitor conditional. Here is what I should have had:
if (testing)
{
gid('item').innerHTML = 'Item: ' + currentItem;
gid('start').innerHTML = 'Start: ' + currentStart;
gid('end').innerHTML = 'End: ' + currentEnd;
gid('dur').innerHTML = 'Dur: ' + currentDur;
gid('stop').innerHTML = 'Stop: ' + stopPos;
}

Due to my recent debugging "enhancement" the item, start, end, dur, and stop DIVs did not exist when I was not testing.

I'm sharing this in case someone else happens to do something stupid like this. :-) It did not throw a javascript error...

@DebFahey,

Welcome to the wonderful world of JavaScript — no error messages, what the H_LL is wrong?

My favorite is IE's "Error on line1, character 1" which means a syntax error (usually punctuation) somewhere in 15,000 characters. I usually keep the JavaScript isolated im multiple code blocks so a simple punctuation error doesn't kill all remaining JavaScript. Then you only have a few lines to look through to find the error. Also, run it in multiple browsers; each one has different error reporting, so if you're lucky, one of them will show something that may be a hint to the location of the error.

Here's my variation on this - I found if there were only one item in the list it would play the item correctly, then go back and play the entire item over, no matter what the repeat settings were. So I changed timeMonitor to:

function timeMonitor(obj)
      {
        currentPosition = obj.position;
      //for debugging
  //gid('time').innerHTML = 'Time: ' + currentPosition;

        if((currentPosition >= currentEnd) && (advance == 'end') && (upDate == true))
        {
//alert('upDate: ' + upDate + '\nCurrent Position: ' + currentPosition + '\nCurrent End: ' + currentEnd + '\nCurrent Start: ' + currentStart + '\nStop Position: ' + currentEnd);
          upDate = false;
          player.sendEvent('NEXT');
        }

        if((currentPosition >= stopPos) && (advance == 'dur') && (upDate == true))
        {
//alert('upDate: ' + upDate + '\nCurrent Position: ' + currentPosition + '\nCurrent Dur: ' + currentDur + '\nCurrent Start: ' + currentStart + '\nStop Position: ' + stopPos);
          upDate = false;
  if(playList[currentItem+1])
    {
             player.sendEvent('NEXT'); 
             }
   else
    {
    player.sendEvent('STOP');
    }
}
      };

and now it seems to work fine, no matter if there are one or multiple tracks.

Hello... I have implemented this and it all works fantastically with a single video. The only problem is that I wish to have more than 1 video.... i.e.

Video 1
- chapter 1 starts at the beginning 00:00 ends 00:30
- chapter 2 starts at the halfway point 1:45 ends 2:45

Video 2
- chapter 1 starts at forty minutes 40:00 ends 45:00

The playlist works fine but when it goes to a new video the start time does not have any impact... so it starts at the beginning

If I double click the new video in the playlist then it starts at the right adjusted place

Is there a way of altering the code to allow proper execution of this?

Thanks

Possibly a player bug. When the player moves automatically to the next track, it should use the start element from the new track, but it doesn't seem to do that for the first new track. I need to do some more testing...

...then maybe a workaround?

great thanks

I can't find anything wrong with my code.

That doesn't mean that there isn't anything wrong with my code; just that I can't find it.

So here is a workaround (add the lines in bold):

    <script type="text/javascript">
      var player          =  null;
      var playList        =  null;
      var currentItem     =     0;
      var previousItem    =    -1;
      var currentFile     =  null;
      var previousFile    =  null;
      var currentPosition =     0;
      var currentStart    =  null;
      var currentEnd      =  null;
      var currentDur      =  null;
      var stopPos         =     0;
    //var advance         = 'end';
      var advance         = 'dur';
      var upDate          = false;

      function itemMonitor(obj)
      {
        currentItem = obj.index;
        if(currentItem != previousItem)
        {
          previousItem = currentItem;
          // get start, end & dur for the current item
          currentStart = 1 * playList[currentItem]['start'];
          currentEnd   = 1 * playList[currentItem]['end'];
          currentDur   = 1 * playList[currentItem]['dur'];
          stopPos      = currentStart + currentDur;
          upDate       = true;

          // extra seek if the file has changed
          currentFile  = playList[currentItem]['file'];
          if(currentFile != previousFile)
          {
            previousFile = currentFile;
            setTimeout("player.sendEvent('SEEK', currentStart)", 300);
          }

          gid('item').innerHTML  = 'Item: '  + currentItem;
          gid('start').innerHTML = 'Start: ' + currentStart;
          gid('end').innerHTML   = 'End: '   + currentEnd;
          gid('dur').innerHTML   = 'Dur: '   + currentDur;
          gid('stop').innerHTML  = 'Stop: '  + stopPos;
        }
      };

you friend, just made my world a whole lot better! thank you very much the workaround worked like a charm....

@Darran,

Good to hear. Good Luck!

                                                                                     :D

maybe I'm asking too much here.... but would it be possible to make this work with multiple (selectable) playlists?

I dunno. Why don't you be the Beta tester?    :D

<a href="#" onclick="player.sendEvent('LOAD', 'http://my.domain.com/path/playlist_two.xml'); return false;">Click here to LOAD Playlist Two</a>

<img onclick="player.sendEvent('LOAD', 'http://my.domain.com/path/playlist_three.xml');" src="image01.jpg" width="80" height="60" alt="Image 01" title="Click here to LOAD Playlist Three" style="cursor:pointer">

<button onclick="player.sendEvent('LOAD', 'http://my.domain.com/path/playlist_four.xml')">LOAD Playlist Four</button>

hello Klink... well this works great.... but when I change playlists then the 'start' 'end' points don't work - even though the debug code displays the correct end/start points.... I really appreciate your help

Yeah, I suppose we should reset things when we change playlists.

Add this function:

      function loadPlaylist(playlist)
      {
        currentItem     =     0;
        previousItem    =    -1;
        currentFile     =  null;
        previousFile    =  null;
        currentPosition =     0;
        currentStart    =  null;
        currentEnd      =  null;
        currentDur      =  null;
        stopPos         =     0;
        upDate          = false;
      
        player.sendEvent('LOAD', playlist);
        player.sendEvent('ITEM', 0);
      };

Change your link(s) to this:
    <a href="#" onclick="loadPlaylist('playlist_end_duration_two.xml'); return false;">Click here to LOAD Playlist Two</a>
    <img        onclick="loadPlaylist('playlist_end_duration_three.xml');" src="image01.jpg" width="80" height="60" alt="Image 01" title="Click here to LOAD Playlist Three" style="cursor:pointer">
    <button     onclick="loadPlaylist('playlist_end_duration_four.xml')">LOAD Playlist Four</button>
The link can be any clickable element, I'm just illustrating three of the available types. The playlist filenames can be any valid filename for your server OS.

Please Beta test.

I'm busy beaveringly beta testing!

It doesn't seem to work in terms of resetting seek times... maybe its easier for you to see whats going on development site here

http://207.192.75.251/aina/

thanks again for your continued help -

Maybe???

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">

  <head>

    <title>End & Duration for Chapters - Mixed Files - Load Playlists - JWMP v4.2.x swfobject v2.1</title>

    <style type="text/css">
      button
      {
        width:                 175px;
      }

      div.instrumentation
      {
        display:              inline;
        float:                  left;
        width:                 100px;
      }
    </style>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject.js"></script>

    <script type="text/javascript">
      var flashvars =
      {
        playlistsize:         '300',
        playlist:             'right',
        shuffle:              'false',
        skin:                 'snel.swf',
        bufferlength:         'null',
        streamer:             'rtmp://my.domain.com/oflaDemo',
        file:                 'http://my.domain.com/playlist_end_duration_one.xml'
      };

      var params =
      {
        allowscriptaccess:    'always',
        allowfullscreen:      'true',
        bgcolor:              '#FFFFFF'
      };

      var attributes =
      {
        id:                   'playerId',
        name:                 'playerId'
      };

      swfobject.embedSWF('player-4.2.90.swf', 'player', '700', '300', '9.0.124', false, flashvars, params, attributes);
    </script>

    <script type="text/javascript">
      var player          =  null;
      var playList        =  null;
      var currentItem     =     0;
      var previousItem    =    -1;
      var currentFile     =  null;
      var previousFile    =  null;
      var currentPosition =     0;
      var currentStart    =  null;
      var currentEnd      =  null;
      var currentDur      =  null;
      var stopPos         =     0;
    //var advance         = 'end';
      var advance         = 'dur';
      var upDate          = false;
      var newPlaylist     = false;
      var newFile         = false;
      var instrumentation =  true;
    //var instrumentation = false;


      function playerReady(obj)
      {
        player = gid(obj.id);
        player.addModelListener('TIME',          'timeMonitor');
        player.addControllerListener('ITEM',     'itemMonitor');
        player.addControllerListener('PLAYLIST', 'playlistHandler');
      };


      function timeMonitor(obj)
      {
        currentPosition = obj.position;
        if(instrumentation)
        {
          gid('time1').innerHTML = 'Time: ' + currentPosition;
        }

        if((currentPosition > 0) && (newFile))
        {
          newFile  = false;
          if(instrumentation)
          {
            gid('extraseek1').innerHTML = 'Extra Seek: ' + currentStart;
          }
          player.sendEvent('SEEK', currentStart);
        }

        if((currentPosition > currentEnd) && (advance == 'end') && (upDate == true))
        {
          if(instrumentation)
          {
            gid('update1').innerHTML = 'Update-1: ' + upDate + '&nbsp;&nbsp;Current Position: ' + currentPosition + '&nbsp;&nbsp;Current End: ' + currentEnd + '&nbsp;&nbsp;Current Start: ' + currentStart + '&nbsp;&nbsp;Stop Position: ' + currentEnd;
          }
          upDate = false;
          player.sendEvent('NEXT');
        }

        if((currentPosition > stopPos) && (advance == 'dur') && (upDate == true))
        {
          if(instrumentation)
          {
            gid('update2').innerHTML = 'Update-2: ' + upDate + '&nbsp;&nbsp;Current Position: ' + currentPosition + '&nbsp;&nbsp;Current Dur: ' + currentDur + '&nbsp;&nbsp;Current Start: ' + currentStart + '&nbsp;&nbsp;Stop Position: ' + stopPos;
          }
          upDate = false;
          player.sendEvent('NEXT');
        }
      };


      function itemMonitor(obj)
      {
        currentItem = obj.index;
        if(instrumentation)
        {
          gid('currentitem').innerHTML = 'Current Item: ' + currentItem + '&nbsp;&nbsp;Previous Item: ' + previousItem + '&nbsp;&nbsp;Current Item Start: ' + playList[currentItem]['start'];
        }
    
        if(currentItem != previousItem)
        {
          previousItem = currentItem;
          // get file, start, end & dur for the current item
          currentFile  =     playList[currentItem]['file'];
          currentStart = 1 * playList[currentItem]['start'];
          currentEnd   = 1 * playList[currentItem]['end'];
          currentDur   = 1 * playList[currentItem]['dur'];
          stopPos      = currentStart + currentDur;
          upDate       = true;

          // extra seek if the file has changed
          if(currentFile != previousFile)
          {
            if(instrumentation)
            {
              gid('extraseek2').innerHTML = 'Extra Seek: ' + newFile + '&nbsp;&nbsp;Previous File: ' + previousFile + '&nbsp;&nbsp;Current File: ' + currentFile + '&nbsp;&nbsp;newPlaylist: ' + newPlaylist;
            }
            newFile = true;
          }

          previousFile = currentFile;

          if(instrumentation)
          {
            gid('extraseek3').innerHTML = 'Extra Seek: ' + newFile + '&nbsp;&nbsp;Previous File: ' + previousFile + '&nbsp;&nbsp;Current File: ' + currentFile + '&nbsp;&nbsp;newPlaylist: ' + newPlaylist;
            gid('start1').innerHTML     = 'Start: ' + currentStart;
            gid('stop1').innerHTML      = 'Stop: '  + stopPos;
            gid('end1').innerHTML       = 'End: '   + currentEnd;
            gid('dur1').innerHTML       = 'Dur: '   + currentDur;
            gid('item1').innerHTML      = 'Item: '  + currentItem;
          }
        }
      };


      function playlistHandler()
      {
        playList = player.getPlaylist();
        player.sendEvent('ITEM', 0);
        if(instrumentation)
        {
          dumpPlaylist();
        }
      };


      function dumpPlaylist()
      {
        for(var j in playList)
        {
          var nodes = '<br />';

          for(var k in playList[j])
          {
            nodes += '<li>' + k + ': ' + playList[j][k] + '</li>';
          }
          gid('dump' + j).innerHTML = nodes;
        }
      };


      function loadPlaylist(playlist)
      {
        currentItem     =     0;
        previousItem    =    -1;
        currentFile     =  null;
        previousFile    =  null;
        currentPosition =     0;
        currentStart    =  null;
        currentEnd      =  null;
        currentDur      =  null;
        stopPos         =     0;
        upDate          = false;
        newPlaylist     =  true;
        newFile         = false;

      
        if(instrumentation)
        {
          gid('item2').innerHTML  = 'Item: '  + currentItem;
          gid('start2').innerHTML = 'Start: ' + currentStart;
          gid('end2').innerHTML   = 'End: '   + currentEnd;
          gid('dur2').innerHTML   = 'Dur: '   + currentDur;
          gid('stop2').innerHTML  = 'Stop: '  + stopPos;
        }

        player.sendEvent('LOAD', playlist);
      };


      function gid(name)
      {
        return document.getElementById(name);
      };
    </script>

  </head>

  <body>

    <div id="playercontainer" class="playercontainer">
      <a id="player" class="player" href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Get the Adobe Flash Player to see this video.</a>
    </div>
    <button onclick="loadPlaylist('playlist_end_duration_one.xml')">LOAD Playlist One</button>
    <button onclick="loadPlaylist('playlist_end_duration_two.xml')">LOAD Playlist Two</button>
    <button onclick="loadPlaylist('playlist_end_duration_three.xml')">LOAD Playlist Three</button>
    <button onclick="loadPlaylist('playlist_end_duration_four.xml')">LOAD Playlist Four</button>
    <div class="instrumentation">
      <div id="time1">
        &nbsp;
      </div>
      <div id="start1">
        &nbsp;
      </div>
      <div id="stop1">
        &nbsp;
      </div>
      <div id="end1">
        &nbsp;
      </div>
      <div id="dur1">
        &nbsp;
      </div>
      <div id="item1">
        &nbsp;
      </div>
    </div>
    <div class="instrumentation">
      <div id="time2">
        &nbsp;
      </div>
      <div id="start2">
        &nbsp;
      </div>
      <div id="stop2">
        &nbsp;
      </div>
      <div id="end2">
        &nbsp;
      </div>
      <div id="dur2">
        &nbsp;
      </div>
      <div id="item2">
        &nbsp;
      </div>
    </div>
    <div id="extraseek1">
        &nbsp;
    </div>
    <div id="extraseek2">
        &nbsp;
    </div>
    <div id="extraseek3">
        &nbsp;
    </div>
    <div id="update1">
        &nbsp;
    </div>
    <div id="update2">
        &nbsp;
    </div>
    <div id="currentitem">
        &nbsp;
    </div>
    <div>
      <div id="dump0">
      </div>
      <div id="dump1">
      </div>
      <div id="dump2">
      </div>
      <div id="dump3">
      </div>
      <div id="dump4">
      </div>
      <div id="dump5">
      </div>
      <div id="dump6">
      </div>
      <div id="dump7">
      </div>
    </div>

  </body>

</html>
Change to your streamer, playlists & player. Turn off the instrumentation with instrumentation = false.

                                                                                     :D

wowzers.... worked liked a charm! Thank you so very much

You're welcome.

If this is going on a production site:

1) Save a backup copy with all of the instrumentation, etc.

2) Cut & paste the two blocks of JavaScript into new files, named something like player.js and API.js

3) Strip all comments and instrumentation from the JavaScript and the HTML

4) Run the JavaScript through a minifier, like the YUI Compressor: http://developer.yahoo.com/yui/compressor/

5) Load the JavaScript files with a single line of code, just like swfobject is loaded

Good Luck!

                                                                                     :D

thanks for you guidance... I'm definately a code hacker (no finesse whatsover) so I'll take what you have said on board when we go live with it... thanks again

Your playlist had non-breaking spaces (character 160) instead of normal spaces (character 32). Use a plain-text editor and save it as plain-text. (Should be Unicode but you don't have foreign characters, so that's not necessary.)

Your player code is OK. Use the v4.2.90 player.

xspf5.xml

<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
  <title>Example XSPF playlist for the JW Player</title>
  <info>http://developer.longtailvideo.com/trac</info>
  <trackList>
    <track>
      <creator>craig creates</creator>
      <title>title goes here</title>
      <location>Extremists.flv</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>100</meta>
      <meta rel='end'>105</meta>
      <meta rel='dur'>5</meta>
      <image>http://sftalkback.com/imgs/megalogo.jpg</image>
      <annotation>01:40 - 01:45</annotation>
      <info>http://my.domain.com/</info>
    </track>
    <track>
      <creator>craig creates</creator>
      <title>title goes here</title>
      <location>Extremists.flv</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>150</meta>
      <meta rel='end'>155</meta>
      <meta rel='dur'>5</meta>
      <image>http://sftalkback.com/imgs/megalogo.jpg</image>
      <annotation>02:30 - 02:35</annotation>
      <info>http://my.domain.com/</info>
    </track>
    <track>
      <creator>craig creates</creator>
      <title>title goes here</title>
      <location>Extremists.flv</location>
      <meta rel='type'>video</meta>
      <meta rel='start'>200</meta>
      <meta rel='end'>205</meta>
      <meta rel='dur'>5</meta>
      <image>http://sftalkback.com/imgs/megalogo.jpg</image>
      <annotation>03:20 - 03:25</annotation>
      <info>http://my.domain.com/</info>
    </track>
  </trackList>
</playlist>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">

  <head>

    <title>End & Duration for Chapters - Mixed Files - Load Playlists - JWMP v4.2.x swfobject v2.1</title>

    <style type="text/css">
      button
      {
        width:                 175px;
      }

      div.instrumentation
      {
        display:              inline;
        float:                  left;
        width:                 100px;
      }
    </style>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject.js"></script>

    <script type="text/javascript">
      var flashvars =
      {
        playlist:             'right',
        playlistsize:         '300',
        shuffle:              'false',
        streamer:             'rtmp://69.50.140.27/simplevideostreaming',
        file:                 'xspf5.xml'
        skin:                 'magma.swf',
        bufferlength:         'null'
      };

      var params =
      {
        allowscriptaccess:    'always',
        allowfullscreen:      'true',
        bgcolor:              '#FFFFFF'
      };

      var attributes =
      {
        id:                   'playerId',
        name:                 'playerId'
      };

      swfobject.embedSWF('player-4.2.90.swf', 'player', '700', '300', '9.0.124', false, flashvars, params, attributes);
    </script>

    <script type="text/javascript">
      var player          =  null;
      var playList        =  null;
      var currentItem     =     0;
      var previousItem    =    -1;
      var currentFile     =  null;
      var previousFile    =  null;
      var currentPosition =     0;
      var currentStart    =  null;
      var currentEnd      =  null;
      var currentDur      =  null;
      var stopPos         =     0;
      var advance         = 'end';
    //var advance         = 'dur';
      var upDate          = false;
      var newPlaylist     = false;
      var newFile         = false;
      var instrumentation =  true;
    //var instrumentation = false;

      function playerReady(obj)
      {
        player = gid(obj.id);
        player.addModelListener('TIME',          'timeMonitor');
        player.addControllerListener('ITEM',     'itemMonitor');
        player.addControllerListener('PLAYLIST', 'playlistHandler');
      };


      function timeMonitor(obj)
      {
        currentPosition = obj.position;
        if(instrumentation)
        {
          gid('time1').innerHTML = 'Time: ' + currentPosition;
        }

        if((currentPosition > 0) && (newFile))
        {
          newFile  = false;
          if(instrumentation)
          {
            gid('extraseek1').innerHTML = 'Extra Seek: ' + currentStart;
          }
          player.sendEvent('SEEK', currentStart);
        }

        if((currentPosition > currentEnd) && (advance == 'end') && (upDate == true))
        {
          if(instrumentation)
          {
            gid('update1').innerHTML = 'Update-1: ' + upDate + '  Current Position: ' + currentPosition + '  Current End: ' + currentEnd + '  Current Start: ' + currentStart + '  Stop Position: ' + currentEnd;
          }
          upDate = false;
          player.sendEvent('NEXT');
        }

        if((currentPosition > stopPos) && (advance == 'dur') && (upDate == true))
        {
          if(instrumentation)
          {
            gid('update2').innerHTML = 'Update-2: ' + upDate + '  Current Position: ' + currentPosition + '  Current Dur: ' + currentDur + '  Current Start: ' + currentStart + '  Stop Position: ' + stopPos;
          }
          upDate = false;
          player.sendEvent('NEXT');
        }
      };


      function itemMonitor(obj)
      {
        currentItem = obj.index;
        if(instrumentation)
        {
          gid('currentitem').innerHTML = 'Current Item: ' + currentItem + '  Previous Item: ' + previousItem + '  Current Item Start: ' + playList[currentItem]['start'];
        }
    
        if(currentItem != previousItem)
        {
          previousItem = currentItem;
          // get file, start, end & dur for the current item
          currentFile  =     playList[currentItem]['file'];
          currentStart = 1 * playList[currentItem]['start'];
          currentEnd   = 1 * playList[currentItem]['end'];
          currentDur   = 1 * playList[currentItem]['dur'];
          stopPos      = currentStart + currentDur;
          upDate       = true;

          // extra seek if the file has changed
          if(currentFile != previousFile)
          {
            if(instrumentation)
            {
              gid('extraseek2').innerHTML = 'Extra Seek: ' + newFile + '  Previous File: ' + previousFile + '  Current File: ' + currentFile + '  newPlaylist: ' + newPlaylist;
            }
            newFile = true;
          }

          previousFile = currentFile;

          if(instrumentation)
          {
            gid('extraseek3').innerHTML = 'Extra Seek: ' + newFile + '  Previous File: ' + previousFile + '  Current File: ' + currentFile + '  newPlaylist: ' + newPlaylist;
            gid('start1').innerHTML     = 'Start: ' + currentStart;
            gid('stop1').innerHTML      = 'Stop: '  + stopPos;
            gid('end1').innerHTML       = 'End: '   + currentEnd;
            gid('dur1').innerHTML       = 'Dur: '   + currentDur;
            gid('item1').innerHTML      = 'Item: '  + currentItem;
          }
        }
      };


      function playlistHandler()
      {
        playList = player.getPlaylist();
        player.sendEvent('ITEM', 0);
        if(instrumentation)
        {
          dumpPlaylist();
        }
      };


      function dumpPlaylist()
      {
        for(var j in playList)
        {
          var nodes = '<br />';

          for(var k in playList[j])
          {
            nodes += '<li>' + k + ': ' + playList[j][k] + '</li>';
          }
          gid('dump' + j).innerHTML = nodes;
        }
      };


      function loadPlaylist(playlist)
      {
        currentItem     =     0;
        previousItem    =    -1;
        currentFile     =  null;
        previousFile    =  null;
        currentPosition =     0;
        currentStart    =  null;
        currentEnd      =  null;
        currentDur      =  null;
        stopPos         =     0;
        upDate          = false;
        newPlaylist     =  true;
        newFile         = false;

      
        if(instrumentation)
        {
          gid('item2').innerHTML  = 'Item: '  + currentItem;
          gid('start2').innerHTML = 'Start: ' + currentStart;
          gid('end2').innerHTML   = 'End: '   + currentEnd;
          gid('dur2').innerHTML   = 'Dur: '   + currentDur;
          gid('stop2').innerHTML  = 'Stop: '  + stopPos;
        }

        player.sendEvent('LOAD', playlist);
      };


      function gid(name)
      {
        return document.getElementById(name);
      };
    </script>

  </head>

  <body>

    <div id="playercontainer" class="playercontainer">
      <a id="player" class="player" href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Get the Adobe Flash Player to see this video.</a>
    </div>
    <a href="#" onclick="loadPlaylist('xspf5.xml'); return false;">Test Playlist</a>
    <button onclick="loadPlaylist('xspf5.xml')">LOAD Playlist One</button>
    <button onclick="loadPlaylist('playlist_end_duration_two.xml')">LOAD Playlist Two</button>
    <button onclick="loadPlaylist('playlist_end_duration_three.xml')">LOAD Playlist Three</button>
    <button onclick="loadPlaylist('playlist_end_duration_four.xml')">LOAD Playlist Four</button>
    <div class="instrumentation">
      <div id="time1">
         
      </div>
      <div id="start1">
         
      </div>
      <div id="stop1">
         
      </div>
      <div id="end1">
         
      </div>
      <div id="dur1">
         
      </div>
      <div id="item1">
         
      </div>
    </div>
    <div class="instrumentation">
      <div id="time2">
         
      </div>
      <div id="start2">
         
      </div>
      <div id="stop2">
         
      </div>
      <div id="end2">
         
      </div>
      <div id="dur2">
         
      </div>
      <div id="item2">
         
      </div>
    </div>
    <div id="extraseek1">
         
    </div>
    <div id="extraseek2">
         
    </div>
    <div id="extraseek3">
         
    </div>
    <div id="update1">
         
    </div>
    <div id="update2">
         
    </div>
    <div id="currentitem">
         
    </div>
    <div>
      <div id="dump0">
      </div>
      <div id="dump1">
      </div>
      <div id="dump2">
      </div>
      <div id="dump3">
      </div>
      <div id="dump4">
      </div>
      <div id="dump5">
      </div>
      <div id="dump6">
      </div>
      <div id="dump7">
      </div>
    </div>

  </body>

</html>

 
@craig,

Post your full page code or a link to your test page and I'll have a look.

@kLink:

See my reply above. But I also have tested the new page on other browsers now, and I'm not getting the stuttering playback, but I AM still seeing the entire length of the video in the scrubber bar. I can scrub back to the very beginning of the video, not matter what the START point for a clip is set at, and if I try to scrub too far in the scrubber bar, it resets back to the START point of the first clip. What I need is a way to show ONLY the part of the clip from the START to END points or START+DUR points, and no way to scrub or even see the length of the clip before or after those. It can be in one individual stream per page, OR in a playlist...in fact, I would love to know how to do this for one individual clip in cases where a playlist won't apply. I am happy to hire you to work on this, if it's too complicated to handle here. Thank you

I had noticed that your video server was incredibly slow at scrubbing but forgot to mention it to you in my post.

Are your videos perhaps too large in width and height or bitrate and need to be scaled down for the player?

As far as showing the full length of the clip in the control bar; that comes from the metadata that is in the file or is created by your streaming server. There is nothing that can be done about that. You could post it as a feature suggestion; Jeroen might do something about it for chapters and applications like yours.

Eventually, the player may support the end parameter which can be sent to your streaming server and then only the clip may show in the scrubber bar.

You can put the start, end, and dur parameters in the player code for a single media file.

Changing the scrubber bar display would require changes in the ActionScript3 player source code. You will have to find a Flash developer for that.

@kLink:

Not sure why the stuttering is occurring. I play these same streams in other FLV players and they are fine, and are at about 500kbps. I didn't see the stuttering in the JW player when I was on a faster connection today.

In the past, with other players, I have seen this stuttering occur when trying to scrub a PORTION of a larger video (such as we are doing here with the start/end/dur variables). I wonder if the wowza server isn't just getting confused with that, for some reason.

I had a Flash developer try to solve the scrubber bar issue I've described in the past, to no avail. It still would show or try to seek to parts of the video beyond and before that which we WANT to show. I'll post it as a suggestion for Jeroen and maybe it can be added later.

I believe it would be an incredibly powerful feature to be able to TRULY chapterize larger videos, and display only the portions that are being shown by the start/end/dur functions. The problem with the way it is now is that the viewer naturally wants to scrub ahead or earlier if they see more of a scrubber bar...and that's what screws things up.

If you know a flash developer who could work on the scrubber bar change for the JW player, please let me know...and thanks very much for your input and help.

Craig

I can move the behaviour so the 'start' position will identify the beginning of the controlbar. Do we miss anything that way? Are there cases when using the 'start' flashvar in which you don't want it to behave like this?

@JeroenW,

I've been pondering this ever since Craig raised the question.

I guess it does make sense to have the control bar show only the chapter that is currently playing.

So if you sere playing from 3:23-7:45 of a longer video/song/audio, 0-100 on the control bar would correspond to 3:23-7:45. That segment is the current selection that is playing, so it sort of makes sense to only display the segment of the larger file.

Just my two cents, JW, I know that I have asked you in the past for "end" parameters to denote the end of a "chapter" to stop playback (or proceed to next playlist item according to the player's configuration).

I do like the idea of absolute and relative options for triggering the desired "end" of a file. This feature would be a powerful addition to JW FLV Player, IMHO.

While a JavaScript solution can be worked out to accomplish this, implementing this as a feature sounds more promising/fitting.

pixelchutes, that already works in 4.3 (using duration). Regarding start, I for one would love to see it, as I think it's much more user friendly. Our customers for one are rather confused by chapters starting in the middle :-D

@yure....I agree, chapters starting in the middle is confusing, but also chapters that stop at some point, but still show a lot more left in the control bar. This is why making the control bar show only the START to END or START+DUR would be ideal, I think.

noticed this player the other day - note how they solved a similar problem by having "chapter breaks" in the progressbar - http://www.vega-tdc-player.dk/index.jsp

@anderson

That other player has an interesting twist on chapters, but it does not solve the issue above...which is to ONLY display the chapter we want...and NOT DISPLAY any video before or after the START/END points. The chapter breaks are neat, but the viewer can still access any part of the video...and that's what we're trying to prevent.

@craig - point taken - didnt mean to indicate that it was THE ultimate solution, but just as you state your self - "an interesting twist" - a reasonably nice compromise...

makes me wonder if it would be possible and what it would take, to make a set of skins, each with one of the various possibilities or maybe a single skin with flashvar settings for the selection of progressbar type...

@andersen: I don't know...hopefully kLink or Jeroen can reply to this thread again, to let us know if this feature can be added...and if so, an approximate time frame. Thank you.

@craig,

I'm just a poor, helpless user.

Only Jeroen can tell us if he will add this feature and when.

The encouraging news is: Jeroen seems to be open to changing the "chapterizing" behavior and he has always been VERY responsive to his user's needs.

@kLink...yes, Jeroen has always been very supportive, so we look forward to his reply on this. Thanks.

i agree with craig on this (as stated). we would much rather see the chapter as a separate item (from start to end, looking like a separate video). This is the way it's usually done. The issue with showing "all chapters" with marks is that you cannot hide the fact it's a chapter, while if you can have start+dur or start+end to show as a separate item, you can have parts of video as separate items or "chapters" depending on how you want the customer to perceive it. So i think what craig has been suggesting is already a compromise and would work best.

but i already said that before :)

Hi there,

Not completely on-topic, but related to chapters, in case Jeroen stops by this thread :

http://www.ted.com/index.php/talks/jill_bolte_taylor_s_powerful_stroke_of_insight.html

This type of interface for Chapters would I think make a lot of people happy :-) Do you think this can be done just through skins?

Cheers,

Jun.

@KLink

Was trying out your awesome sounding code but cannot get it to work. The video player won't show. Can you please offer any suggestions? I'm most assuredly NOT a programmer, so it is probably my stupid error.

Ok, here is the code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">

<head>

<title>Test Video Player</title>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject.js"></script>

<script type="text/javascript">
var flashvars =
{
playlist: 'right',
playlistsize: '300',
shuffle: 'false',
//streamer: 'rtmp://69.50.140.27/simplevideostreaming',
file: 'http://www.intranet/mediaplayer/HRMovies/playlist4.xml'
skin: 'http://www.intranet/mediaplayer/HRMovies/snel.swf',
bufferlength: 'null'
};

var params =
{
allowscriptaccess: 'always',
allowfullscreen: 'true',
bgcolor: '#FFFFFF'
};

var attributes =
{
id: 'playerId',
name: 'playerId'
};

swfobject.embedSWF('http://www.intranet/mediaplayer/HRMovies/player.swf', 'player', '700', '300', '9.0.124', false, flashvars, params, attributes);
</script>

<script type="text/javascript">
var player = null;
var playList = null;
var currentItem = 0;
var previousItem = -1;
var currentFile = null;
var previousFile = null;
var currentPosition = 0;
var currentStart = null;
var currentEnd = null;
var currentDur = null;
var stopPos = 0;
var advance = 'end';
//var advance = 'dur';
var upDate = false;
var newPlaylist = false;
var newFile = false;
// var instrumentation = true;
var instrumentation = false;

function playerReady(obj)
{
player = gid(obj.id);
player.addModelListener('TIME', 'timeMonitor');
player.addControllerListener('ITEM', 'itemMonitor');
player.addControllerListener('PLAYLIST', 'playlistHandler');
};

function timeMonitor(obj)
{
currentPosition = obj.position;
if(instrumentation)
{
gid('time1').innerHTML = 'Time: ' + currentPosition;
}

if((currentPosition > 0) && (newFile))
{
newFile = false;
if(instrumentation)
{
gid('extraseek1').innerHTML = 'Extra Seek: ' + currentStart;
}
player.sendEvent('SEEK', currentStart);
}

if((currentPosition > currentEnd) && (advance == 'end') && (upDate == true))
{
if(instrumentation)
{
gid('update1').innerHTML = 'Update-1: ' + upDate + ' Current Position: ' + currentPosition + ' Current End: ' + currentEnd + ' Current Start: ' + currentStart + ' Stop Position: ' + currentEnd;
}
upDate = false;
player.sendEvent('NEXT');
}

if((currentPosition > stopPos) && (advance == 'dur') && (upDate == true))
{
if(instrumentation)
{
gid('update2').innerHTML = 'Update-2: ' + upDate + ' Current Position: ' + currentPosition + ' Current Dur: ' + currentDur + ' Current Start: ' + currentStart + ' Stop Position: ' + stopPos;
}
upDate = false;
player.sendEvent('NEXT');
}
};

function itemMonitor(obj)
{
currentItem = obj.index;
if(instrumentation)
{
gid('currentItem').innerHTML = 'Current Item: ' + currentItem + ' Previous Item: ' + previousItem + ' Current Item Start: ' + playList[currentItem]['start'];
}

if(currentItem != previousItem)
{
previousItem = currentItem;
// get file, start, end & dur for the current item
currentFile = playList[currentItem]['file'];
currentStart = 1 * playList[currentItem]['start'];
currentEnd = 1 * playList[currentItem]['end'];
currentDur = 1 * playList[currentItem]['dur'];
stopPos = currentStart + currentDur;
upDate = true;

// extra seek if the file has changed
currentFile = playList[currentItem] ['file'];
if(currentFile != previousFile)
{
previousFile = currentFile;
setTimeout("player.sendEvent('SEEK', currentStart)", 300);
}

gid('start').innerHTML = 'Start: ' + currentStart;
gid('stop').innerHTML = 'Stop: ' + stopPos;
gid('end').innerHTML = 'End: ' + currentEnd;
gid('dur').innerHTML = 'Dur: ' + currentDur;
gid('item').innerHTML = 'Item: ' + currentItem;
}
};

function playlistHandler()
{
playList = player.getPlaylist();
player.sendEvent('ITEM', 0);
if(instrumentation)
{
dumpPlaylist();
}
};

function dumpPlaylist()
{
for(var j in playList)
{
var nodes = '<br />';

for(var k in playList[j])
{
nodes += '<li>' + k + ': ' + playList[j][k] + '</li>';
}
gid('dump' + j).innerHTML = nodes;
}
};

function loadPlaylist(playlist)
{
currentItem = 0;
previousItem = -1;
currentFile = null;
previousFile = null;
currentPosition = 0;
currentStart = null;
currentEnd = null;
currentDur = null;
stopPos = 0;
upDate = false;
newPlaylist = true;
newFile = false;

player.sendEvent('LOAD', playlist);
player.sendEvent('ITEM', 0);
};

if(instrumentation)
{
gid('item2').innerHTML = 'Item: ' + currentItem;
gid('start2').innerHTML = 'Start: ' + currentStart;
gid('end2').innerHTML = 'End: ' + currentEnd;
gid('dur2').innerHTML = 'Dur: ' + currentDur;
gid('stop2').innerHTML = 'Stop: ' + stopPos;
}

player.sendEvent('LOAD', playlist);
};

function gid(name)
{
return document.getElementById(name);
};
</script>

</head>

<body>

<div id="playercontainer" class="playercontainer">
<a id="player" class="player" href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Get the Adobe Flash Player to see this video.</a>
</div>

<div class="instrumentation">
<div id="time1">

</div>
<div id="start1">

</div>
<div id="stop1">

</div>
<div id="end1">

</div>
<div id="dur1">

</div>
<div id="item1">

</div>
</div>
<div class="instrumentation">
<div id="time2">

</div>
<div id="start2">

</div>
<div id="stop2">

</div>
<div id="end2">

</div>
<div id="dur2">

</div>
<div id="item2">

</div>
</div>
<div id="extraseek1">

</div>
<div id="extraseek2">

</div>
<div id="extraseek3">

</div>
<div id="update1">

</div>
<div id="update2">

</div>
<div id="currentitem">

</div>
<div>
<div id="dump0">
</div>
<div id="dump1">
</div>
<div id="dump2">
</div>
<div id="dump3">
</div>
<div id="dump4">
</div>
<div id="dump5">
</div>
<div id="dump6">
</div>
<div id="dump7">
</div>
</div>
</body>

</html>

The end result is hopefully, a player with a playlist that controls the above mentioned duration problem and will control the crazy playlist "shuffle?", ie: when you click on one of the items in the playlist it selects from the one below it? Suggestions welcome.

Code currently being used for this is:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script type="text/javascript" src="swfobject.js"></script>

<table width="647" cellspacing="0" border="0" align="center">

<tr style=" background-image:url(imagesIcons/greyplayerframe.jpg); background-repeat:no-repeat; background-position:top; background-position:center">

<td height="550" style="padding-bottom:50px; padding-left:3px; padding-top:80px"><!--- begining of content table-->

<div id="mediaspace" align="center">
<a href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Get the Adobe Flash Player to see this video.</a>
</div>
<script type="text/javascript">
var so = new SWFObject('http://intranet/mediaplayer/player.swf', 'mpl', '630', '300', '9.0.124');
so.addParam('allowscriptaccess', 'always');
so.addParam('allowfullscreen', 'true');
so.addParam('wmode', 'transparent');
so.addVariable('channel', '7735');

so.addVariable('file', encodeURIComponent('http://intranet/mediaplayer/playlist2.xml?'));
so.addVariable('backcolor', '000000');
so.addVariable('frontcolor', 'cccccc');
so.addVariable('lightcolor', 'cccccc');
so.addVariable('playlistsize', '275');
so.addVariable('skin', 'http://www.longtailvideo.com/jw/upload/stylish.swf');
so.addVariable('playlist', 'right');

so.addVariable('autostart', 'false');
so.write('mediaspace');
</script>

</td>
</tr>

</table>

Sweet and simple. The Java Script is new to me so that could explain why I am so lost. Please help!

I think you mis-copied the code because there were both duplicated and missing lines.

The v4.4.x player's behavior has changed, so I updated the player code and the playlists.

See your code here: http://willswonders.myip.org:8082/Whiteheart.html

Just copy the page source in your browser.

I used full paths for the playlist and other files, so you can download them to use as examples.

@lefTy

Thanks. When I access the code outside of our server, because server won't allow access, it looks great. When I transfer code inside server and modify to read my player, the player will not show up. I see the buttons etc. but not the player. It was a good try. Now when I use the original code with the player it works fine, comes in just fine. But add the new J.S. and it won't pull it in. Any ideas why this might be?

On a different note, why would the playlist on the player not play the movie selected but instead jump you down to the movie below it? Is this a bug?

You have been very patient and it is greatly appreciated.

W.

Jumping to the next track is usually an indication that the track that you selected is not available, so the player tries to play the next track.

I don't exactly understand what you mean by inside/outside server.

Do you have a test page that I can see?

"This is why making the control bar show only the START to END or START+DUR would be ideal.."

Did this ever get implemented? Ive been scrolling the forums for a solution with no luck.

Looking for this my self Gina.

It respects the duration but you can seek backwards after the start point.

Post new comment

  • Allowed HTML tags: <code> <blockquote> <em> <strong> <strike> <ul> <li> <ol>
  • Lines and paragraphs break automatically.
  • You may post code using <code>...</code> (generic).

More information about formatting options