Name is required.
Email address is required.
Invalid email address
Answer is required.
Exceeding max length of 5KB

seek() before video starts


If I try to seek before starting video playback, it starts playing, but doesn't go to the requested seek point.

I can probably work around this via external code, but was wondering if this is intended behavior or not.

16 Community Answers

JW Player

User  
0 rated :

Seeking only works within the already downloaded portion of the media file unless you have a streaming server that can receive requests to seek into the media file on the server.

See the Tutorial *"HTTP Video Streaming"* at the top of this page.

JW Player

User  
0 rated :

Sorry for not stating it before hand, but I have streaming already working w/ lighttpd, seeking works exactly as it should once the video has started playing once.

Steps to reproduce:
) Load video in jw player WITHOUT autoplay
) Avoid starting playback of the video
) attempt to seek via javascript API call
Result:
Video starts playing from beginning
Future attempts to seek via JS api work fine

JeroenW

JW Player Support Agent  
0 rated :

A seek before start will not work, since the first part of the video (with the metadata) always has to be loaded first.

JW Player

User  
0 rated :

Hello guys.

I have the same problem as Bob. I know that it is impossible to seek before start video as Jeroen said. But, can we use some trick to make it works?

What i need... I have one video on page and few links to start plying this video from some part. All works ok after video is started first. But i need to give ability to starting playing video from some part. I am using JS API so maybe there is some trick to make it works somehow. Maybe we can add some command to JS function for starting playing parts which allow to seek with first time (starting video first and next seek to needed position). Is this possible? I tried few solutions but no success yet.

Jeroen, what you think about that? :)

JW Player

User  
0 rated :

@Tom,

Generally what you do in this situation is start the player, when the position reported is > 0 (meaning the video has started playing), you pause the video, then seek. I usually mute the audio before starting the player and unmute after the seek to avoid the audio glitch that can occur during the few tenths of a second that the video is playing when you first start it.

This may not be exactly right for your use, but you can see the basic process:bc.. <!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01//EN""http://www.w3.org/TR/html4/strict.dtd">

<htmllang="en">

<head>

<title>ScrubFirstView-JWMPv4.2.x-swfobjectv2.1</title>

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

<scripttype="text/javascript">
varplayer=null;
varseek=true;
varpause=true
//varstart=<?phpecho$start_secs;?>;
varstart=20;
varloaded=start*90000


functionplayerReady(obj)
{
player=gid(obj.id);
player.addModelListener('LOADED','loadedMonitor');
};


functionloadedMonitor(obj)
{
gid('loaded').innerHTML='Loaded:'+obj.loaded;

if(seek==true)
{
if((obj.loaded>0)&&(pause==true))
{
player.sendEvent('PLAY','false');
pause=false;
}
elseif(obj.loaded>loaded)
{
player.sendEvent('SEEK',start);
player.sendEvent('MUTE','false');
seek=false;
}
}
};


functiongid(name)
{
returndocument.getElementById(name);
};
</script>

<scriptlanguage="JavaScript"type="text/javascript">
varflashvars=
{
//streamer:'http://domain/xmoov.php',
//file:'showmy.flv',
file:'BubbleMovie.flv',
shuffle:'false',
repeat:'always',
stretching:'uniform',
mute:'true',
autostart:'true'
};

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

varattributes=
{
id:'playerId',
name:'playerId'
};

swfobject.embedSWF('player-4.2.87.swf','player','440','270','9.0.124',false,flashvars,params,attributes);
</script>

</head>

<body>

<divid="playercontainer"class="playercontainer">
<aid="player"class="player"href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">GettheFlashPlugintoseethisvideo.</a>
</div>
<divid="loaded">
</div>

</body>

</html>


JW Player

User  
0 rated :

Sorry for late response.

After looking at my code again I realized that I was manually starting the video if a seek was requested before playback had started.

I ended up implementing a way to queue up a 'one time event' for specific STATE changes, so my workaround code ends up working like this (using the framework I whipped up):

) seek occurs
) If play back hasn't started, queue up a 'one time event' for 'PLAYING' state change.
) one time event has an associated function literal that tells jw player to seek to specified time.
) Tell jw player to start playback

some time later:

) a stateEventListener recieves a state event.
) find a one time event in state queue with a targetState == newState of state event.
) execute associated function literal.
) function literal performs seek.

Might be overly complicated for other people's needs but should be a decent foundation if I need to do something similar again.

JW Player

User  
0 rated :

hi Bob,

could you post your solution? I'm about to write sth like this myself, but since you've already done it... ;)

JW Player

User  
0 rated :

I ended up w/ something similar to this (not verbatim from my code because it was encapsulated in some utility classes):

And sorry, can't seem to get indenting to display properly.

bc.. // Potentially encapsulate in your player utility class

oneTimeStateEvents = [];

function addOneTimeStateEvent(playerId, targetState, f) {
var e = {
playerId: playerId // ID of player
, targetState: targetState // State to trigger on
, f: f // Function to execute
};
oneTimeStateEvents.push(e);
}

function stateEventListener(info) {
for (var i = 0; i < oneTimeStateEvents.length; ) {
var e = oneTimeStateEvents[i];
// id doesn't appear to be properly set in incoming event objects?
//if (e.playerId == info.id && e.targetState == info.newstate ) {
if (e.targetState == info.newstate ) {
oneTimeStateEvents.splice(i,1); // remove event
e.f();
continue;
}
i++;
}
}

// Potentially encapsulate in your player class

player.addModelListener('STATE', 'stateEventListener');

function seek(time) {
var state = player.getConfig()['state'];
if (state == 'IDLE') {
// Create a one time event to seek once playback starts
addOneTimeStateEvent(playerId,'PLAYING',
function() {
player.sendEvent('SEEK',time);
});
player.sendEvent('PLAY', true);
}
else {
if (state == 'STOPPED') {
player.sendEvent('PLAY', true);
}
player.sendEvent('SEEK', time);
}
}

JW Player

User  
0 rated :

I have a similar problem that only comes up with the new 4.2 version. I am currently using 4.1 player and this works fine:
sendEvent("LOAD", filename");
sendEvent("SEEK", currentTime);

I do this to swap between high and low quality versions of the file in case their internet connection is poor.
It works with 4.1 but when I try the 4.2 player it just goes back to the beginning.

I think this is a bug? Any way around it? I maybe could put a little timeout between the load and seek parts but that seems like a hack.
Thanks

JW Player

User  
0 rated :

The proper way to do this would be to setup a TIME listener and set a load flag.

Then if the load flag is true and the TIME obj.position > 0 (indicating that the file has loaded and is starting to play), do the seek and reset the load flag.

JW Player

User  
0 rated :

I tried this but have to put in a timeout or it doesn't work for some reason?? Also it needs a longer timeout if it's on a slower internet connection and takes a while to load the video. Do you know why this is? It worked fine on the older versions...

JW Player

User  
0 rated :

Hello,

i've several problems with the SEEK function too, but if there would be a SEEK_AND_PLAY( time ) function, it would be the best.
i think, this player shoulb be able to handle the following problems:
- seek in a newly loaded video (like in the start flashvar)
- seek and play from any state (paused, stopped, etc)

Can anybody help to write the SEEK_AND_PLAY functionality?

Thanks,
Tamas

JW Player

User  
0 rated :

Most good players have the ability to seek and start playing at any point no matter if the video is loaded or not. Are there any plans for implementing this?

JW Player

User  
0 rated :

@Alex,

Name one Flash-based player that can seek and start without server support or else you're just trolling.

JW Player

User  
0 rated :

Sure it can.

The JW FLV Media Player can use pseudostreaming with a script or the streaming modules for nginx, LightTPD, and Apache.

Or it can use a real streaming RTMP server like Wowza, Flash Media Server, or Red5.

Or you can use ffmpeg to transcode on-the-fly.

ALL provide almost instant seeking.

JW Player

User  
0 rated :

there's a new kid on the block: Adobe Open Source Media Framework. I just tried implementing the following use case:

Having progressive video, I want the player to start loading in and when enough has loaded, jump to a certain time in the video. This was not easy with JW Player. With OSMF I did it the day I downloaded the code for the first time :)

bc.. <?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:players="com.adobe.strobe.players.*"
layout="vertical"
minWidth="1024" minHeight="768"
creationComplete="creationCompleteHandler()" >

<mx:Script>
<![CDATA[
import org.openvideoplayer.media.MediaPlayerState;
import mx.utils.ObjectUtil;
import org.openvideoplayer.events.MediaPlayerStateChangeEvent;
import org.openvideoplayer.events.MediaPlayerCapabilityChangeEvent;
import org.openvideoplayer.events.DurationChangeEvent;
import org.openvideoplayer.display.MediaPlayerSprite;
import mx.core.UIComponent;
import org.openvideoplayer.media.MediaPlayer;
import org.openvideoplayer.utils.URL;
import org.openvideoplayer.media.URLResource;
import org.openvideoplayer.net.NetLoader;
import org.openvideoplayer.video.VideoElement;
import mx.events.FlexEvent;

// private static const REMOTE_PROGRESSIVE : String = "http://mediapm.edgesuite.net/strobe/content/test/AFaerysTale_sylviaApostol_640_500_short.flv";
private static const REMOTE_PROGRESSIVE : String = "http://videocdn.reuters.com/20090809/ftpo1235901116262.flv";
private var player : MediaPlayer;

protected function creationCompleteHandler() : void {
createPlayer();
}

private function createPlayer() : void {
player = new MediaPlayer();
var playerSprite : MediaPlayerSprite = new MediaPlayerSprite( player );
var comp : UIComponent = new UIComponent();
comp.addChild( playerSprite );
addChild( comp );
playerSprite.width = 320;
playerSprite.height = 240;
}

protected function playVideo() : void {
var videoElement : VideoElement = new VideoElement( new NetLoader(),
new URLResource( new URL( REMOTE_PROGRESSIVE ) ) );
playerWrapper.element = videoElement;

var sameVideoElement : VideoElement = new VideoElement( new NetLoader(),
new URLResource( new URL( REMOTE_PROGRESSIVE ) ) );
player.autoPlay = true;
player.source = sameVideoElement;
}

protected function playVideoFromTheMiddle() : void {
var sameVideoElement : VideoElement = new VideoElement( new NetLoader(),
new URLResource( new URL( REMOTE_PROGRESSIVE ) ) );

player.autoPlay = false;
player.source = sameVideoElement;
player.addEventListener( DurationChangeEvent.DURATION_CHANGE, onDurationChange );
player.addEventListener( MediaPlayerCapabilityChangeEvent.TEMPORAL_CHANGE, onTemporalChange );
player.addEventListener( MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE, onPlayerStateChange );
player.play();
player.pause();
}

private function onDurationChange( event : DurationChangeEvent ) : void {
trace( "duration change: " + event.newDuration );
trace( "can seek to 30s: " + player.canSeekTo( 30 ) );
if ( player.canSeekTo( 30 ) ) {
player.seek( 30 );
player.play();
}
}

private function onTemporalChange( event : MediaPlayerCapabilityChangeEvent ) : void {
trace( "temporal change: " + player.duration );
}

private function onPlayerStateChange( event : MediaPlayerStateChangeEvent ) : void {
trace( "state change: " + (player.state == MediaPlayerState.PLAYBACK_ERROR) );
}



]]>
</mx:Script>

<players:MediaPlayerWrapper id="playerWrapper" width="640" height="480" />
<mx:Button label="play" click="playVideo()" />
<mx:Button label="play from the middle" click="playVideoFromTheMiddle()" />

</mx:Application>


This question has received the maximum number of answers.