I'm having an issue where looped HTML5 video elements in Safari with the loop
attribute have a noticeable delay between the end of the video and the beginning when looping. When the video reaches the end, it freezes for a moment then jumps back to the first frame. I tried the same page in Chrome (trying both the .mp4 and .webm versions) and didn't have this problem. Has anyone else noticed this? Is there a way to get the Safari video to loop cleanly instead of pausing before returning to the beginning of the video?
I'm using Wordpress along with the Slick carousel jQuery plugin.
Here is the code I'm working with:
SASS
#home-slider {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
margin-bottom: 0;
& > a {
display: block;
width: 100%;
height: 100%;
}
.slide {
height: 100vh;
position: relative;
background-repeat: no-repeat;
background-position: top center;
@include background-size(cover);
&.slick-active {
z-index: 8000;
}
@media only screen
and (max-width: 750px) {
.video-bg {
display: none;
z-index: -1;
video {
display: none;
}
}
}
.video-bg {
z-index: 5000;
position: absolute;
width: 100vw;
height: 100vh;
video {
position: absolute;
top: 50%;
left: 50%;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -100;
-ms-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
}
}
}
HTML
<div class="slide" style="background-image: url('<?= $slide_bg['url']; ?>');">
<?php if(count($slide_video_bg) > 0) : ?>
<div class="video-bg">
<video playsinline muted loop poster="<?= $slide_bg['url']; ?>" preload="auto">
<source src="<?= $slide_video_bg['webm']['url']; ?>" type="video/webm">
<source src="<?= $slide_video_bg['mp4']['url']; ?>" type="video/mp4">
</video>
</div>
<?php endif; ?>
<a class="slide-link" data-video-title="<?= $post->post_title; ?>" data-vimeo-id="<?= $vimeo_id; ?>" data-video-client="<?= $video_client; ?>" data-video-director="<?= $video_director; ?>" data-video-description="<?= $video_description; ?>"></a>
<div class="slide-info">
<a class="mobile-play vimeo-link" data-video-slug="<?= $post->post_name; ?>" data-vimeo-id="<?= $vimeo_id; ?>" data-video-title="<?php the_title(); ?>" data-video-client="<?= $slide_client; ?>"></a>
<h3 class="slide-client"><a class="vimeo-link" data-video-slug="<?= $post->post_name; ?>" data-vimeo-id="<?= $vimeo_id; ?>" data-video-title="<?php the_title(); ?>" data-video-client="<?= $slide_client; ?>"><?= $slide_client; ?></a></h3>
<h3 class="slide-slash">/</h3>
<h2 class="slide-title"><a class="vimeo-link" data-video-slug="<?= $post->post_name; ?>" data-vimeo-id="<?= $vimeo_id; ?>" data-video-title="<?php the_title(); ?>" data-video-client="<?= $slide_client; ?>"><?php the_title(); ?></a></h2>
</div>
</div>
JS
var $lightbox = $('.lightbox'),
$slideLink = $('.slide-link'),
slideCount = $('.slide').length,
startSlide = Math.floor(Math.random() * slideCount),
urlHash = window.location.hash,
lastSlide = startSlide;
$homeSlider.slick({
adaptiveHeight: true,
arrows: false,
autoplay: true,
autoplaySpeed: 4000,
cssEase: "ease-in-out",
dots: true,
fade: false,
initialSlide: startSlide,
lazyLoad : 'progressive',
onBeforeChange: beforeSlickChange,
onAfterChange: afterSlickChange,
pauseOnHover: false,
speed: 800
});
initSlides();
function beforeSlickChange(slick, currentSlide, nextSlide) {
if(hasVideoBG(nextSlide) === true && isMobile(mobileQuery)=== false) {
if(nextSlide === 0) {
$homeSlider.find(".slick-cloned:eq(1) video").get(0).play();
}
if(nextSlide === (getSliderCount() - 1)) {
$homeSlider.find(".slick-cloned:eq(0) video").get(0).play();
}
if(getSlideVideoByIndex(nextSlide).paused) {
getSlideVideoByIndex(nextSlide).play();
lastSlide = currentSlide;
}
}
}
function afterSlickChange(slick, currentSlide) {
if(currentSlide === 0 && lastSlide != 1) {
var $slideVideo = $homeSlider.find(".slick-cloned:eq(1) video").get(0);
getSlideByIndex(currentSlide).find("video").get(0).currentTime = $slideVideo.currentTime
} else if(currentSlide === (getSliderCount - 1) && lastSlide != (getSliderCount - 2)) {
var $slideVideo = $homeSlider.find(".slick-cloned:eq(0) video").get(0);
getSlideByIndex(currentSlide).find("video").get(0).currentTime = $slideVideo.currentTime
}
getSlideVideoByIndex(lastSlide).pause();
}
Thanks in advance.
I would love to help, but we need to see your code. We can't really help much, because we don't know what you have.
Here is a theory to get you started:
Only .MP4 is supported in Safari - so make sure your video is actually .MP4 formatted. If it isn't it's a possiblity that it is playing, but the delay is because it's not supported. This is only so if you didn't convert it correctly.
Or another theory could be that the delay is because in Safari, looping the video virtually, just starts it over, so it will "Buffer" or "Re-Load" to replay.
Conclusive evidence (from some quick google referencing) shows, that the second theory is more torward what I am seeing. Chrome may have some special code inside the engine that renders differently from safari. Regardless. Try the code in the answer of a Similiar question.
Update
OP added code, still going to stick beside my answer as what I researched seemed to have came back to that conclusion.