Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prefetch video in a react application?

I have a React app with a component that loads different videos depending on user input. There are only 4 or 5 small videos, so I'd like to pre-fetch all of them when the browser is inactive.

Within my component, I have:

<video src={this.props.video} type="video/mp4" />

In my index.html, I have a line in the head for a video:

<link rel="prefetch" as="video/mp4" href="link/to/my/video.mp4">

However, this doesn't work. Looking at the console, I can see that the video is fetched (with a 200 status) but not stored in the cache (size is 5 Mb for the response, 0 Mb for on disk). When I provide user input and the component needs to display that video, it is fetched again which takes a few seconds.

PS - The reason I'm not trying to use preload on the video element is because preload only works if the page you are looking at has the video in it. In my case, I want to load the videos even if they are not required for the current page.

Update: I made a pen where you can see that the video isn't pre-fetched despite the use of a link tag in the head.

like image 871
bluprince13 Avatar asked Aug 07 '18 19:08

bluprince13


People also ask

What is prefetching in React?

The goal of prefetching is to make data fetch before the user navigates to a page or attempts to load some known content. There are a handful of situations that you may want to do this, but some very common use cases are: User hovers over a navigation element. User hovers over a list element that is a link.

How do you reduce load time on React app?

To solve this react itself has a native solution, which is code-splitting and lazy loading. Which allows splitting bundle files into a smaller size. The best place to introduce code splitting is in routes. Route-based code splitting solve half of the issues.

How do you set a video in React?

To add a background video with React, we can add the video element with the autoPlay prop. We add the video element with the loop prop to make the video replay after it's finished. And the autoPlay prop makes the video start automatically when we load the page.


1 Answers

In your situation, you can make an AJAX request and create blob URL from the response of that request.

You can see from my code pen

function playVideo() {
    var video = document.getElementById('video')

    if (video) {
        video.play().then(_ => {
            console.log('played!')
        });
    }
}

function onSuccess(url) {
    console.log(url);
    var video = document.createElement('VIDEO')
    if (!video.src) {
        video.id = 'video';
        document.body.appendChild(video);
        video.src = url
    }
}

function onProgress() {

}

function onError() {

}

prefetch_file('https://raw.githubusercontent.com/FilePlayer/test/gh-pages/sw_360_lq.mp4', onSuccess, onProgress, onError)

function prefetch_file(url,
                       fetched_callback,
                       progress_callback,
                       error_callback) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";

    xhr.addEventListener("load", function () {
        if (xhr.status === 200) {
            var URL = window.URL || window.webkitURL;
            var blob_url = URL.createObjectURL(xhr.response);
            fetched_callback(blob_url);
        } else {
            error_callback();
        }
    }, false);

    var prev_pc = 0;
    xhr.addEventListener("progress", function (event) {
        if (event.lengthComputable) {
            var pc = Math.round((event.loaded / event.total) * 100);
            if (pc != prev_pc) {
                prev_pc = pc;
                progress_callback(pc);
            }
        }
    });
    xhr.send();
}

The disadvantage of this approach is that it will not work if the video doesn't allow CORS for your site.

like image 194
Max Avatar answered Sep 21 '22 07:09

Max