I'm trying to implement moving the time frame by frame, so precise control is very important. After getting some strange results, I've discovered something weird behaviour when setting time via .input.time or .input.position...
When time is set while video is paused, VLC for some reason moves it 15 milliseconds AHEAD of the set value!!
And that's not all, it does so around 200-400 milliseconds later (when frame is redrawn)!!
At first I thought VLC is just aligning the time to mid-frame values, but after testing this with videos at 15, 10 and 2 fps, that's not true. Even time values 'aligned' by VLC aren't 'safe' - when passed to .input.time, VLC always adds 15 ms!
his creates some problems... For example, it's imposible to set time to 0ms via .input.time (not a big deal). I'm also woring on a workaround of cross-browser player event handling and that time jumping complicates things a bit...
Tested with IE7, Firefox, Chrome and Safari (Win).
Someone noticed this earlier? Will this be fixed anytime soon? Thank you in advance.
I've prepared a test page (change YOUR_MEDIA_PATH variable to your local media file if you want).
Code: Select all
<html>
<head><title>VLC Plugin Time Bug(?)</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript">
var YOUR_MEDIA_PATH = "D:/movies/test.avi"; // Change this, if you want
jQuery(function($)
{
// Get VLC element
window.vlc = $('#VLC').get(0);
$("#path").val(YOUR_MEDIA_PATH);
// ----------------
function liveStatsCallback()
{
var msg = "";
try
{
msg =
"Current time: " + vlc.input.time + "<br/>" +
"Current frame: " + (vlc.input.time / (1000.0 / vlc.input.fps)).toFixed(3) + "<br/>" +
"FPS: " + vlc.input.fps + "<br/>" +
"Length: " + vlc.input.length + "<br/>" +
"State: " + vlc.input.state + "<br/>" +
"";
}
catch (e)
{
msg = "Error: " + e;
}
$("#info").html(msg);
};
var liveStatsIntervalId = null;
$("#liveStats").click(function()
{
if (liveStatsIntervalId !== null)
{
clearInterval(liveStatsIntervalId);
liveStatsIntervalId = null;
}
else
{
liveStatsIntervalId = setInterval(liveStatsCallback, 200);
}
$("#info").css("backgroundColor",
(this.checked = (liveStatsIntervalId !== null)) ? "yellow" : "#BBB");
}) .triggerHandler('click');
// -------------
$("#play").click(function()
{
try
{ vlc.playlist.playItem(vlc.playlist.add($("#path").val())); }
catch (e)
{ alert("Play : " + e); }
});
// --------------
$("#pause").click(function()
{
try
{ vlc.playlist.togglePause(); }
catch (e)
{ alert("Pause : " + e); }
});
$("#justMove").click(function()
{
var timeVal = parseInt($("#targetTime").val());
try
{
vlc.input.time = timeVal;
liveStatsCallback();
}
catch (e)
{ alert("JustSet: " + e); }
});
// -----------
$('#moveAndTest').click(function()
{
var vlc = window.vlc;
if (!vlc) return;
var timeVal = parseInt($("#targetTime").val());
var startTime = (new Date()).getTime();
var testLen = 1000;
var testCount = 0;
var changeTime = 0;
var newTime = 0;
try {
vlc.input.time = timeVal; // Set the time
// Now wait for a magical change for a second...
for (; (changeTime = ((new Date()).getTime() - startTime)) < testLen; testCount++)
{
if (timeVal != (newTime = vlc.input.time))
{
alert("Something's wrong!\n\n" +
"Entered: \t" + timeVal + "\n" +
"Changed to: \t" + newTime + "\n" +
"Difference: \t" + (newTime - timeVal) + " ms\n" +
"\n" +
"Change after:\t" + changeTime + " ms" +
" (" + testCount + " iterations)");
return;
}
}
} catch(e)
{
alert("Test : " + e);
return;
}
alert("Nothing changed after 1000ms and " + testCount + " tests!");
});
});
</script>
</head>
<body>
<script type="text/javascript">
var MEDIA_WIDTH = 400;
var MEDIA_HEIGHT = 300;
if (jQuery.browser.msie)
{
document.write(
'<object ' +
'id="VLC" ' +
'codeBase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab" ' +
'classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921" ' +
'height="' + MEDIA_HEIGHT + '" width="' + MEDIA_WIDTH + '" ' +
'autoplay="yes" ' +
' > </object>');
}
else
{
document.write(
'<embed ' +
'id="VLC" ' +
'type="application/x-vlc-plugin" ' +
'pluginspage="http://www.videolan.org\" ' +
'version="VideoLAN.VLCPlugin.2" ' +
'autoplay="yes" loop="no" hidden="no" ' +
'width="' + MEDIA_WIDTH + '" height="' + MEDIA_HEIGHT + '" ' +
' />' );
}
</script>
<div style="padding: 8px;">
Media path
<input type="text" value="D:/movies/test.avi" style="width: 400px;" id="path"/>
<input type="button" id="play" value="Play"/>
<input type="button" id="pause" value="Pause"/>
</div>
<div style="padding: 8px;">
Enter target time
<input type="text" id="targetTime" value="0" />
<input type="button" id="justMove" value="Just Move"/>
<input type="button" id="moveAndTest" value="Move and Test"/>
</div>
<div>
<input type="checkbox" id="liveStats" checked="checked" />
<label for="liveStats"> Enable Live Stats</label>
</div>
<div id="info" style="border: 1px solid black; background: #BBB; margin: 8px 2px; padding: 8px;"></div>
<div style="background: #DDD; font-size: small; padding: 8px; margin: 4px 2px;">
<h3>Help</h3>
<ol>
<li>Enter correct media path</li>
<li>Press "Play" open it</li>
<li>Press "Pause" </li>
<li>Enter time value (milliseconds)</li>
<li>Press "Move and Test" or "Just Move" and observe stats</li>
</ol>
</div>
</body>
</html>