Устройства apple не получают видео с сервера

введите сюда описание изображенияЕсть функция отправки видео по чанкам и блок video.

Проблема: В браузере видео загружается, а на ios нет, с сервером проблем нету тк. стоит на vps

JavaScript:

router.get('/video/first',
    async (req, res) => {
        try {
            console.log(req.ip)
            const range = req.headers.range;
            if (!range) {
                res.status(400).send("Requires Range header");
            }
            const videoPath = path.join(__dirname, '../media/videos/M.mp4');
            const videoSize = fs.statSync(videoPath).size;
            const CHUNK_SIZE = 10 ** 6;
            const start = Number(range.replace(/\D/g, ""));
            const end = Math.min(start + CHUNK_SIZE, videoSize - 1);
            const contentLength = end - start + 1;
            const headers = {
                "Content-Range": `bytes ${start}-${end}/${videoSize}`,
                "Accept-Ranges": "bytes",
                "Content-Length": contentLength,
                "Content-Type": "video/mp4",
            };
            res.writeHead(206, headers);
            const videoStream = fs.createReadStream(videoPath, {
                start,
                end
            });
            return videoStream.pipe(res);
        } catch (e) {

        }

    })

HTML:

<video controls className="firstPage_videoBlock_video" id="player">
    <source src="http://serverurl:5000/api/video/first"/>
</video>

Ответы (1 шт):

Автор решения: Daniil Loban

Поправил код из вопроса, добавил комментариев. Так должно работать, end не нужно было высчитывать.

router.get('/video/first',
    async (req, res) => {
        try {
            //console.log(req.ip)
            const range = req.headers.range;
            if (!range) {
              res.status(400).send("Requires Range header");
              return // тут нужен ретурн
            }
            // путь лучше собирать так, без .. (точек)
            const videoPath = path.join(__dirname, 'assets/sample.mp4');
            const videoSize = fs.statSync(videoPath).size;

            //const CHUNK_SIZE = 10 ** 6;
            //const start = Number(range.replace(/\D/g, ""));
            //const end = Math.min(start + CHUNK_SIZE, videoSize - 1);
              
            const parts = range.replace(/bytes=/, "").split("-")
            const start = parseInt(parts[0], 10) // первое число
            const end = parts[1] // и если есть второе 
                ? parseInt(parts[1], 10)
                : videoSize-1 // или подставляем конец файла

            // cначала высчитать разницу потом прибавить 1
            const contentLength = (end-start)+1//end - start + 1;
            const headers = {
                "Content-Range": `bytes ${start}-${end}/${videoSize}`,
                "Accept-Ranges": "bytes",
                "Content-Length": contentLength,
                "Content-Type": "video/mp4",
            };
            res.writeHead(206, headers);
            const videoStream = fs.createReadStream(videoPath, {
                start,
                end
            });
            // return тут скорее всего не нужен
            videoStream.pipe(res);
        } catch (e) {

        }
})

На хостинге у меня код страницы такой, все работает (проверял на iphone)

<video src="https://имя_хостинга/testapp/video" 
    controls id="videoPlayer">
</video>


    
→ Ссылка