We run a red5 server inside the firewall, and mostly it works quite well for the number of users so far. We usually stream short clips, but recently have started using longer ones. We keep the data rate down around 300 kbps and put keyframes every 10 frames. Once in a while we get a long video and it's never been a problem until now. We're using player 4.6.485.
The problem happened when we attempted to break a 1-hour long video into chapters using "start" and "duration" settings in a playlist. The last 2 chapters absolutely would not play beyond the first several seconds. I had the video author re-output the video several times, and I re-encoded it using several different tools. I also tried the metadata injector. No matter what we tried, the last 2 segments would play for a bit, then in the console you will see Buffer.Empty and the video stops. You just see the buffering icon twirling forever.
TIME ({duration:3460, position:3344.5})
META ({level:status, code:NetStream.Buffer.Empty})
We solved the problem by NOT using the built in playlist. Instead we constructed one using javascript based on tips elsewhere in this forum. The entire video now plays fine, although Safari tends to skip ahead if I set the bufferlength to "0", so I keep it at "2". Then all browsers are happy. I don't have an external red5 server to demonstrate this with, but if someone wants to lend one, I'll put the problem video on it and hook up a working demo.
Working code:
<div id="rightColumn">
<div id="subTitleBar">
<div align="right"><span id="pageNumberHolder"></span> <a href="javascript:window.print()" id="printIcon"><img src="images/images.jpg" alt="print this page" /></a> </div>
</div>
<div id="content">
<!--*********************put content below this line!!!!************-->
<table width="100%" border="0" id="contenTable" cellpadding="0" cellspacing="0">
<tr>
<td valign="top" class="col1"><h1>chapters</h1>
</td>
</tr>
<tr>
<td valign="top">
<script type="text/javascript">
var player=document.getElementById('player');
var seek = 0;
var seekFlag = false;
var currentTime;
function gid(name) {
return document.getElementById(name);
};
var flashvars =
{
fullscreen: 'true',
resizing: 'true',
width: '476',
height: '288',
backcolor: '#111111',
frontcolor: '#999999',
lightcolor: '#66cc00',
playlist: 'none',
repeat: 'none',
shuffle: 'false',
icons: 'false',
bufferlength: '2',
autostart: 'false',
stretching: 'fill',
skin: 'includes/mediaplayer4.5/modieus.swf',
oncomplete: 'none',
file: 'mpegStreamclipOutput.flv',
streamer: 'rtmpt://red502.mcit.med.umich.edu:80/oflaDemo/lms/measuringsuccess',
debug: 'console'
};
var params ={
allowscriptaccess: 'always',
allowfullscreen: 'true',
bgcolor: '#000000'
};
var attributes ={
id: 'player',
name: 'player'
};
swfobject.embedSWF('includes/jw_media_player/player-licensed.swf', 'player', '600', '310', '9.0.124', false, flashvars, params, attributes);
</script>
<script type="text/javascript">
function playerReady(obj) {
//alert(gid(obj));
player = gid('player');
player.addModelListener('TIME', 'timeMonitor');
};
//function loadFile(theFile){ player.sendEvent('LOAD',theFile); };
function timeMonitor(obj)
{
//alert('in timeMonitor');
if((obj.position > 0) && (seekFlag))
{
seekFlag = false;
player.sendEvent('SEEK', seekto);
}
currentTime = obj.position;
};
function seekSome(seconds, id)
{
// alert(player);
seekto = seconds;
if(currentTime > 0)
{
//alert('currentTime > 0');
player.sendEvent('SEEK', seekto);
makeCurrent(id);
}
else
{
// alert('currentTime <= 0');
seekFlag = true;
makeCurrent(id);
player.sendEvent('PLAY', 'true');
}
};
function makeCurrent(selectedLayer){
// Written By: WillyDuitt@hotmail.com || 03-22-2005 \\;
var links = getElementsByClass(document, 'navbtn', 'a');
for(var i=0; i<links.length; i++){
links[i].className = 'navbtn';
}
// alert(selectedLayer);
gid(selectedLayer).className = 'navbtn current';
};
function gid(name) { return document.getElementById(name); };
</script>
<a id="player" name="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>
</td>
<td valign="top" class="col1">
<div id="subnav" style="height:309px;overflow:auto;">
<h2>Jump to</h2>
<a href="javascript:seekSome('0', 'int');" id="int" class="navbtn">Introduction</a>
<a href="javascript:seekSome('312', 'q4u')" id="q4u" class="navbtn">Questions for you</a>
<a href="javascript:seekSome('439', 'why')" id="why" class="navbtn">Why Measure?</a>
<a href="javascript:seekSome('651','cst')" id="cst" class="navbtn">Cost</a>
<a href="javascript:seekSome('875','stk')" id="stk" class="navbtn">Stakeholders</a>
<a href="javascript:seekSome('915','msr')" id="msr" class="navbtn">Measure What?</a>
<a href="javascript:seekSome('1021','rca')" id="rca" class="navbtn">Root Cause Analysis</a>
<a href="javascript:seekSome('1395','bsl')" id="bsl" class="navbtn">Baseline & Audit Data]</a>
<a href="javascript:seekSome('1580','aud')" id="aud" class="navbtn">3 Audit Types</a>
<a href="javascript:seekSome('1896','cse')" id="cse" class="navbtn">A Case Study</a>
<a href="javascript:seekSome('2138','whn')" id="whn" class="navbtn">When to Measure</a>
<a href="javascript:seekSome('2344','lvl')" id="lvl" class="navbtn">4 Learning Levels</a>
<a href="javascript:seekSome('2525','chl')" id="chi" class="navbtn">Children & Adults</a>
<a href="javascript:seekSome('2627','stc')" id="stc" class="navbtn">Sticky Learning</a>
<a href="javascript:seekSome('3250','cnc')" id="cnc" class="navbtn">Conclusion</a>
<a href="javascript:seekSome('3342','crd')" id="crd" class="navbtn">Credits</a>
</div>
</td>
</tr>
</table>
<!--*********put content above this line!!!!!*****-->
</div><!--end content-->
</div><!--end rightColumn-->
Non-working code:
<script>
function showNavbar(){
document.getElementById('whiteArea').style.background = 'url(images/whiteArea2shadows.jpg)';
document.getElementById('leftColumn').style.display = 'block';
document.getElementById('leftColumn').className = 'leftColumnOpen';
document.getElementById('subTitleBar').style.visibility = 'visible';
}
</script>
<script type="text/javascript">
var flashvars = {
resizing: 'true',
backcolor: '#00487a',
frontcolor: '#dff0fb',
playlist: 'right',
playlistsize: '200',
shuffle: 'false',
icons: 'true',
bufferlength: '2',
autostart: 'false',
debug: 'console',
repeat: 'list',
stretching: 'exactfit',
file: 'media/playlist_10-5.xml',
streamer: 'rtmpt://red502.mcit.med.umich.edu:80/oflaDemo/lms/measuringsuccess/'
};
var params =
{
allowscriptaccess: 'always',
allowfullscreen: 'true',
bgcolor: '#000000'
};
var attributes =
{
id: 'player',
name: 'player'
};
swfobject.embedSWF('includes/jw_media_player/player-licensed.swf', 'player', '898', '413', '9.0.124', false, flashvars, params, attributes);
//function loadFile(theFile){ player.sendEvent('LOAD',theFile); };
// -->
</SCRIPT>
....
<a id="player" name="player" class="player" href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash"><img src="media/poster001.jpg"/>Get the Adobe Flash Player to see this video.</a>
Playlist to go with non-working code:
<?xml version="1.0" encoding="utf-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
<trackList>
<track>
<title>Introduction</title>
<creator>zzzz</creator>
<annotation>zzzzzzz</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">0</meta>
<meta rel="duration">311</meta>
</track>
<track>
<title>Questions for you</title>
<annotation>...and for me.</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">312</meta>
<meta rel="duration">438</meta>
</track>
<track>
<title>Why Measure?</title>
<annotation>Is it worth it?</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">439</meta>
<meta rel="duration">650</meta>
</track>
<track>
<title>Cost</title>
<annotation>Learning as an investment</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">651</meta>
<meta rel="duration">869</meta>
</track>
<track>
<title>Stakeholders</title>
<annotation>Who benefits?</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">875</meta>
<meta rel="duration">914</meta>
</track>
<track>
<title>Measure What?</title>
<annotation>Define the problem.</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">915</meta>
<meta rel="duration">1020</meta>
</track>
<track>
<title>Root Cause Analysis</title>
<annotation>Drilling down</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">1021</meta>
<meta rel="duration">1394</meta>
</track>
<track>
<title><![CDATA[Baseline & Audit Data]]></title>
<annotation>Gather evidence</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">1395</meta>
<meta rel="duration">1579</meta>
</track>
<track>
<title>3 Audit Types</title>
<annotation>What works for you?</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">1580</meta>
<meta rel="duration">1895</meta>
</track>
<track>
<title>A Case Study</title>
<annotation>The "rage to conclude"...</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">1896</meta>
<meta rel="duration">2137</meta>
</track>
<track>
<title>When to Measure</title>
<annotation><![CDATA[Retrieval & retention]]></annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">2138</meta>
<meta rel="duration">2343</meta>
</track>
<track>
<title>4 Learning Levels</title>
<annotation>The Kirkpatrick model</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">2344</meta>
<meta rel="duration">2524</meta>
</track>
<track>
<title><![CDATA[Children & Adults]]></title>
<annotation><![CDATA[Pedagogy & Andragogy]]></annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">2525</meta>
<meta rel="duration">2626</meta>
</track>
<track>
<title>Sticky Learning</title>
<annotation>6 Concrete examples</annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">2627</meta>
<meta rel="duration">3249</meta>
</track>
<track>
<title>Conclusion</title>
<annotation> </annotation>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">3250</meta>
<meta rel="duration">3341</meta>
</track>
<track>
<title>Credits</title>
<location>mpegStreamclipOutput.flv</location>
<type>rtmp</type>
<meta rel="start">3342</meta>
<meta rel="duration">3460</meta>
</track>
</trackList>
</playlist>
I'm aware this may be a red5 problem, but it's odd that it worked with the javascript playlist and not the flash one. I'll post it over on the red5 list also.
Ellen
I'm seeing the v4.6.485 player skip the next-to-last track, oh, about 90% of the time, and that's on HTTP progressive. Swapping tracks around seems to have changed the issue, but there isn't any consistency to it that I can see yet...