fregante / iphone-inline-video

📱 Make videos playable inline on the iPhone (prevents automatic fullscreen)
https://npm.im/iphone-inline-video
MIT License
2.05k stars 297 forks source link

Seeking is not reliable #77

Open chema2708 opened 8 years ago

chema2708 commented 8 years ago

Hi, i'm currently using jwPlayer to play videos in desktop and mobile devices, the IIV plugin works fine except that when jwplayer seeks to a position, IIV sometimes gets updated and sometimes doesn't. It creates a conflict because sometimes the video playback continues to play in the initial second even if jwplayer has requested it to move.

Don't know if it's just a setup error but i don't think it is because jwplayer manages all the events and play() and pause() are correctly triggered.

fregante commented 8 years ago

This is because when dragging the playhead, the player sets .currentTime a lot of times and IIV can't keep up.

It's probably going to be hard/impossible, but a solution could be to prevent JWplayer from seeking (i.e. setting .currentTime) until the user releases the playhead.

Another possible solution would be to change IIV to remember more than 3 seeks here: https://github.com/bfred-it/iphone-inline-video/blob/09c1b5d446d54c13962290355ec05df45f71331f/index.js#L51

Try changing that 3 to something like 30 or more. A high number could impact performance because this line is called up to 60 times per second

chema2708 commented 8 years ago

That's true, but my problem is not with actually "dragging" playhead. i am using the event in the code videojwplayer.seek(40), this will skip to second 40 in the video an the

i tried catching it and doing iivideo.currentTime = newTime; but sometimes it works and sometimes it doesn't

fregante commented 8 years ago

Gotcha. Could to make that 3 -> 30 change and let me know if it improves the situation?

The core problem is that IIV sets .currentTime on the video for every frame to "play" it, so it has to figure out whether the resulting seeked event comes from itself (and therefore ignore it) or from the user (and update the audio accordingly)

In iOS 9, try seeking this way: (iOS 8 is different)

Object.getOwnPropertySymbols(video)[0].audio.currentTime = 40
chema2708 commented 8 years ago

I tried what you mentioned but the result was the same.

Solved it by using the 'timeupdate' event, when the user triggers the jwplayer.seek() i add a new property to the video element called newTime. When it is created i evaluate in 'timeupdate' that the property exists and is defined, so if it is i add

video.currentTime = video.newTime;
player.driver.currentTime = video.currentTime;
delete video.newTime;

but since it is in 'timeupdate' it is independent from the seeking event.

i know it's a weird workaround but worked for me, just wanted to let you know

Thank you for your work on this plugin!

fregante commented 8 years ago

Yeah the workaround would be to have a secondary interface to set the time, but since this is trying to be polyfill I'd rather not add that for now. Glad you you got it working though

Sandstedt commented 7 years ago

Note for other with similar problem: Had a similar problem with setting currentTimeon a video. Usually you can just set video.currentTime = 10, and then video.play(), but with IIV i needed to run video.play() first and then set the video.currentTime.

Example:

const el = document.getElementById("videototrigger");
enableInlineVideo(el);

el.addEventListener('ended', evt => {
  videoLoop(el);
});
videoLoop (el) {
  el.play();
  el.currentTime = this.loopFrom;
}