Video is lagging when using currentTime - javascript

I have a simple HTML page and I play a video on the page. I use the scrollbar as the seekbar. In other words, video plays as long as the user scrolls.
I've seen this effect used in couple places and wanted to create it myself. The script I wrote is fully functioning, but there's a small problem: the video itself.
The videos from the examples run smoothly, but the videos that I created, they lag. I can't seem to figure out the cause. I've tried different combination of FPS, resolution, bit rate, but they didn't help.
The only difference among the videos that I could find is when I play the videos from the examples, I can seek any frame on MPC (K-Lite). I can seek only 3-4 frames on the videos that I've created. So the problem might be related to that. I'm not sure. If it's about that, I need a way to make the videos fully seekable. How do I do that?
https://akinuri.github.io/sticky-scrollable-video/ (online demo)
https://github.com/akinuri/sticky-scrollable-video (repo, check for details)
https://www.audi.com.tr/tr/web/tr/modeller/a8/a8-l.html (sticky scrollable video)
codepen.io/ollieRogers/pen/lfeLc (scrollable video)
Online demo plays the smooth/seekable video (from Audi). To see the difference between videos, you have to download the project from GitHub. Two videos (Audi and Chrome_ImF.ogv) are smooth/seekable. Other two (Chrome_icon, bedroom.mp4) are problematic/lags (only few frames are seekable).
Chrome/Opera produces smoother playback than Firefox. I'm using Premiere Pro for the videos.
Edit: While the linked question talks about the same problem, I can't mark my question as a duplicate of it. Why? It's 3 years old, has only 1 answer, the answer isn't accepted, and it is poor. Video editing isn't my main occupation, so I can't make a direct inference from an answer. Answers should be given elaborately. My Q/A is more detailed. So I doubt that anyone viewing both questions would prefer the old one to this.

The problem is indeed about seekability. I've found another question related to this problem and it made me look into key frames a little deeper.
I was looking for a way to modify the key frames (in Premiere Pro) and I found it in
Export Settings (CTRL+M) -> Video -> Advanced Settings -> Key Frame Distance
The keyframe distance is the maximum number of frames before the encoder inserts an i-frame,...
https://forums.adobe.com/message/9451877#9451877
This setting was not ticked, and was set to 72. So depending on the FPS, it equals to 1-2 seconds. To make all the frames seekable, I've set this to 1 and it worked.
Update: It turns out that playing videos with low KFD on mobile (Chrome, Samsung Internet) is problematic. While StickyScrollableVideo can play the video (using currentTime), it is laggy. On the other hand, video.play() fails. Video just doesn't play. So instead of using StickyScrollableVideo on mobile, I'll disable it and just play the video. And to be able to do that, I need a version of the video with a higher KFD. So I prepared two videos; one with KFD:1 for desktop/StickyScrollableVideo, and other with KFD:25 (FPS) for mobile/video.play().
Issue can be seen here: https://akinuri.github.io/in-view-tracker/video.html
First video is with KFD:1, and the second is KFD:25. Tap on videos to play/pause.

You must know root of this bug is CPU usage for complete page work (your video staff + all other job). In your example look like video encoder (mp4) bug. To make full response for all browsers you need both (safari,firefox,chrome) video format.
One way is theory: Use web workers (new thread) to play video and navigate from code.
Second is drawing video blob direct in canvas2d. In canvas program you can easy void to the current frame.
Did you try on other (better) computer with similar environment and same browser version?
This will fix you problem 50%. Just conver mp4 to the ogg ( .ogv ) format
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogv" type="video/ogg">
Your browser does not support the video tag.
</video>

Related

HTML5 video stutter on loop

I have a simple HTML5 video on my website. I want it to loop so I added loop tag to it. It works, the problem is that it stutters everytime it restarts. The video is very short, has only 8 seconds, but when it reaches the end, and then restarts, the very first frame of the video "freezes" about half of a second. I tested it on Chrome and on Firefox, it only happens on Chrome.
After google it I found several workarounds, but none of them worked for me. I tried to catch the ended event of the video in JS so I play the video again, to clear the poster image of the video when it starts to play $video.attr('poster', ''), and so on.
If I play the video on Windows Media Player or any other video player with "repeat" mode on, it loops without any stutter, so I don't think is something related with the video encoding.
<video loop>
<source src="myvid.mp4" type="video/mp4">
</video>
When trying to optimize my video size, I found Handbrake, a video editor software. After optimize my video size with this software, it gone from 1.4MB to
272KB, and magically the stutter disappeared.
So after all, it really was about video encoding, or something related with.
For those who came here from google and have already tried the many workarounds suggested to this problem in other stack questions, try to optimize your video with Handbrake and I hope your "stutter" goes away.
In my own attempts to loop a seamless Ken Burns clip as a background for a hero unit, I also ran into inexplicable stutter issues. Turns out, the loop property isn't implemented very well in many browsers, generally giving me a half second to full second pause before resuming playback. To correct this, I had to implement my own looping behaviour:
document.querySelector('video').addEventListener('ended', function(e) {
e.target.currentTime = 0;
e.target.play();
}, false);
This was fast enough in testing to appear actually seamless. Complex stream encoding (e.g. use of lookahead frames or other non-baseline features) will only compound this overall issue. Always make sure you export your video "for the web" / "streaming", which disables these incompatible features.
I merged amcgregor's solution with Thomas Brad's solution and came up with something like this:
document.querySelector('video').addEventListener('timeupdate', function(e) {
if(e.target.duration - e.target.currentTime <= 1) {
e.target.currentTime = 0;
e.target.play();
}
}, false);
With this one stutter goes away even for not well encoded videos.

Xml audio list player not working on the mobile and autoplay is not working

I have been working on a multimedia website,, but i am stuck in a problem for the last three days.
I want to integrate an audio player in my website so that it can show the playlist in XML and also have an autoplay.
I have tried many free and paid audio player. In last i choose JW Player it has XML playlist integration but it is not working when mobile website is accessed by the user. and Autoplay is not working. Please solve my problem what can i change in JW player to solve these issues.
First, forget about autoplay. This has been repeated so many times, it's getting tiresome:
There is no autoplay possible on a mobile device.
The mobile devices themselves disable this. There are very good reasons for doing this - expensive bandwidth, disruption in meetings, restaurants, etc. There is no way around this. There is no player on Earth that can bypass this.

Gapless Transition from Video to Video using html5

I am trying to create a feature where a user can change (back and forth) between multiple videos while maintaining a single consistent audio. Think of being able to watch a concert from multiple angles but listening to a single audio. The trouble I am having with this feature is that there can not be a lag between the changes in video or the audio will no longer sync with the videos (especially true after multiple changes).
I have tried two methods, both using html5 only (I would prefer not use flash although I will eventually have a fallback) that have not worked seamlessly, although depending on the browser and hardware, it can come very close.
Basic Methods:
Method 1: Preloading all videos and changing the video src path on each click using javascript
Method 2: Again preloading video and using multiple tags and changing between them using javascript on each click.
Is there anyway to get either of these two methods to work seamlessly without a gap? Should I be using a slight of hand trick, like playing both videos concurrently for a second before revealing the second and stoping the first? Can this just not be done with html5 players? Can it be done with flash?
I have seen this type of question a couple of times with both video and audio with no clear solution, but they were a couple of months old and I was hoping there is now a solution. Thanks for the help.
Worth adding that it is possible with the MediaSource API proposed by Google. This API allows you to feed arbitrary binary data to a single video element, thus if you have your video split into chunks you can fetch those chunks via XHR and append them to your video element, they'll be played without gaps.
Currently it's implemented only in Chrome and you need to enable Enable Media Source API on <video> elements in chrome:flags to use it. Also, only WebM container is currently supported.
Here is an article on HTML5Rocks that demonstrates how the API works: "Stream" video using the MediaSource API.
Another useful article that talks about chunked playlist: Segmenting WebM Video and the MediaSource API.
I hope this implementation gets adopted and gets wider media container support.
UPDATE JUN 2014 Browser support is slowly getting better: (thanks #Hugh Guiney for the tip)
Chrome Stable
FF 25+ has a flag media.mediasource.enabled [MDN]
IE 11+ on Windows 8.1 [MSDN]
Did you find a better way to do that?
I implemented a double-buffered playback using two video tags.
One is used for the current playback, and the second for preloading the next video.
When the video ends I "swap" the tags:
function visualSwap() {
video.volume = video2.volume;
video2.volume = 0;
video.style.width = '300px';
video2.style.width = '0px';
}
It has some non-deterministic behavior, so I am not 100% satisfied, but it's worth trying...
Changing the SRC tag is fast, but not gapless. I'm trying to find the best method for a media player I'm creating and preloading the next track and switching the src via "ended" leaves a gap of about 10-20ms, which may sound tiny, but it's enough to be noticable, especially with music.
I've just tested using a second audio element which fires off as soon as the first audio element ends via the event 'ended' and that incurred the same tiny gap.
Looks like (without using elaborate hacks) there isn't an simple(ish) way of achieving gapless playback, at least right now.
it is possible. you can check this out: http://evelyn-interactive.searchingforabby.com/ it's all done in html5. they are preloading all videos at the beginning and start them at the same time. didn t had time yet, to check how they re doing it exactly, but maybe it helps if you check their scripts via firebug
After many attempts, I did end up using something similar to Method 2. I found this site http://switchcam.com and basically copied their approach. I pre-buffered as the video start time approached and then auto-played as the videos starting point hit. I had the current videos playing simultaneously (in a little div - as a UI bonus) and users could toggle between the videos switching the "main screen view". Since all videos were playing at once, you could choose the audio and the gap didn't end up being an issue.
Unfortunately, I never ended up solving my problem exactly and I am not sure my solution has the best performance, but it works okay with a fast connection.
Thanks for everyones help!

iOS html5 video on mobile safari

I have a video I'm playing on iOS 4.2 where I'm listening in the timeupdate events and pausing video at certain times. This is fairly accurate. However, I also have player controls that seek to certain parts of the video using current time.
There appears to be a bug where the time seeked is never accurate - not accurate enough for what I need to do with it. The problem gets worse as the length of the video increases and I've also noticed that at the beginning of the video the seek time would be around 0.5 miliseconds off the time I specify but as I try to seek further along in the video this increases. Seeking 2 minutes into a video files is off by around 2 seconds.
I don't think this is a probloem with my code as I've replicated the same behaviour using the opensource Jplayer.
http://www.jplayer.org/HTML5.Media.Event.Inspector/
currentTime has caused me nothing but problems on iOS. It didn't even work on 3.2.
Is the problem I'm having now a known bug and is there a workaround for this?
I ran a test to see if I could confirm the same behavior on my emulated build of iOS 4.1.
I definitely experienced similar problems on both the iPhone and iPad. But I didn't notice the offset growing proportionately as the video got longer - it seemed more random. If I had to guess, I'd say the video is seeking to the keyframe prior to to your requested time rather than to the correct position.
The iOS devices seem to be reporting currentTime accurately... You are able to pause the video in the correct place and it looks like the timecode on the iPhone matches that on the desktop. It just won't queue up in the correct place.
What kind of video are you using? I tested h264 video encoded with ffmpeg.
It might be worth adding more keyframes to your video or looking for a switch in your encoder that makes the content more easily seekable. I know ogg video has support for indexing (see this post). That won't help this issue, but we might be able to find a parallel solution that works here.
This is going to be a problem for me very soon, so I'm very interested to see if you found a fix. Please post back if you have.

Multi-channel audio support in the browser on iOS and Android

I found this link to a page here on StackOverflow about "Creating Audio using Javascript in <audio>", and this page on how to play audio on multiple channels. I found that the iPhone supports the audio tag and the Audio object in Javascript to play single channel audio, but is there a way to play audio on multiple channels?
Maybe I'm over complicating this, so this is what I'm trying to do. I want a way to make a graceful audio player in Javascript that supports transitioning from one audio file to another. The way I was going to implement this is to incrementally reduce the volume on one channel while incrementally increasing the volume on the other channel so I'd get a kind of fade effect. Is there a simpler solution to this using only Javascript? I guess another solution would be to reduce the volume to a certain point, start the new audio file on the same channel, then increase the volume again. This circumvents the need for fading, but I would like to fade if at all possible.
Is this possible? I know the HTML5 spec isn't finished yet, but is there some kind of workaround that you know of? Do any of you have ideas for another approach?
From what I can tell from this post about playing audio in the Android browser, this isn't supported yet, but do any of you know if it will support multiple channel audio once the audio tag is supported? Does opera mini support this?
This is an old question I know :).
iOS Safari does not support multiple audio objects playing at the same time. Also, it is not possible for having a fade-in/out effect for iOS, as the only way to change the volume setting is from the hardware itself. Apple decided to give this ability only to the device user. Volume setting is not writable by javascript. It is not even readable (always returns 1).
You can check out the Safari documentation for iOS for more info.
For Android, to be honest I have no idea.
There's no direct way that I know of to have multiple channels on an audio tag, but check out this blog post on using multiple audio tags to simulate multiple channels. http://www.storiesinflight.com/html5/audio.html
I know this is a total hack but try this trick I came up with...
Go to the page below and type on the home row keys to play a blues riff (type multiple keys at the same time etc.)
http://davealger.com/jthump/
The way this works is to create invisible <iframe> components that play a sound before destroying the frame.
I know it is a total hack and I look forward to better HTML 5 multi-channel audio support in the future.

Categories

Resources