javascriptgoogle-chromehtml5-videovimeoakamai

Chrome not loading (or redirecting) Vimeo direct video URLs


Context:

So I built a website for a company, and it uses Vimeo to host all it's videos. We use the "direct download" URL's Vimeo Pro provides to play a MP4 video using the native <video> element.

You can see the site here.

For example, a lot of images on this site show a video on hover, on almost all pages. Those videos are what I am describing. It is not the video's shown with player controls, those are proper Vimeo iFrame embeds.

The problem:

After browsing around the site for a little (navigating to about 4-5 different pages should trigger it), those MP4 videos stop loading, but only in Chrome. I've tested it across a lot of computers in my company, both in office and remote. I am using Chrome for Mac, Version 107.0.5304.121.

What does "stop loading" mean? I mean, that if you copy the video src URL from the site source code and open it in a new browser, it never loads... But if you use that same URL in an Incognito tab, it will load and play. You can also see it happening in the Network tab of DevTools.

From best I can tell, the Vimeo URL actually get redirected to a akamaized.net URL, and that redirect stops working, perhaps by some sort of rate limit or cookie tracking?

Here is a video recording showing the issue: https://www.dropbox.com/s/fnp0oaoaeb9s54i/New%20Recording%20-%2011_29_2022%2C%2010_32_58%20AM.webm?dl=0

The code that is used to display those videos is like this:

<video 
    src="https://player.vimeo.com/progressive_redirect/playback/759618180/rendition/1080p/file.mp4?loc=external&signature=73c3773c3830e6ef73af25b0c88e33c411a79a365497ef56519b5f18a963b523" 
    loop="loop" 
    autoplay="autoplay" 
    playsinline="true" 
    disablepictureinpicture="true" 
    preload="none" 
    muted=""
>
</video>

And then using an IntersectionObserver when the video is in-view I load() the video, and on hover I play() the video.

Vimeo support says they are "unable to replicate the issue" which given the multiple people in my company (and the client) that can see this, I think Vimeo support is wrong.

Attempted solutions:

I tried setting crossorigin="anonymous" on each video, and that had no effect.

I implemented the Intersection Observer and preload="none" code to be more efficient with what videos get loaded. This helped with bandwidth usage, but didn't solve the Vimeo video's not loading/redirecting.

Intersection Observer:

A comment asked for the Intersection Observer code, so here it is. This is a big Vue component using a custom IntersectionObserver directive, so I simplified it some.

<figure
        v-intersection-observer.once="{ rootMargin: '50% 0% 50% 0%' }"
        :class="classes"
        @has-entered="onEntered" // Above directive emits this
        @mouseover.native="play()"
        @mouseleave.native="pause()"
    >
    <video
            ref="video"
            :src="videoUrl"
            :loop="true"
            :autoplay="true"
            :muted="true"
            :playsinline="true"
            disablepictureinpicture="true"
            preload="none"
            crossorigin="anonymous"
            @error="onError('video')"
        />
</figure>
<script>
export default {
    props: {
        videoUrl: {}
    },
    methods: {      
        onEntered() {
            if (this.$refs.video) {
                this.$refs.video.load()
            }
        },
        pause() {
            if (this.$refs.video) {
                this.$refs.video.pause()
            }
        },
        play() {
            if (this.$refs.video && this.$refs.video.paused) {
                return this.$refs.video.play()
            }
        },
    }
}
</script>

Solution

  • Here is what happening:

    here is a proper way to implement paly/pause using promise

    <video id="video" preload="none" src="https://example.com/file.mp4"></video>
     
    <script>
      // Show loading animation.
      var playPromise = video.play();
     
      if (playPromise !== undefined) {
        playPromise.then(_ => {
          // Automatic playback started!
          // Show playing UI.
          // We can now safely pause video...
          video.pause();
        })
        .catch(error => {
          // Auto-play was prevented
          // Show paused UI.
        });
      }
    </script>
    

    Also, be aware of this Chromium Bug