2

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">&#47;</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.

Hendeca
  • 915
  • 2
  • 15
  • 32
  • I was thinking this was just a Safari issue too (on iOS), but Chrome on android is doing the same thing. The video in question is only about 2 seconds long, so maybe they're not optimized for that situation with respect to buffering. An animated GIF is one solution if you have to – Simon_Weaver Jul 24 '18 at 21:22

2 Answers2

2

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.

Community
  • 1
  • 1
  • Ah, yeah sorry about that. Code is now added. I have tried several different versions of the MP4 file and tried re-exporting one in Handbrake that's web optimized and still no luck. I think you are probably right about the buffering, I'm going to try that solution now! Thanks – Hendeca Jan 16 '17 at 20:13
  • I never actually figured out exactly what was going on, but I think this was the most helpful explanation and seems to me to apply to my situation. – Hendeca Oct 18 '17 at 07:11
  • Np. All theories, but that was only because there wasn't much to go on, your question isn't what I mean by that either its a perfectly fine question, there isn't much documentation on issue by issue. Some issues are just known and not many talk about it alot. Did you ever resolve it? If so how so? – jeffrey crowder Oct 19 '17 at 01:48
  • 1
    I never really solved it, or if I did, I don't remember how. I ended up finding something good enough to fix the issue I was having, but honestly it's been a bit too long to remember exactly how I figured it out or what the exact delay was. – Hendeca Oct 19 '17 at 03:39
  • @Hendeca the only reliable solution I’ve found - even today - is an animated gif. They loop perfectly. Obvious disadvantages, but sometimes it seems necessary. I have an animation that needs 0 delay or it looks jumpy. So I was just hoping you’d found a solution other than animated gif ! – Simon_Weaver Jul 24 '18 at 20:35
1

If you don't need audio with the video, export the video with no audio track, the loop then no longer has delay

Matt
  • 71
  • 1
  • 4