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

Forums

/

automatically reloading playlist

40 replies [Last post]

Hi. I am a relative noob when it comes to javascript and flash. I have been looking at some examples and was able to get Media Player 4.3 to work with a XSPF playlist. I need the ability for Media Player to reload the playlist if it finds an updated playlist. I have been using a meta refresh to reload the page and playlist but I don't like this solution. I did a search and did not find many posts related to this. The few posts that I did find seemed to be talking about Media Player 3.X.

I am attaching a copy of my html. I would greatly appreciate any help I can get. The more detailed the response, the better...since I really don't know what I am doing. Thanks in advance!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="refresh" content="300">

<title>Test Page</title>

<style type="text/css">
body { background-color: #000000; color:#000000; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px;}
</style>

</head>
<body>

<div id='player1' style="position:absolute; top:10px; left:10px">This is player1</div>

<script type='text/javascript' src='swfobject.js'></script>
<script type='text/javascript'>
var s1 = new SWFObject('player.swf','player1','640','400','9');
s1.addParam('allowfullscreen','true');
s1.addParam('allowscriptaccess','always');
s1.addParam('flashvars','file=list.xspf&autostart=true&repeat=list&repeat=always&icons=false&bufferlength=1&stretching=exactfit');
s1.write('player1');
</script>

</body>
</html>

This code uses a timer to reload the playlist every nn seconds  —OR—  it checks the file modified time of the playlist and reloads the playlist on completion of the currently playing item, if the playlist has been updated.

It's v3.x player code. If I can find the time later, I'll update it for the v4.x JW FLV Media Player.

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

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head>

    <title>Reload Playlist Every 60s -or- If Playlist Has Been Updated - JWMP v3.x - swfobject v2.2</title>

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

    <!-- inline script #1 - AJAX -->
    <script type="text/javascript">
      var xmlhttp         = false;
      var lastModified    =  null;
      var playlistUpdated = false;

      try
      {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(E)
        {
          xmlhttp = false;
        }
      }

      if(!xmlhttp && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp = false;
        }
      }

      if(!xmlhttp && window.createRequest)
      {
        try
        {
          xmlhttp = window.createRequest();
        }
        catch(e)
        {
          xmlhttp = false;
        }
      }

      function checkFileUpdate(file)
      {
        xmlhttp.open('HEAD', file, true);
        xmlhttp.onreadystatechange = function()
        {
          if(xmlhttp.readyState == 4)
          {
            if((lastModified != null) && (lastModified != xmlhttp.getResponseHeader('Last-Modified')))
            {
              alert('File was last modified on: ' + xmlhttp.getResponseHeader('Last-Modified'));
              lastModified   = xmlhttp.getResponseHeader('Last-Modified');
              playlistUpdated = true;
            }
            lastModified = xmlhttp.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp.send(null)

        setTimeout("checkFileUpdate('playlist.xml')", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate('playlist.xml')", 60000);
    </script>

    <!-- inline script #2 - Player API -->
    <script type="text/javascript">
      var currentItem = 0;
      var startItem   = 0;

      function getUpdate(typ, pr1, pr2, pid)
      {
        if(typ == 'item')
        {
          currentItem = pr1;
        }
        // reload playlist on completion of current item only if playlist has been updated
        if((typ == 'state') && (pr1 == 3) && playlistUpdated)
        {
          gid('playerId').loadFile({file:'playlist.xml'});
//alert('playlistUpdated: ' + playlistUpdated);
          playlistUpdated = false;
        }
      };

      // playlist reload loop timer
      function reloadPlaylist()
      {
        gid('playerId').loadFile({file:'playlist.xml'});
        startItem = currentItem;
        setTimeout("gid('playerId').sendEvent('playitem', startItem)", 750);
        setTimeout("reloadPlaylist()", 60000);
      };

      // start loop timer
    //setTimeout("reloadPlaylist()", 60000);

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

    <!-- inline script #3 - Player -->
    <script type="text/javascript">
      var flashvars =
      {
        file:                 'playlist.xml',
        width:                '400',
        height:               '443',
        displayheight:        '300',
        enablejs:             'true',
        javascriptid:         'playerId',
        overstretch:          'fit',
        repeat:               'true',
        shuffle:              'false',
        autostart:            'true'
      };

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

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

      swfobject.embedSWF('mediaplayer.swf', 'player', '400', '443', '9.0.124', false, flashvars, params, attributes);
    </script>

  </head>

  <body>

    <div id="playercontainer" class="playercontainer">
      <a id="player" class="player" href='http://www.macromedia.com/go/getflashplayer'>get the flash player to see this player.</a>
    </div>

  </body>

</html>

v4 player code:

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

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head>

    <title>Reload Playlist Every 60s -or- If Playlist Has Been Updated - JWMP v4.4.x - swfobject v2.2</title>

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

    <!-- inline script #1 - AJAX -->
    <script type="text/javascript">
      var xmlhttp         = false;
      var lastModified    =  null;
      var playlistUpdated = false;

      try
      {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(E)
        {
          xmlhttp = false;
        }
      }

      if(!xmlhttp && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp = false;
        }
      }

      if(!xmlhttp && window.createRequest)
      {
        try
        {
          xmlhttp = window.createRequest();
        }
        catch(e)
        {
          xmlhttp = false;
        }
      }

      function checkFileUpdate(file)
      {
        xmlhttp.open('HEAD', file, true);
        xmlhttp.onreadystatechange = function()
        {
          if(xmlhttp.readyState == 4)
          {
            if((lastModified != null) && (lastModified != xmlhttp.getResponseHeader('Last-Modified')))
            {
//alert('File was last modified on: ' + xmlhttp.getResponseHeader('Last-Modified'));
              lastModified    = xmlhttp.getResponseHeader('Last-Modified');
              playlistUpdated = true;
            }
            lastModified = xmlhttp.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp.send(null)

        setTimeout("checkFileUpdate('playlist.xml')", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate('playlist.xml')", 60000);
    </script>

    <!-- inline script #2 - Player API -->
    <script type="text/javascript">
      var player       =  null;
      var currentItem  =     0;
      var startItem    =     0;

      function playerReady(obj)
      {
        player = gid(obj.id);
        player.addControllerListener('ITEM', 'itemMonitor');
        player.addModelListener('STATE',     'stateMonitor');
      };

      function itemMonitor(obj)
      {
        currentItem = obj.index;
      };

      function stateMonitor(obj)
      {
//alert('obj.newstate: ' + obj.newstate + '\nplaylistUpdated: ' + playlistUpdated);
        //...reload playlist on completion of current item only if playlist has been updated
        if((obj.newstate = 'COMPLETED') && playlistUpdated)
        {
          player.sendEvent('LOAD', 'playlist.xml');
//alert('playlistUpdated: ' + playlistUpdated);
          playlistUpdated = false;
        }
      };

/*
      //...use this function to load a new item upon completion of the current item
      //...comment out or remove the loop:  function reloadPlaylist()
      //...comment out or remove the entire JavaScript code block:  <!-- inline script #1 - AJAX -->
      //...comment out or remove the other: function stateMonitor()
      function stateMonitor(obj)
      {
        //...load a new playlist on completion of current item
        if(obj.newstate = 'COMPLETED')
        {
          player.sendEvent('LOAD', 'playlist.xml');
        }
      };
*/

/*
      // playlist reload loop timer
      function reloadPlaylist()
      {
        player.sendEvent('LOAD', 'playlist.xml');
        startItem = currentItem;
        setTimeout("player.sendEvent('ITEM', startItem)", 750);
        setTimeout("reloadPlaylist()", 60000);
      };

      // start loop timer
      setTimeout("reloadPlaylist()", 60000);
*/

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

    <!-- inline script #3 - Player -->
    <script type="text/javascript">
      var flashvars =
      {
        'file':                         'playlist.xml',
        'playlist':                     'bottom',
        'playlistsize':                 '180',
        'stretching':                   'exactfit',
        'repeat':                       'always',
        'shuffle':                      'false',
        'autostart':                    'true'
      };

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

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

      swfobject.embedSWF('player-4.4.135.swf', 'player', '400', '500', '9.0.124', false, flashvars, params, attributes);
    </script>

  </head>

  <body>

    <div id="playercontainer" class="playercontainer">
      <a id="player" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>

  </body>

</html>

Thanks for posting the v4 player code. I am having some problems getting it to work. I am using 4.13 player with firefox. I didn't see a swfobject-2.2.js so I changed it to swfobject.js. I didn't see a player-4.4.135.swf so I changed it to player.swf. I changed playlist.xml to list.xspf so it matches my playlist name. I was looking at the page using the firebug plugin in firefox and it says sfwobject is not defined at line 183. I am lost. Please help.

Thanks!

Here is my code:

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

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<title>Reload Playlist Every 60s -or- If Playlist Has Been Updated - JWMP v4.4.x - swfobject v2.2</title>

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

<!-- inline script #1 - AJAX -->
<script type="text/javascript">
var xmlhttp = false;
var lastModified = null;
var playlistUpdated = false;

try
{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(E)
{
xmlhttp = false;
}
}

if(!xmlhttp && typeof XMLHttpRequest != 'undefined')
{
try
{
xmlhttp = new XMLHttpRequest();
}
catch(e)
{
xmlhttp = false;
}
}

if(!xmlhttp && window.createRequest)
{
try
{
xmlhttp = window.createRequest();
}
catch(e)
{
xmlhttp = false;
}
}

function checkFileUpdate(file)
{
xmlhttp.open('HEAD', file, true);
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readyState == 4)
{
if((lastModified != null) && (lastModified != xmlhttp.getResponseHeader('Last-Modified')))
{
//alert('File was last modified on: ' + xmlhttp.getResponseHeader('Last-Modified'));
lastModified = xmlhttp.getResponseHeader('Last-Modified');
playlistUpdated = true;
}
lastModified = xmlhttp.getResponseHeader('Last-Modified');
}
}
xmlhttp.send(null)

setTimeout("checkFileUpdate('list.xspf')", 60000);
};

// start loop timer
setTimeout("checkFileUpdate('list.xspf')", 60000);
</script>

<!-- inline script #2 - Player API -->
<script type="text/javascript">
var player = null;
var currentItem = 0;
var startItem = 0;

function playerReady(obj)
{
player = gid(obj.id);
player.addControllerListener('ITEM', 'itemMonitor');
player.addModelListener('STATE', 'stateMonitor');
};

function itemMonitor(obj)
{
currentItem = obj.index;
};

function stateMonitor(obj)
{
//alert('obj.newstate: ' + obj.newstate + '\nplaylistUpdated: ' + playlistUpdated);
//...reload playlist on completion of current item only if playlist has been updated
if((obj.newstate = 'COMPLETED') && playlistUpdated)
{
player.sendEvent('LOAD', 'list.xspf');
//alert('playlistUpdated: ' + playlistUpdated);
playlistUpdated = false;
}
};

/*
//...use this function to load a new item upon completion of the current item
//...comment out or remove the loop: function reloadPlaylist()
//...comment out or remove the entire JavaScript code block: <!-- inline script #1 - AJAX -->
//...comment out or remove the other: function stateMonitor()
function stateMonitor(obj)
{
//...load a new playlist on completion of current item
if(obj.newstate = 'COMPLETED')
{
player.sendEvent('LOAD', 'list.xspf');
}
};
*/

/*
// playlist reload loop timer
function reloadPlaylist()
{
player.sendEvent('LOAD', 'list.xspf');
startItem = currentItem;
setTimeout("player.sendEvent('ITEM', startItem)", 750);
setTimeout("reloadPlaylist()", 60000);
};

// start loop timer
setTimeout("reloadPlaylist()", 60000);
*/

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

<!-- inline script #3 - Player -->
<script type="text/javascript">
var flashvars =
{
'file': 'list.xspf',
'playlist': 'bottom',
'playlistsize': '180',
'stretching': 'exactfit',
'repeat': 'always',
'shuffle': 'false',
'autostart': 'true'
};

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

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

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

</head>

<body>

<div id="playercontainer" class="playercontainer">
<a id="player" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
</div>

</body>

</html>

Use this code to load swfobject v2.1 from Google:    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject.js"></script>

You can get the v4.4.135 (or latest) player here:

      http://developer.longtailvideo.com/trac/browser/trunk/as3/player.swf?rev=140

After you have loaded the player, right-click on the display area to see the exact release that you have.

I might add, you can name swfobject.js and player.swf anything that you want to. I add the version to the filename so anyone looking at this code can see what versions I used. swfobject doesn't change too fast, but the JavaScript code for swfobject v2.x is very different from the code that was used for SWFObject v1.x (now considered to be obsolete by its developers).

However, the JW FLV Media Player is changing very fast, with new features added every few days, so if you want to be on the "bleeding edge" and use the latest bells, whistles, and kazoos, you need to know what version is needed to make the code work as posted.

Thanks for the response lefTy. I am making some progress. I am able to get media player to work with swobject 2.1 and 4.4.135 player. However, the player is not recognizing playlist updates so it continues to loop the original playlist. I am using firefox on linux (Ubuntu 8.10). I am not sure if this makes any difference. Ubuntu does keep file modified information. I don't know if your script is able to read this information?

Thanks!

Your server has to return the Response Headers for this to work.

You can turn on (uncomment) this alert to see if your server is returning the headers:

//alert('File was last modified on: ' + xmlhttp.getResponseHeader('Last-Modified'));

There is a mistake in the code, sorry about that.

In the stateMonitor() function find this:if((obj.newstate = 'COMPLETED') && playlistUpdated)and add a second equals sign:if((obj.newstate <strong>==</strong> 'COMPLETED') && playlistUpdated)

I have been testing this code locally on my computer by just pointing my browser to the html file. Based on your response, it appears that for Response Headers to work, I need to test on a webserver?

I tried the code on an internal webserver I have and commented out the line you suggest.

I updated the playlist and got an the message "File was last modified on: Sat, 24 Jan 2009 19:14:34 GMT" so it appears Response Headers are working on my webserver.

However, the playlist is still not reloading.

Based on my limited knowledge of how this all works, I
commented out the line.
//alert('playlistUpdated: ' + playlistUpdated);

I updated the playlist file and refreshed browser but got no alerts and playlist still did not reload.

Thanks!

I didn't see your previous post about adding the second equal sign in the stateMonitor() function. I just made the update but the playlist is still not reloading. I tried commenting out

//alert('obj.newstate: ' + obj.newstate + '\nplaylistUpdated: ' + playlistUpdated);

and

//alert('playlistUpdated: ' + playlistUpdated);

I didn't get any alerts.

Thanks!

I'll do some more testing.

Try replacing your stateMonitor(obj) function with this one:

      function stateMonitor(obj)
      {
        //...reload playlist on completion of current item only if playlist has been updated
        if((obj.newstate == 'COMPLETED') && playlistUpdated)
        {
          var rid = Math.round(1000 * Math.random());
          player.sendEvent('STOP', 'null');
          player.sendEvent('LOAD', playlistFile + '?' + rid);
          player.sendEvent('PLAY', 'true');
          playlistUpdated = false;
        }
      };

Prevents the cached playlist from being re-loaded by adding a random number to the playlist filename, which forces a fresh load of the playlist from your server.

Thanks for the response. I have replaced the stateMonitor function as you suggested. However, it is still not updating the playlist. One thing that I noticed was refreshing the browser after updating the playlist isn't updating the playlist. I am having to clear temporary internet files and then refreshing the browser to get the updated playlist to show. I tested with internet explorer 7, Opera 9.6 and firefox 3.05. All three browsers are behaving the same.

I am testing by browsing to the web page. I update the playlist file. I am updating the file within a minute or so...not sure if that makes a difference or not. I wait about five minutes to see if the player reloads the new playlist or not. (The playlist should update in 60 seconds, right?). When the playlist doesn't update, I try refreshing the browser but it seems to have the old playlist cached. After I delete temporary internet files and refresh the page, the updated playlist starts to play. I am using an .xspf playlist. Not sure if that makes a difference.

Can you post the most updated version of the code? We have made a few changes but I want to make sure I have the exact same code you have. Also, I am not sure if there is anything I need to comment out or not. Your code had some comments that said to comment/delete lines of code if needed. I haven't modified anything at all except the changes you mentioned in this post.

Thanks!

Here's the file I'm currently using. Enter your playlist filename on line 16. The code checks for an updated playlist every 60 seconds, which you can change on line 82.

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

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head>

    <title>Reload Playlist Every 60s -or- If Playlist Has Been Updated - JWMP v4.4.x - swfobject v2.2</title>

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

    <!-- inline script #1 - AJAX -->
    <script type="text/javascript">
      var xmlhttp         = false;
      var lastModified    =  null;
      var playlistUpdated = false;
      var playlistFile    = 'playlist_reload.xml';

      try
      {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(E)
        {
          xmlhttp = false;
        }
      }

      if(!xmlhttp && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp = false;
        }
      }

      if(!xmlhttp && window.createRequest)
      {
        try
        {
          xmlhttp = window.createRequest();
        }
        catch(e)
        {
          xmlhttp = false;
        }
      }

      function checkFileUpdate(file)
      {
        xmlhttp.open('HEAD', file, true);
        xmlhttp.onreadystatechange = function()
        {
          if(xmlhttp.readyState == 4)
          {
            if((lastModified != null) && (lastModified != xmlhttp.getResponseHeader('Last-Modified')))
            {
              lastModified    = xmlhttp.getResponseHeader('Last-Modified');
              playlistUpdated = true;
gid('checkfile').innerHTML = 'File was last modified on: ' + xmlhttp.getResponseHeader('Last-Modified') + '   playlistUpdated: ' + playlistUpdated;
            }
            else
            {
gid('checkfile').innerHTML = 'File has not been modified since: ' + xmlhttp.getResponseHeader('Last-Modified') + '   playlistUpdated: ' + playlistUpdated;
            }
            lastModified = xmlhttp.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp.send(null)

        setTimeout("checkFileUpdate(playlistFile)", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate(playlistFile)", 10000);
    </script>

    <!-- inline script #2 - Player API -->
    <script type="text/javascript">
      var player       =  null;
      var currentItem  =     0;
      var startItem    =     0;

      function playerReady(obj)
      {
        player = gid(obj.id);
        player.addControllerListener('ITEM', 'itemMonitor');
        player.addModelListener('STATE',     'stateMonitor');
      };

      function itemMonitor(obj)
      {
        currentItem = obj.index;
      };

//var count = 1;
      function stateMonitor(obj)
      {
gid('state1').innerHTML = 'obj.newstate: ' + obj.newstate + '   playlistUpdated: ' + playlistUpdated;
        //...reload playlist on completion of current item only if playlist has been updated
        if((obj.newstate == 'COMPLETED') && playlistUpdated)
        {
          var rid = Math.round(1000 * Math.random());
          player.sendEvent('STOP', 'null');
          player.sendEvent('LOAD', playlistFile + '?' + rid);

//player.sendEvent('LOAD', 'playlist_reload' + count + '.xml?' + rid);
//gid('state2').innerHTML = 'playlistUpdated: ' + playlistUpdated + '   Playlist: ' + 'playlist_reload' + count + '.xml?' + rid;
//count++;
//if(count > 6) count = 1;

          player.sendEvent('PLAY', 'true');
gid('state2').innerHTML = 'playlistUpdated: ' + playlistUpdated + '   Playlist: ' + playlistFile + '?' + rid;
          playlistUpdated = false;
        }
      };

/*
      //...use this function to load a new item upon completion of the current item
      //...comment out or remove the loop:  function reloadPlaylist()
      //...comment out or remove the entire JavaScript code block:  <!-- inline script #1 - AJAX -->
      //...comment out or remove the other: function stateMonitor()
      function stateMonitor(obj)
      {
        //...load a new playlist on completion of current item
        if(obj.newstate == 'COMPLETED')
        {
          player.sendEvent('LOAD', 'playlist.xml');
        }
      };
*/

/*
      // playlist reload loop timer
      function reloadPlaylist()
      {
        player.sendEvent('LOAD', 'playlist.xml');
        startItem = currentItem;
        setTimeout("player.sendEvent('ITEM', startItem)", 750);
        setTimeout("reloadPlaylist()", 60000);
      };

      // start loop timer
      setTimeout("reloadPlaylist()", 60000);
*/

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

    <!-- inline script #3 - Player -->
    <script type="text/javascript">
      var flashvars =
      {
        'file':                          playlistFile,
        'playlist':                     'bottom',
        'playlistsize':                 '180',
        'stretching':                   'exactfit',
        'repeat':                       'always',
        'shuffle':                      'false',
        'autostart':                    'true'
      };

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

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

    //swfobject.embedSWF('player-4.3.132.swf', 'player', '400', '500', '9.0.124', false, flashvars, params, attributes);
      swfobject.embedSWF('player-4.4.139.swf', 'player', '400', '500', '9.0.124', false, flashvars, params, attributes);
    </script>

  </head>

  <body>

    <div id="playercontainer" class="playercontainer">
      <a id="player" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="state1">
    </div>
    <div id="state2">
    </div>
    <div id="checkfile">
    </div>

  </body>

</html>

Thanks for posting your code. I noticed you are using swfobject2.2.js. I looked around but was not able to find that so I am still using swfobject2.1.js. I also downloaded the latest version of player (4.4.140). I was using 4.4.135 previously.

I tested the code on different operating systems / browsers and am getting different results:

Ubuntu 8.10 / Firefox 3.05 / Opera 9.62 / Flash 10:
Playlist is still not reloading. I only see the "File has not been modified since: Sun, 25 Jan 2009 23:46:19 GMT playlistUpdated: true" line.
I do not see the obj.newstate or the Playlist xxx?xxx" line under the player. This might be the problem?

Windows XP / Internet Explorer 7 / Firefox 3.02/ Chrome
This appears to be working. It is showing
"obj.newstate: PLAYING playlistUpdated: false
playlistUpdated: true Playlist: list..xspf?747
File was last modified on: Sun, 25 Jan 2009 23:46:19 GMT playlistUpdated: true" under the player.

It appears as if there is something with the Ubuntu, Firefox combination that stateMonitor() function is not liking? Could there be some browser security settings that can cause these issues? Or maybe it is something related to swfobject2.1 vs 2.2? I need this to work under Ubuntu/Firefox.

I think we are getting closer to a solution :) Thanks for your continued help with this!

Maybe....................................................

Ubuntu doesn't seem to get the player's id, so Jeroen added a bit of code to help.

See:

      http://developer.longtailvideo.com/trac/wiki/FlashVars#External

So........................................ add:

        'id':                           'playerId',

in your flashvars.

swfobject v2.1 and v2.2 are about the same except for a few "enhancements" for IE, etc. If you really want swfobject v2.2, get it here:

      http://code.google.com/p/swfobject/wiki/development_notes

Direct link:

      http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js

[i]WARNING: Alpha code.  Have fun !!!       :D[/i]

Updating the flashvars as you recommended did the trick! I originally added them to the end of the list of flashvars and it failed. When I added it to the begining of the list it worked :)

Now for the next question. I would like to use multiple players (and have them each automatically reload the playlist if it is updated). I searched for some examples but dont know how to incorporate it witht he code that you have written.

Thanks for the help!

For 2 players, the first step would be to duplicate everything, numbered 1 & 2.

Once that is working, you would combine the common functions as I have done with playerReady() and itemMonitor(). I'll leave the others for you.

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

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head>

    <title>Reload Playlist If Playlist Has Been Updated - 2 Players - JWMP v4.4.x - swfobject v2.2</title>

    <style type="text/css">
      div.playercontainer
      {
        display:              inline;
      }
    </style>

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

    <!-- inline script #1 - AJAX -->
    <script type="text/javascript">
      var xmlhttp1         =   false;
      var lastModified1    =   null;
      var playlistUpdated1 =   false;
      var playlistFile1    =  'playlist_reload_1.xml';

      var xmlhttp2         =   false;
      var lastModified2    =   null;
      var playlistUpdated2 =   false;
      var playlistFile2    =  'playlist_reload_2.xml';

      try
      {
        xmlhttp1 = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp1 = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(E)
        {
          xmlhttp1 = false;
        }
      }

      if(!xmlhttp1 && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp1 = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp1 = false;
        }
      }

      if(!xmlhttp1 && window.createRequest)
      {
        try
        {
          xmlhttp1 = window.createRequest();
        }
        catch(e)
        {
          xmlhttp1 = false;
        }
      }

      function checkFileUpdate1(file)
      {
        xmlhttp1.open('HEAD', file, true);
        xmlhttp1.onreadystatechange = function()
        {
          if(xmlhttp1.readyState == 4)
          {
            if((lastModified1 != null) && (lastModified1 != xmlhttp1.getResponseHeader('Last-Modified')))
            {
              lastModified1    = xmlhttp1.getResponseHeader('Last-Modified');
              playlistUpdated1 = true;
gid('checkfile1').innerHTML = 'File1 was last modified on: ' + xmlhttp1.getResponseHeader('Last-Modified') + '   playlistUpdated1: ' + playlistUpdated1;
            }
            else
            {
gid('checkfile1').innerHTML = 'File1 has not been modified since: ' + xmlhttp1.getResponseHeader('Last-Modified') + '   playlistUpdated1: ' + playlistUpdated1;
            }
            lastModified1 = xmlhttp1.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp1.send(null)

        setTimeout("checkFileUpdate1(playlistFile1)", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate1(playlistFile1)", 10000);

      try
      {
        xmlhttp2 = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp2 = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(E)
        {
          xmlhttp2 = false;
        }
      }

      if(!xmlhttp2 && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp2 = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp2 = false;
        }
      }

      if(!xmlhttp2 && window.createRequest)
      {
        try
        {
          xmlhttp2 = window.createRequest();
        }
        catch(e)
        {
          xmlhttp2 = false;
        }
      }

      function checkFileUpdate2(file)
      {
        xmlhttp2.open('HEAD', file, true);
        xmlhttp2.onreadystatechange = function()
        {
          if(xmlhttp2.readyState == 4)
          {
            if((lastModified2 != null) && (lastModified2 != xmlhttp2.getResponseHeader('Last-Modified')))
            {
              lastModified2    = xmlhttp2.getResponseHeader('Last-Modified');
              playlistUpdated2 = true;
gid('checkfile2').innerHTML = 'File2 was last modified on: ' + xmlhttp2.getResponseHeader('Last-Modified') + '   playlistUpdated2: ' + playlistUpdated2;
            }
            else
            {
gid('checkfile2').innerHTML = 'File2 has not been modified since: ' + xmlhttp2.getResponseHeader('Last-Modified') + '   playlistUpdated2: ' + playlistUpdated2;
            }
            lastModified2 = xmlhttp2.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp2.send(null)

        setTimeout("checkFileUpdate2(playlistFile2)", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate2(playlistFile2)", 10000);
    </script>

    <!-- inline script #2 - Player API -->
    <script type="text/javascript">
      var player1       =  null;
      var currentItem1  =     0;
      var startItem1    =     0;

      var player2       =  null;
      var currentItem2  =     0;
      var startItem2    =     0;

      function playerReady(obj)
      {
        if(obj.id == 'playerId1')
        {
          player1 = gid(obj.id);
        }

        if(obj.id == 'playerId2')
        {
          player2 = gid(obj.id);
        }

        if(player1 && player2)
        {
          player1.addControllerListener('ITEM',      'itemMonitor');
          player2.addControllerListener('ITEM',      'itemMonitor');
          player1.addModelListener('STATE',          'stateMonitor');
          player2.addModelListener('STATE',          'stateMonitor');
        }
      };

      function itemMonitor(obj)
      {
        if(obj.id == 'player1')
        {
          currentItem1 = obj.index;
        }
        if(obj.id == 'player2')
        {
          currentItem2 = obj.index;
        }
      };

      function stateMonitor(obj)
      {
        if(obj.id == 'playerId1')
        {
gid('state11').innerHTML = 'Player1: ' + obj.newstate + '   playlistUpdated1: ' + playlistUpdated1;
          //...reload playlist on completion of current item only if playlist has been updated
          if((obj.newstate == 'COMPLETED') && playlistUpdated1)
          {
            player1.sendEvent('STOP', 'null');
            player1.sendEvent('LOAD', playlistFile1 + '?' + Math.round(1000 * Math.random()));
            player1.sendEvent('PLAY', 'true');
gid('state12').innerHTML = 'playlistUpdated1: ' + playlistUpdated1 + '   Playlist1: ' + playlistFile1 + '?' + Math.round(1000 * Math.random());
            playlistUpdated1 = false;
          }
        }

        if(obj.id == 'playerId2')
        {
gid('state21').innerHTML = 'Player2: ' + obj.newstate + '   playlistUpdated2: ' + playlistUpdated2;
          //...reload playlist on completion of current item only if playlist has been updated
          if((obj.newstate == 'COMPLETED') && playlistUpdated2)
          {
            player2.sendEvent('STOP', 'null');
            player2.sendEvent('LOAD', playlistFile2 + '?' + Math.round(1000 * Math.random()));
            player2.sendEvent('PLAY', 'true');
gid('state22').innerHTML = 'playlistUpdated2: ' + playlistUpdated2 + '   Playlist2: ' + playlistFile2 + '?' + Math.round(1000 * Math.random());
            playlistUpdated2 = false;
          }
        }
      };

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

    <!-- inline script #3 - Players 1 &amp; 2 -->
    <script type="text/javascript">
      var flashvars =
      {
        'file':                          playlistFile2,
        'playlist':                     'bottom',
        'playlistsize':                 '180',
        'stretching':                   'exactfit',
        'repeat':                       'always',
        'shuffle':                      'false',
        'id':                           'playerId1',
        'autostart':                    'true'
      };

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

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

      swfobject.embedSWF('player-4.4.139.swf', 'player1', '400', '500', '9.0.124', false, flashvars, params, attributes);

      flashvars.file                   =  playlistFile2;
      flashvars.id                     = 'playerId2';

      attributes.id                    = 'playerId2';
      attributes.name                  = 'playerId2';

      swfobject.embedSWF('player-4.4.139.swf', 'player2', '400', '500', '9.0.124', false, flashvars, params, attributes);
    </script>

  </head>

  <body>

    <div id="playercontainer1" class="playercontainer">
      <a id="player1" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="playercontainer2" class="playercontainer">
      <a id="player2" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="state11">
    </div>
    <div id="state12">
    </div>
    <div id="checkfile1">
    </div>
    <br />
    <div id="state21">
    </div>
    <div id="state22">
    </div>
    <div id="checkfile2">
    </div>

  </body>

</html>

Have Fun !!! :D

The longer this code gets the more overwhelming it gets for me :)

I am trying to figure out what functions have been updated and what still need to be updated.

From what I can see, checkFileUpdate1 and 2, playerReady, itemMonitor, stateMonitor functions have been updated.

I am not if or how function gid(name) should be updated.

I tried the code as is and both players were showing the same playlist. I modified the the flashver line 'file': playlistFile2 to playlistFile1 to correct this.

Right now player1 is able to reload updated playlists but player2 isn't.

I'm sure I am missing something simple.

Thanks!

The function gid(name) is common and doesn't need to be updated.

The playlistFile2 for player1 was a mistake.

Post your code (please use the code tags "<>" below the text entry box) or a live link to your test page and I'll check your code.

Here is the code I currently have.

Thanks

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

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head>

    <title>Reload Playlist If Playlist Has Been Updated - 2 Players - JWMP v4.4.x - swfobject v2.1</title>

    <style type="text/css">
      div.playercontainer
      {
        display:              inline;
      }
    </style>

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

    <!-- inline script #1 - AJAX -->
    <script type="text/javascript">
      var xmlhttp1         =   false;
      var lastModified1    =   null;
      var playlistUpdated1 =   false;
      var playlistFile1    =  'playlist1.xspf';

      var xmlhttp2         =   false;
      var lastModified2    =   null;
      var playlistUpdated2 =   false;
      var playlistFile2    =  'playlist2.xspf';

      try
      {
        xmlhttp1 = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp1 = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(E)
        {
          xmlhttp1 = false;
        }
      }

      if(!xmlhttp1 && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp1 = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp1 = false;
        }
      }

      if(!xmlhttp1 && window.createRequest)
      {
        try
        {
          xmlhttp1 = window.createRequest();
        }
        catch(e)
        {
          xmlhttp1 = false;
        }
      }

      function checkFileUpdate1(file)
      {
        xmlhttp1.open('HEAD', file, true);
        xmlhttp1.onreadystatechange = function()
        {
          if(xmlhttp1.readyState == 4)
          {
            if((lastModified1 != null) && (lastModified1 != xmlhttp1.getResponseHeader('Last-Modified')))
            {
              lastModified1    = xmlhttp1.getResponseHeader('Last-Modified');
              playlistUpdated1 = true;
gid('checkfile1').innerHTML = 'File1 was last modified on: ' + xmlhttp1.getResponseHeader('Last-Modified') + '   playlistUpdated1: ' + playlistUpdated1;
            }
            else
            {
gid('checkfile1').innerHTML = 'File1 has not been modified since: ' + xmlhttp1.getResponseHeader('Last-Modified') + '   playlistUpdated1: ' + playlistUpdated1;
            }
            lastModified1 = xmlhttp1.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp1.send(null)

        setTimeout("checkFileUpdate1(playlistFile1)", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate1(playlistFile1)", 10000);

      try
      {
        xmlhttp2 = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp2 = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(e)
        {
          xmlhttp2 = false;
        }
      }

      if(!xmlhttp2 && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp2 = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp2 = false;
        }
      }

      if(!xmlhttp2 && window.createRequest)
      {
        try
        {
          xmlhttp2 = window.createRequest();
        }
        catch(e)
        {
          xmlhttp2 = false;
        }
      }

      function checkFileUpdate2(file)
      {
        xmlhttp2.open('HEAD', file, true);
        xmlhttp2.onreadystatechange = function()
        {
          if(xmlhttp2.readyState == 4)
          {
            if((lastModified2 != null) && (lastModified2 != xmlhttp2.getResponseHeader('Last-Modified')))
            {
              lastModified2    = xmlhttp2.getResponseHeader('Last-Modified');
              playlistUpdated2 = true;
gid('checkfile2').innerHTML = 'File2 was last modified on: ' + xmlhttp2.getResponseHeader('Last-Modified') + '   playlistUpdated2: ' + playlistUpdated2;
            }
            else
            {
gid('checkfile2').innerHTML = 'File2 has not been modified since: ' + xmlhttp2.getResponseHeader('Last-Modified') + '   playlistUpdated2: ' + playlistUpdated2;
            }
            lastModified2 = xmlhttp2.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp2.send(null)

        setTimeout("checkFileUpdate2(playlistFile2)", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate2(playlistFile2)", 10000);
    </script>

    <!-- inline script #2 - Player API -->
    <script type="text/javascript">
      var player1       =  null;
      var currentItem1  =     0;
      var startItem1    =     0;

      var player2       =  null;
      var currentItem2  =     0;
      var startItem2    =     0;

      function playerReady(obj)
      {
        if(obj.id == 'playerId1')
        {
          player1 = gid(obj.id);
        }

        if(obj.id == 'playerId2')
        {
          player2 = gid(obj.id);
        }

        if(player1 && player2)
        {
          player1.addControllerListener('ITEM',      'itemMonitor');
          player2.addControllerListener('ITEM',      'itemMonitor');
          player1.addModelListener('STATE',          'stateMonitor');
          player2.addModelListener('STATE',          'stateMonitor');
        }
      };

      function itemMonitor(obj)
      {
        if(obj.id == 'player1')
        {
          currentItem1 = obj.index;
        }
        if(obj.id == 'player2')
        {
          currentItem2 = obj.index;
        }
      };

      function stateMonitor(obj)
      {
        if(obj.id == 'playerId1')
        {
gid('state11').innerHTML = 'Player1: ' + obj.newstate + '   playlistUpdated1: ' + playlistUpdated1;
          //...reload playlist on completion of current item only if playlist has been updated
          if((obj.newstate == 'COMPLETED') && playlistUpdated1)
          {
            player1.sendEvent('STOP', 'null');
            player1.sendEvent('LOAD', playlistFile1 + '?' + Math.round(1000 * Math.random()));
            player1.sendEvent('PLAY', 'true');
gid('state12').innerHTML = 'playlistUpdated1: ' + playlistUpdated1 + '   Playlist1: ' + playlistFile1 + '?' + Math.round(1000 * Math.random());
            playlistUpdated1 = false;
          }
        }

        if(obj.id == 'playerId2')
        {
gid('state21').innerHTML = 'Player2: ' + obj.newstate + '   playlistUpdated2: ' + playlistUpdated2;
          //...reload playlist on completion of current item only if playlist has been updated
          if((obj.newstate == 'COMPLETED') && playlistUpdated2)
          {
            player2.sendEvent('STOP', 'null');
            player2.sendEvent('LOAD', playlistFile2 + '?' + Math.round(1000 * Math.random()));
            player2.sendEvent('PLAY', 'true');
gid('state22').innerHTML = 'playlistUpdated2: ' + playlistUpdated2 + '   Playlist2: ' + playlistFile2 + '?' + Math.round(1000 * Math.random());
            playlistUpdated2 = false;
          }
        }
      };

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

    <!-- inline script #3 - Players 1 &amp; 2 -->
    <script type="text/javascript">
      var flashvars =
      {
        'file':                          playlistFile1,
        'playlist':                     'bottom',
        'playlistsize':                 '180',
        'stretching':                   'exactfit',
        'repeat':                       'always',
        'shuffle':                      'false',
        'id':                           'playerId1',
        'autostart':                    'true'
      };

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

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

      swfobject.embedSWF('player-4.4.140.swf', 'player1', '400', '500', '9.0.124', false, flashvars, params, attributes);

      flashvars.file                   =  playlistFile2;
      flashvars.id                     = 'playerId2';

      attributes.id                    = 'playerId2';
      attributes.name                  = 'playerId2';

      swfobject.embedSWF('player-4.4.140.swf', 'player2', '400', '500', '9.0.124', false, flashvars, params, attributes);
    </script>

  </head>

  <body>

    <div id="playercontainer1" class="playercontainer">
      <a id="player1" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="playercontainer2" class="playercontainer">
      <a id="player2" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="state11">
    </div>
    <div id="state12">
    </div>
    <div id="checkfile1">
    </div>
    <br />
    <div id="state21">
    </div>
    <div id="state22">
    </div>
    <div id="checkfile2">
    </div>

  </body>

</html>

Flawless.

http://willswonders.myip.org:8085/php/ss_double.html

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

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head>

    <title>Reload Playlist If Playlist Has Been Updated - 2 Players - JWMP v4.4.x - swfobject v2.1</title>

    <style type="text/css">
      div.playercontainer
      {
        display: inline;
      }
    </style>

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

    <!-- inline script #1 - AJAX -->
    <script type="text/javascript">
      var xmlhttp1          =            false;
      var lastModified1     =             null;
      var playlistUpdated1  =            false;
      var playlistFile1     = 'playlist1.xspf';

      var xmlhttp2          =            false;
      var lastModified2     =             null;
      var playlistUpdated2  =            false;
      var playlistFile2     = 'playlist2.xspf';

      try
      {
        xmlhttp1 = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp1 = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(E)
        {
          xmlhttp1 = false;
        }
      }

      if(!xmlhttp1 && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp1 = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp1 = false;
        }
      }

      if(!xmlhttp1 && window.createRequest)
      {
        try
        {
          xmlhttp1 = window.createRequest();
        }
        catch(e)
        {
          xmlhttp1 = false;
        }
      }

      function checkFileUpdate1(file)
      {
        xmlhttp1.open('HEAD', file, true);
        xmlhttp1.onreadystatechange = function()
        {
          if(xmlhttp1.readyState == 4)
          {
            if((lastModified1 != null) && (lastModified1 != xmlhttp1.getResponseHeader('Last-Modified')))
            {
              lastModified1 = xmlhttp1.getResponseHeader('Last-Modified');
              playlistUpdated1 = true;
gid('checkfile1').innerHTML = 'File1 was last modified on: ' + xmlhttp1.getResponseHeader('Last-Modified') + ' playlistUpdated1: ' + playlistUpdated1;
            }
            else
            {
gid('checkfile1').innerHTML = 'File1 has not been modified since: ' + xmlhttp1.getResponseHeader('Last-Modified') + ' playlistUpdated1: ' + playlistUpdated1;
            }
            lastModified1 = xmlhttp1.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp1.send(null)

        setTimeout("checkFileUpdate1(playlistFile1)", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate1(playlistFile1)", 10000);

      try
      {
        xmlhttp2 = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch(e)
      {
        try
        {
          xmlhttp2 = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(E)
        {
          xmlhttp2 = false;
        }
      }

      if(!xmlhttp2 && typeof XMLHttpRequest != 'undefined')
      {
        try
        {
          xmlhttp2 = new XMLHttpRequest();
        }
        catch(e)
        {
          xmlhttp2 = false;
        }
      }

      if(!xmlhttp2 && window.createRequest)
      {
        try
        {
          xmlhttp2 = window.createRequest();
        }
        catch(e)
        {
          xmlhttp2 = false;
        }
      }

      function checkFileUpdate2(file)
      {
        xmlhttp2.open('HEAD', file, true);
        xmlhttp2.onreadystatechange = function()
        {
          if(xmlhttp2.readyState == 4)
          {
            if((lastModified2 != null) && (lastModified2 != xmlhttp2.getResponseHeader('Last-Modified')))
            {
              lastModified2 = xmlhttp2.getResponseHeader('Last-Modified');
              playlistUpdated2 = true;
gid('checkfile2').innerHTML = 'File2 was last modified on: ' + xmlhttp2.getResponseHeader('Last-Modified') + ' playlistUpdated2: ' + playlistUpdated2;
            }
            else
            {
gid('checkfile2').innerHTML = 'File2 has not been modified since: ' + xmlhttp2.getResponseHeader('Last-Modified') + ' playlistUpdated2: ' + playlistUpdated2;
            }
            lastModified2 = xmlhttp2.getResponseHeader('Last-Modified');
          }
        }
        xmlhttp2.send(null)

        setTimeout("checkFileUpdate2(playlistFile2)", 60000);
      };

      // start loop timer
      setTimeout("checkFileUpdate2(playlistFile2)", 10000);
    </script>

    <!-- inline script #2 - Player API -->
    <script type="text/javascript">
      var player1       =  null;
      var currentItem1  =     0;
      var startItem1    =     0;

      var player2       =  null;
      var currentItem2  =     0;
      var startItem2    =     0;

      function playerReady(obj)
      {
        if(obj.id == 'playerId1')
        {
          player1 = gid(obj.id);
        }

        if(obj.id == 'playerId2')
        {
          player2 = gid(obj.id);
        }

        if(player1 && player2)
        {
          player1.addControllerListener('ITEM',  'itemMonitor');
          player2.addControllerListener('ITEM',  'itemMonitor');
          player1.addModelListener('STATE',      'stateMonitor');
          player2.addModelListener('STATE',      'stateMonitor');
        }
      };

      function itemMonitor(obj)
      {
        if(obj.id == 'player1')
        {
          currentItem1 = obj.index;
        }
        if(obj.id == 'player2')
        {
          currentItem2 = obj.index;
        }
      };

      function stateMonitor(obj)
      {
        if(obj.id == 'playerId1')
        {
gid('state11').innerHTML = 'Player1: ' + obj.newstate + ' playlistUpdated1: ' + playlistUpdated1;
          //...reload playlist on completion of current item only if playlist has been updated
          if((obj.newstate == 'COMPLETED') && playlistUpdated1)
          {
            player1.sendEvent('STOP', 'null');
            player1.sendEvent('LOAD',  playlistFile1 + '?' + Math.round(1000 * Math.random()));
            player1.sendEvent('PLAY', 'true');
gid('state12').innerHTML = 'playlistUpdated1: ' + playlistUpdated1 + ' Playlist1: ' + playlistFile1 + '?' + Math.round(1000 * Math.random());
            playlistUpdated1 = false;
          }
        }

        if(obj.id == 'playerId2')
        {
gid('state21').innerHTML = 'Player2: ' + obj.newstate + ' playlistUpdated2: ' + playlistUpdated2;
          //...reload playlist on completion of current item only if playlist has been updated
          if((obj.newstate == 'COMPLETED') && playlistUpdated2)
          {
            player2.sendEvent('STOP', 'null');
            player2.sendEvent('LOAD',  playlistFile2 + '?' + Math.round(1000 * Math.random()));
            player2.sendEvent('PLAY', 'true');
gid('state22').innerHTML = 'playlistUpdated2: ' + playlistUpdated2 + ' Playlist2: ' + playlistFile2 + '?' + Math.round(1000 * Math.random());
            playlistUpdated2 = false;
          }
        }
      };

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

    <!-- inline script #3 - Players 1 &amp; 2 -->
    <script type="text/javascript">
      var flashvars =
      {
        'file':                          playlistFile1,
        'playlist':                     'bottom',
        'playlistsize':                 '180',
        'stretching':                   'exactfit',
        'repeat':                       'always',
        'shuffle':                      'false',
        'id':                           'playerId1',
        'autostart':                    'true'
      };

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

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

      swfobject.embedSWF('player-4.4.140.swf', 'player1', '400', '500', '9.0.124', false, flashvars, params, attributes);

      flashvars.file                  =  playlistFile2;
      flashvars.id                    = 'playerId2';

      attributes.id                   = 'playerId2';
      attributes.name                 = 'playerId2';

      swfobject.embedSWF('player-4.4.140.swf', 'player2', '400', '500', '9.0.124', false, flashvars, params, attributes);
    </script>

  </head>

  <body>

    <div id="playercontainer1" class="playercontainer">
      <a id="player1" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="playercontainer2" class="playercontainer">
      <a id="player2" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="state11">
    </div>
    <div id="state12">
    </div>
    <div id="checkfile1">
    </div>
    <br />
    <div id="state21">
    </div>
    <div id="state22">
    </div>
    <div id="checkfile2">
    </div>

  </body>

</html>

Thanks for posting the updated code. It seems to work but I am seeing some strange behavior. Sometimes it is taking upto 10 mins for the updated playlist to be recognized and loaded. I also had player1 crash on me once. It stopped playing files and wouldn't respond to pressing the play button. Refreshing the page fixed the issue. I need to do some more testing to make sure this is not just a random problem. I will report back with that later.

Ok now to throw another twist into this... I would also like to use image rotator on this page. I would like to have image rotator look for updated playlists and load them. Could that be incorporated into the current framework or do different functions need to be written?

I really appreciate all the help you have provided with this. I am sure others will benefit from the code you have posted here as well. I promise to leave you alone soon :)

Thanks!

The Image Rotator is still v3.x, so it uses the old API.

A new block of the v3.x API code would have to be added as well as the Image Rotator code itself (similar to the player code, using swfobject v2.x to embed).

Rather than tripling the AJAX code, it's time to re-write it to use multiple instances.

A few days...

Thanks! It will give me time to test some of the unusual things I was seeing.

 
[i]Enjoy![/i]
    :D
 

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

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head>

    <title>Reload Playlist If Playlist Has Been Updated - 4 Players - JWMP v4.4.x - 2 Image Rotators - JWIR v3.17 - swfobject v2.2</title>

    <style type="text/css">
      div.playercontainer1
      {
        position:           absolute;
        top:                    50px;
        left:                  200px;
        width:                 400px;
        height:                380px;
        z-index:                   0;
      }

      div.playercontainer2
      {
        position:           absolute;
        top:                    50px;
        left:                  650px;
        width:                 400px;
        height:                380px;
        z-index:                   0;
      }

      div.playercontainer3
      {
        position:           absolute;
        top:                   480px;
        left:                  200px;
        width:                 400px;
        height:                380px;
        z-index:                   0;
      }

      div.playercontainer4
      {
        position:           absolute;
        top:                   480px;
        left:                  650px;
        width:                 400px;
        height:                380px;
        z-index:                   0;
      }

      div.imagerotatorcontainer1
      {
        position:           absolute;
        top:                   910px;
        left:                  200px;
        width:                 400px;
        height:                320px;
        z-index:                   0;
      }

      div.imagerotatorcontainer2
      {
        position:           absolute;
        top:                   910px;
        left:                  650px;
        width:                 400px;
        height:                320px;
        z-index:                   0;
      }
    </style>

    <style type="text/css">
      div.datapc1
      {
        position:           absolute;
        top:                    50px;
        left:                  200px;
        width:                 390px;
        height:                 40px;
        padding:                 5px;
        font-size:              12px;
        font-weight:            bold;
        font-family:           arial;
        color:               #202020;
        z-index:                   1;
      }

      div.datapc2
      {
        position:           absolute;
        top:                    50px;
        left:                  650px;
        width:                 390px;
        height:                 40px;
        padding:                 5px;
        font-size:              12px;
        font-weight:            bold;
        font-family:           arial;
        color:               #202020;
        z-index:                   1;
      }

      div.datapc3
      {
        position:           absolute;
        top:                   480px;
        left:                  200px;
        width:                 390px;
        height:                 40px;
        padding:                 5px;
        font-size:              12px;
        font-weight:            bold;
        font-family:           arial;
        color:               #202020;
        z-index:                   1;
      }

      div.datapc4
      {
        position:           absolute;
        top:                   480px;
        left:                  650px;
        width:                 390px;
        height:                 40px;
        padding:                 5px;
        font-size:              12px;
        font-weight:            bold;
        font-family:           arial;
        color:               #202020;
        z-index:                   1;
      }

      div.datair1
      {
        position:           absolute;
        top:                   910px;
        left:                  200px;
        width:                 390px;
        height:                 40px;
        padding:                 5px;
        font-size:              12px;
        font-weight:            bold;
        font-family:           arial;
        color:               #202020;
        z-index:                   1;
      }

      div.datair2
      {
        position:           absolute;
        top:                   910px;
        left:                  650px;
        width:                 390px;
        height:                 40px;
        padding:                 5px;
        font-size:              12px;
        font-weight:            bold;
        font-family:           arial;
        color:               #202020;
        z-index:                   1;
      }
    </style>

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

    <!-- inline script #1 - Configuration -->
    <script type="text/javascript">

/* doesn't work on LightTPD because the Last-Modified header is missing for an AJAX request; probably just my config
                        - LightTPD -
      C:\curl>curl -I http://127.0.0.1:8081/playlist_reload_1.xml
      HTTP/1.1 200 OK
      Date: Mon, 26 Jan 2009 23:47:50 GMT
      Server: LightTPD/1.4.19 (Win32)
      Last-Modified: Mon, 26 Jan 2009 20:11:23 GMT
      ETag: "-691693120"
      Accept-Ranges: bytes
      Content-Length: 329
      Content-Type: text/xml
  
                        - Apache -
      C:\curl>curl -I http://192.168.0.3:8085/php/playlist_reload_1.xml
      HTTP/1.1 200 OK
      Date: Mon, 26 Jan 2009 23:52:05 GMT
      Server: Apache
      Last-Modified: Mon, 26 Jan 2009 20:11:23 GMT
      ETag: "abdc-149-57bec488"
      Accept-Ranges: bytes
      Content-Length: 329
      Content-Type: text/xml;
*/

      // change the player or imagerotator filename here
      var player_filename        = 'player-4.4.141.swf';
      var imagerotator_filename  = 'imagerotator-3.17.swf';

      // turn the instrumentation off here
      var instrumentation        =   false;

      //...change the playlist file names here
      var lastModified1          =   null;
      var playlistUpdated1       =   false;
      var playlistFile1          =  'playlist_reload_1.xml';

      var lastModified2          =   null;
      var playlistUpdated2       =   false;
      var playlistFile2          =  'playlist_reload_2.xml';

      var lastModified3          =   null;
      var playlistUpdated3       =   false;
      var playlistFile3          =  'playlist_reload_3.xml';

      var lastModified4          =   null;
      var playlistUpdated4       =   false;
      var playlistFile4          =  'playlist_reload_4.xml';

      var lastModified5          =   null;
      var playlistUpdated5       =   false;
      var playlistFile5          =  'playlist_reload_5.xml';

      var lastModified6          =   null;
      var playlistUpdated6       =   false;
      var playlistFile6          =  'playlist_reload_6.xml';
    </script>

    <!-- inline script #2 - Concurrent AJAX -->
    <script type="text/javascript">
      //...From: http://www.hunlock.com/blogs/Concurrent_Ajax
      function ajaxObject(id, url)
      {
        var that       = this;
        var updating   = false;
        this.callback  = function() {}
        this.update    = function(passData)
        {
          if(updating == true)
          {
            return false;
          }
          updating = true;
          var AJAX = null;

          if(window.XMLHttpRequest)
          {
            AJAX = new XMLHttpRequest();
          }
          else
          {
            AJAX = new ActiveXObject("Microsoft.XMLHTTP");
          }

          if(AJAX == null)
          {
            alert("Your browser doesn't support AJAX.");
            return false;
          }
          else
          {
            AJAX.onreadystatechange = function()
            {
              if((AJAX.readyState == 4) || (AJAX.readyState == "complete"))
              {
                var lastModified = AJAX.getResponseHeader('Last-Modified');
                delete AJAX;
                updating = false;
                that.callback(returnId, lastModified);
              }
            }
            AJAX.open('HEAD', urlCall, true);
            AJAX.send(null);
            return true;
          }
        }
        var returnId = id;
        var urlCall  = url;
      };

      function checkFileUpdate()
      {
        for(j = 1; j < 7; j++)
        {
          window['fileUpdate' + j] = new ajaxObject(j, window['playlistFile' + j]);

          window['fileUpdate' + j].callback = function(id, lastModifiedTime)
          {
//alert('id: ' + id + '\nlastModified' + id + ': ' + window['lastModified' + id] + '\nlastModifiedTime: ' + lastModifiedTime);
            if((window['lastModified' + id] != null) && (window['lastModified' + id] != lastModifiedTime))
            {
              window['playlistUpdated' + id] = true;
if(instrumentation) gid('checkfile' + id).innerHTML = 'File' + id + ' was last modified on: ' + lastModifiedTime + '<br />playlistUpdated' + id + ': ' + window['playlistUpdated' + id];
            }
            else
            {
if(instrumentation) gid('checkfile' + id).innerHTML = 'File' + id + ' has not been modified since: ' + lastModifiedTime + '<br />playlistUpdated' + id + ': ' + window['playlistUpdated' + id];
            }

            window['lastModified' + id] = lastModifiedTime;

          };
          window['fileUpdate' + j].update();
        }
        setTimeout("checkFileUpdate()", 30000);
      };

      //...start loop timer
      setTimeout("checkFileUpdate()", 10000);
    </script>

    <!-- inline script #3 - Player API -->
    <script type="text/javascript">
      var player1       =  null;
      var player2       =  null;
      var player3       =  null;
      var player4       =  null;

      function playerReady(obj)
      {
        window['player' + obj.id.substr((obj.id.length -1), 1)] = gid(obj.id);

        if(player1 && player2 && player3 && player4)
        {
          player1.addModelListener('STATE', 'stateMonitor');
          player2.addModelListener('STATE', 'stateMonitor');
          player3.addModelListener('STATE', 'stateMonitor');
          player4.addModelListener('STATE', 'stateMonitor');
        }
      };

      function stateMonitor(obj)
      {
        var number = obj.id.substr((obj.id.length -1), 1);
//alert('stateMonitor - number: ' + number + '\nplaylistUpdated' + number + ': ' + window['playlistUpdated' + number]);
if(instrumentation) gid('state' + number + '1').innerHTML = 'Player' + number + ': ' + obj.newstate + '   Playlist' + number + ': ' + window['playlistFile' + number] + '?' + Math.round(1000 * Math.random());

        //...reload playlist on completion of current item only if playlist has been updated
        if((obj.newstate == 'COMPLETED') && (window['playlistUpdated' + number]))
        {
          gid(obj.id).sendEvent('STOP', 'null');
          gid(obj.id).sendEvent('LOAD', window['playlistFile' + number] + '?' + Math.round(1000 * Math.random()));
          gid(obj.id).sendEvent('PLAY', 'true');
          window['playlistUpdated' + number] = false;
        }
      };

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

    <!-- inline script #4 - Image Rotator API -->
    <script type="text/javascript">
      currentItem5      = null;
      currentItem6      = null;
      playlistLength5   = null;
      playlistLength6   = null;

      function getUpdate(typ, pr1, pr2, pid)
      {
        if(pid == 'imagerotatorId1')
        {
           if(typ == 'state')
           {
             var state = null;
if(instrumentation)
{
  switch(pr1){case 0:state='READY      ';break;case 1:state='BUFFERING';break;case 2:state='PLAYING    ';break;case 3:state='COMPLETED';break;};
//alert('pid: ' + pid + '\nstate: ' + state + '\ncurrentItem5: ' + currentItem5 + '\nplaylistLength5: ' + playlistLength5);
  gid('state111').innerHTML = 'Image Rotator1: ' + state + '   Playlist5: ' + playlistFile5 + '?' + Math.round(1000 * Math.random()) + '<br />playlistLength5: ' + playlistLength5;
}
             if((pr1 == 3) && (playlistUpdated5) && (currentItem5 == playlistLength5))
             {
               gid(pid).loadFile({file:playlistFile5 + '?' + Math.round(1000 * Math.random())});
               playlistUpdated5 = false;
               playlistLength5 = null;
             }
           }
           else if(typ == 'item')
           {
             currentItem5 = pr1;
             if(playlistLength5 < pr1)
             {
               playlistLength5 = pr1;
             }
           }
        }

        if(pid == 'imagerotatorId2')
        {
          if(typ == 'state')
          {
            var state = null;
if(instrumentation)
{
  switch(pr1){case 0:state='READY      ';break;case 1:state='BUFFERING';break;case 2:state='PLAYING    ';break;case 3:state='COMPLETED';break;};
  gid('state121').innerHTML = 'Image Rotator2: ' + state + '   Playlist5: ' + playlistFile6 + '?' + Math.round(1000 * Math.random()) + '<br />playlistLength6: ' + playlistLength6;
}
            if((pr1 == 3) && (playlistUpdated6) && (currentItem6 == playlistLength6))
            {
              gid(pid).loadFile({file:playlistFile6 + '?' + Math.round(1000 * Math.random())});
              playlistUpdated6 = false;
              playlistLength6 = null;
            }
          }
          else if(typ == 'item')
          {
            currentItem6 = pr1;
            if(playlistLength6 < pr1)
            {
              playlistLength6 = pr1;
            }
          }
        }
      };
    </script>

    <!-- inline script #5 - Players 1, 2, 3, and 4 - Image rotators 1 and 2  -->
    <script type="text/javascript">
      var flashvars =
      {
        'file':                          playlistFile1,
        'playlist':                     'bottom',
        'playlistsize':                 '60',
        'stretching':                   'exactfit',
        'repeat':                       'always',
        'shuffle':                      'false',
        'id':                           'playerId1',
        'autostart':                    'false'
      };

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

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

      swfobject.embedSWF(player_filename, 'player1', '400', '380', '9.0.124', false, flashvars, params, attributes);

      flashvars.file                  =  playlistFile2;
      flashvars.id                    = 'playerId2';

      attributes.id                   = 'playerId2';
      attributes.name                 = 'playerId2';

      swfobject.embedSWF(player_filename, 'player2', '400', '380', '9.0.124', false, flashvars, params, attributes);

      flashvars.file                  =  playlistFile3;
      flashvars.id                    = 'playerId3';

      attributes.id                   = 'playerId3';
      attributes.name                 = 'playerId3';

      swfobject.embedSWF(player_filename, 'player3', '400', '380', '9.0.124', false, flashvars, params, attributes);

      flashvars.file                  =  playlistFile4;
      flashvars.id                    = 'playerId4';

      attributes.id                   = 'playerId4';
      attributes.name                 = 'playerId4';

      swfobject.embedSWF(player_filename, 'player4', '400', '380', '9.0.124', false, flashvars, params, attributes);

      var flashvars =
      {
        'file':                          playlistFile5,
        'overstretch':                  'fit',
        'repeat':                       'always',
        'shuffle':                      'false',
        'enablejs':                     'true',
        'javascriptid':                 'imagerotatorId1',
        'autostart':                    'true'
      };

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

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

      swfobject.embedSWF(imagerotator_filename, 'imagerotator1', '400', '320', '9.0.124', false, flashvars, params, attributes);

      flashvars.file                  =  playlistFile6;
      flashvars.javascriptid          = 'imagerotatorId2',

      attributes.id                   = 'imagerotatorId2';
      attributes.name                 = 'imagerotatorId2';

      swfobject.embedSWF(imagerotator_filename, 'imagerotator2', '400', '320', '9.0.124', false, flashvars, params, attributes);
    </script>

  </head>

  <body>

    <div id="playercontainer1" class="playercontainer1">
      <a id="player1" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="playercontainer2" class="playercontainer2">
      <a id="player2" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="playercontainer3" class="playercontainer3">
      <a id="player3" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="playercontainer4" class="playercontainer4">
      <a id="player4" class="player" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="imagerotatorcontainer1" class="imagerotatorcontainer1">
      <a id="imagerotator1" class="imagerotator" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <div id="imagerotatorcontainer2" class="imagerotatorcontainer2">
      <a id="imagerotator2" class="imagerotator" href='http://www.macromedia.com/go/getflashplayer'>Get the Adobe Flash Player to see this player.</a>
    </div>
    <!-- instrumentation -->
    <div id="datapc1" class="datapc1">
      <div id="checkfile1">
         
        <br />
         
      </div>
      <div id="state11">
      </div>
    </div>
    <div id="datapc2" class="datapc2">
      <div id="checkfile2">
         
        <br />
      </div>
      <div id="state21">
      </div>
    </div>
    <div id="datapc3" class="datapc3">
      <div id="checkfile3">
         
        <br />
         
      </div>
      <div id="state31">
      </div>
    </div>
    <div id="datapc4" class="datapc4">
      <div id="checkfile4">
         
        <br />
         
      </div>
      <div id="state41">
      </div>
    </div>
    <div id="datair1" class="datair1">
      <div id="checkfile5">
         
        <br />
         
      </div>
      <div id="state111">
      </div>
    </div>
    <div id="datair2" class="datair2">
      <div id="checkfile6">
         
        <br />
         
      </div>
      <div id="state121">
      </div>
    </div>
    <!-- testing -->
    <button onclick="checkFileUpdate();">checkFileUpdate</button>

  </body>

</html>

Thanks! I will try it out and let you know how it goes.

Thanks for posting that code LefTy. It appears to work but I am seeing some strange behavior:

The players are not reloading the playlist consistently. Sometimes they will reload in a few mins. Sometimes it will take 30+ mins. If I update multiple playlists at the same time, they get reloaded at different times...sometimes 30+ mins apart. I have recreated this in Firefox 2, Firefox 3, Opera 9.6 and Internet Explorer 7.

Overstretch "fit" is also behaving differently in different browsers. On Firefox 3 it is shrinking an image down to maintain the ratio rather than resizing it to fit the container. In Opera 9.6 and IE 7 it is working fine (resizing an image so it fits the container). It is also working fine in Firefox 2.

The instrumentation function in Firefox 2 is putting the player information under the player/imagerotator so you cant see it. It works fine in other browsers.

Thanks for your continued help with this. I am learning a lot from your code and hope it is beneficial to others as well.

1) The browsers can be very persistent in caching playlists, so we need to use the "add a random number" trick to force the browser to make a fresh request to the server.

      function checkFileUpdate()
      {
        <strong>var rnd = '?' + Math.round(1000 * Math.random());</strong>

        for(j = 1; j < 7; j++)
        {
          <strong>window['fileUpdate' + j] = new ajaxObject(j, (window['playlistFile' + j] + rnd));</strong>

          window['fileUpdate' + j].callback = function(id, lastModifiedTime)
          {
//alert('id: ' + id + '\nlastModified' + id + ': ' + window['lastModified' + id] + '\nlastModifiedTime: ' + lastModifiedTime);
            if((window['lastModified' + id] != null) && (window['lastModified' + id] != lastModifiedTime))
            {
              window['playlistUpdated' + id] = true;
if(instrumentation) gid('checkfile' + id).innerHTML = 'File' + id + ' was last modified on: ' + lastModifiedTime + '<br />playlistUpdated' + id + ': ' + window['playlistUpdated' + id];
            }
            else
            {
if(instrumentation) gid('checkfile' + id).innerHTML = 'File' + id + ' has not been modified since: ' + lastModifiedTime + '<br />playlistUpdated' + id + ': ' + window['playlistUpdated' + id];
            }

            window['lastModified' + id] = lastModifiedTime;

          };
          window['fileUpdate' + j].update();
        }
        setTimeout("checkFileUpdate()", 30000);
      };

2) The Image Rotator overstretching issue.
From: http://developer.longtailvideo.com/trac/wiki/Flashvars3#Displayappearance

"overstretch (false): Sets how to stretch images/movies to make them fit the display. The default stretches to fit the display. Set this to true to stretch them proportionally to fill the display, fit to stretch them disproportionally and none to keep original dimensions."

You might experiment with a single Image Rotator on a separate page to get the overstretching behavior correct. It has always worked well unless your images are huge (over 4096px if I remember correctly) and Flash doesn't like progressively encoded images and some images saved from PhotoShop (I don't know the configuration) don't stretch correctly, so try a different graphics editor if you happen to be using PhotoShop.

3) The instrumentation display is straightforward CSS. Overlaying on Flash requires:
a) wmode=opaque (Adobe Flash Player parameter)
b) position:absolute; (CSS - sometimes relative is OK)
c) z-index:1 (CSS - higher z-index than the player, which is at 0)
Other than those three items, I don't know of anything that would prevent the instrumentation from being displayed overlaid on the player. You might do some Googling for "CSS z-index Firefox" to see if there are any other issues with Firefox and the CSS z-index. It's always worked OK for me.

LefTy,
the "add random number" trick seems to have worked. I am able to get the playlists to refresh regularly now.

I was able to resolve the image rotator sizing issues by adding the following flashvars:

'width':                        '400',
'height':                       '320',

I was not able to find a good solution for the z-index issue I am seeing in firefox2. I was able to work around it by temporarily modifying the containers to
position:              fixed;
This allows me to temporarily see the instrumentation info.

I am seeing another strange issue with media player. I am finding the the player is crashing on me occasionally. Instrumentation shows that it is stuck in a buffering state. This usually happens when my playlist has back to back .flv files. If i put an image file in my playlist between .flv files it seems to play ok. Do you know what might be causing this?

Thanks for the help!

Hey LefTy,

Not sure if you saw this post or not. Your help would be greatly appreciated.

Thanks!

@ss,

Sorry, I didn't see your post.

Player gets stuck on back-to-back FLV files.

I'll check into this.

Do you have a test page that I can see?

LefTy,

I put up a test page for you to look at:
http://71.193.100.222/lefty/mpandir.html

MediaPlayer1 has no back-to-back .flv files and plays fine. MediaPlayer2 and MediaPlayer3 have back-to-back .flv files somewhere in the playlist. The player gets stuck in a buffer state as soon as the back-to-back .flv is played.

MediaPlayer4 only has image files and works fine. ImageRotator1 and ImageRotator2 work fine.

A few other strange things I am seeing:

When a new playlist is loaded for a MediaPlayer, the player doesn't start playing from the first item in the playlist. It starts playing somewhere in the middle of the playlist.

When a playlist has both image and .flv files and a .flv file is playing, it momentarily shows the last frame of the last .flv file that was played before it starts playing the current .flv file. Its as if the last frame of the last .flv file that was played is in the buffer?

I would like to use Lighttpd but have not been able to get this to work on there. I don't think Lighttpd is returning Last-Modified response headers. I saw some comments in your code indicating that maybe you had the same problem? Any idea on how to get this to work on Lighttpd?

Thanks for your help!

 
I've been playing back-to-back FLV files with no problem. Are any of the files repeats? IE's caching "feature" may be causing a delay.

The player does "remember" the previous index when you load a new playlist. The simple way to fix that is to send a:player.sendEvent('ITEM', 0); after it reports the playlist loaded by calling the PLAYLIST Listener function. I'll add that code.

Jeroen will have to fix the player showing the last frame of the last FLV. It's been reported before.

I haven't figured out how to get LightTPD to send the Last-Modified header on an AJAX call. It works with cURL or a normal browser or wget call, just not with AJAX. I have successfully used both Apache2 and nginx as the server. In my test code, I'm dumping all of the headers and Last-Modified simply isn't there. I just installed LightTPD-1.4.21 from WLMP so I'll keep working on LightTPD.

I'll check your test page for the back-to-back problem.

 
The page now has indexing to 0 when the playlist is re-loaded.

      http://willswonders.myip.org:8082/Automatic Reload 4 Players 2 Rotators.html

The "stalling" was being caused by Internet Explorer's caching "feature". Once a video has been downloaded and is in the browser's cache, the next time it is viewed, the browser fully loads the video from the cache before it will play, thus what looks like stalling.

To workaround the caching "feature", you have to append a random number to the playlist, which we were already doing, and you have to append a random number to each file in the playlist, which I added. The one thing I still need to add, is to add a random number to the files in the initial playlist, in case it is replayed.

Thanks for working on this LefTy. I checked out the page you setup but haven't tried to incorporate it into my page yet. I will wait for you to post the code that takes care of the caching feature.

I was doing my tests mostly in firefox since that is what I will be using. When my player got stuck in the buffering state, it never got out of it. If I understand what you are saying about your experience with IE, the player would buffer the whole video file first and then start playing. This never happened for me in my tests. It would get stuck until you refresh the page and then get stuck at the same point in the playlist again.

I was researching the Last-Modified header in Lighttpd and came across this:
http://redmine.lighttpd.net/issues/1236

Is this the problem we are experiencing? If so, it appears as if it is by design and they don't have any plans to "fix" it. There was a workaround posted there but it didn't work for me. I was getting errors after implementing it and was not able to start the lighttpd server.

Thanks!

LightTPD seems to be full of these "features", so I'm not using it anymore.

Apache2 and nginx respond correctly. nginx is much faster and also sends the start parameter in the X-Sendfile header so it's useful for FLV/H.264 streaming with the streaming modules. I just need to find a Windows build with the modules or figure out how to compile it myself or setup a Linux video server (most likely)

The demo page has the IE "cache-busting" code now; I'll test it in Firefox...

Demo pages ...served by nginx

http://willswonders.myip.org:8082/Automatic Reload 4 Players 2 Rotators.html

http://willswonders.myip.org:8082/Automatic Reload 4 Players 2 Rotators No Playlist Display.html

Hi lefTy,

Sorry I didn't get a chance to respond until now. I had my appendix removed and have been trying to recover.

I tried to use your source code but am seeing the following problems:

All four instances of Media Player are using playlist_reload_4.xspf (even though in the code it says to use playlist_reload_1.xspf - playlist_reload_4.xspf.)

I am seeing the same issue with the two instances of Image Rotator. Both instances are using playlist_reload_6.xspf (instead of playlist_reload_5.xspf and playlist_reload_6.xspf)

Your demo pages are not working any more so I couldn't compare it with your pages.

I have posted a demo page for you to look at:
http://71.193.100.222/lefty/mpandir2_1.html

Another issue I have noticed but haven't been able to fully test is that the page crashes the browser in IE8/Vista, Firefox3.5/Vista. It appears to run ok in IE7/XP, Firefox3.5/Ubuntu.

Thanks!

Sorry to hear about your illness. I hope you are getting well now.

I moved the demo to: http://willswonders.myip.org:8083/Automatic Reload 4 Players 2 Rotators.html

I checked the code and the server logs. Each player/rotator is using it's own playlist.

Later today/tonight, I'll check your test page.

Hi LefTy,

I'm not sure if you got a chance to look at my test page or not. I was looking at your page again and noticed you might have made some updates (your page now shows pop up messages when a new playlist is loaded).

I created a new test page and am having the same problems:

All four instances of Media Player are using playlist_reload_4.xspf (even though in the code it says to use playlist_reload_1.xspf - playlist_reload_4.xspf.)

I am seeing the same issue with the two instances of Image Rotator. Both instances are using playlist_reload_6.xspf (instead of playlist_reload_5.xspf and playlist_reload_6.xspf)

I am using Ubuntu/Apache server.
player-4.4.162
I am using xspf playlists

My latest test page can be found at:
http://71.193.100.222/lefty/mpandir2_2.html

Thanks!