HTML5 video stutter on loop - javascript

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.

Related

Video is lagging when using currentTime

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>

Problems with audio in cocos2d-javascript on mobile devices

I'm trying to find some documentation for audio support for cocos2d-javascript.
Preloading audio and playing them with the standard method using mp3 or ogg formats:
var audioEngine = cc.AudioEngine.getInstance();
audioEngine.playEffect(s_sound);
// s_sound is a reference to a preloaded audio resource
works perfectly in all browsers. But when you load the browser on a device, let's say iphone 4s retina, no audio plays, or at least it seems no audio plays for sounds longer than a few seconds. I haven't found anything stating specifically what limitations there may be in device support, nor do I see an attempt to resolve this in anyone's example games like Moon Warriors - which also does not play audio on the iphone 4s.
I am attempting to play multiple sounds simultaneously.
Each sound having problems is over 15 seconds long and is a file greater than 500k
All audio is definitely loaded since the game does not appear unless they are
Each audio track is a layer for the background music of a guitar hero type game. This is why they are over 500k and longer than 15 seconds.
Perhaps someone here has had similar issues and may know of a way to guarantee audio plays on mobile devices?
The acceptable answer thus far is to us Howler.js and HowlerAudioEngine.js
I load both files in my script loader, then modified Platform/HTML5/CocosDenshion/SimpleAudioEngine.js -
cc.AudioEngine.getInstance = function () {
if (window.devicePixelRatio > 1) {
if (!this._instance) {
this._instance = new cc.HowlerAudioEngine();
this._instance.init();
}
} else {
if (!this._instance) {
this._instance = new cc.AudioEngine();
this._instance.init();
}
}
return this._instance;
};
Notice window.devicePixelRatio > 1 where I detect retina display or hd in general. This can be substituted with any proven variety of detecting "mobile" - However, sys.platform and cc.config.deviceType always returned "browser" for me so I resorted to pixel ratio for now since my testing device will return true for that.
The cons, however, are that there is still substantial delay in the delivering of sound fx. I can compensate for that for the most part, so this is better than nothing. Also, I haven't found the tolerance threshold for audio files (play time or data length). I do know that my longer tracks of about 3 minutes don't play even in howler, but my 1 minute tracks do.
If you have anything that is better, more reliable or just an addition to this, please post it. There isn't enough support for cocos2d-javascript yet so everything helps.

Play audio in HTML5 game for mobile phone with collision

What is the best way for Playing audio in HTML5 game for mobile phone with collision.
I trying to use audio tag in HTML5, but there are a delay in sound when the collision repeated quickly !!!!!
Any idea ?
Once I've been playing around with HTML 5 and GameDevelopment - trying things out and so on. For Sound I used Soundmanager, take a look here: Click Here , maybe this can help you. It worked fine for me.
sound playing is limited to 1 sound at time on iPhone and have a big latency,
latency is probably the same on Android.
then unfortunately, it's actually not possible to use <audio> on game for collision sound. (you can use it for background music).

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.

Categories

Resources