vendure-ecommerce / vendure

The commerce platform with customization in its DNA.
https://www.vendure.io
Other
5.58k stars 989 forks source link

Support asset streaming #3026

Open casperiv0 opened 3 weeks ago

casperiv0 commented 3 weeks ago

Is your feature request related to a problem? Please describe. We have video product shots - which work perfectly in a web environment - we'd also like to implement these for our mobile app. iOS requires support for streaming video assets

Describe the solution you'd like Support video streaming, something like:

const range = req.headers.range;
if (range) {
    const total = file.length;
    res.setHeader("Accept-Ranges", "bytes")
    res.setHeader("Access-Control-Expose-Headers", "origin, range, vendure-auth-token");

    const positions = range.replace(/bytes=/, "").split("-");
    const start = parseInt(positions[0], 10);
    const end = positions[1] ? parseInt(positions[1], 10) : total - 1;

    if (start >= total || end >= total) {
        res.status(416).send('Requested range not satisfiable\n' + `start: ${start}, end: ${end}, total: ${total}`);
        return;
    }

    const chunksize = (end - start) + 1;

    // Set response headers
    res.writeHead(206, {
        'Content-Range': `bytes ${start}-${end}/${total}`,
        'Accept-Ranges': 'bytes',
        'Content-Length': chunksize,
        'Content-Type': 'video/mp4',
    });

    // Slice the buffer according to the range and send it
    const chunk = file.slice(start, end + 1);
    res.end(chunk);
} else {
    res.send(file);
}

Describe alternatives you've considered Implement the above code snippet into Vendure locally.

michaelbromley commented 3 weeks ago

Hi,

Can you give me a bit more context about where that code would need to go? Would it be part of the AssetServerPlugin handler?

And would it also mean that any asset file can be streamed if the client request includes the range header? Excuse my ignorance because I have never dealt with file streaming over http before.

casperiv0 commented 3 weeks ago

Yep, this would be part of the AssetServerPlugin, more notably the sendAsset function (and if necessary for images, generateTransformedImage function too). I've never worked with streaming over http before, but the above code snippet seems quite OK as a solution, though, there are probably some packages out there that do it for you (& probably better 😄)