Аудиопоток Expressjs не воспроизводится по запросу

#javascript #express #streaming #html5-audio #audio-streaming

#javascript #выражать #потоковое вещание #html5-аудио #потоковое аудио #выразить #потоковая передача

Вопрос:

Я создаю мобильное музыкальное приложение, которое использует Expressjs API, и у меня возникли проблемы с отправкой песни клиенту через потоковую передачу.

У меня есть songs маршрут в моем приложении Express:

 import express from 'express'

import fs from 'fs'

const router = express.Router()
router.get(
    '/:fileName',
    async (req: express.Request, res: express.Response) => {
        try {
            const { fileName } = req.params
            const filePath = `music/${fileName}`
            const stream = fs.createReadStream(filePath)
            const stat = fs.statSync(filePath)

            res.set('Content-Disposition', `attachment; filename="${filePath}"`)
            res.set('Content-Range', `bytes ${0}-${stat.size - 1}/${stat.size}`)
            res.set('Content-Length', `${stat.size}`)

            res.set('Content-Type', 'audio/mpeg')
            res.set('Accept-Ranges', 'bytes')

            stream.pipe(res)
        } catch (err) {
            res.status(400).send(err)
        }
    }
)

module.exports = router
  

И мое мобильное приложение построено на React и использует react-native-track-player .
По какой-то причине звук не воспроизводится не только в моем мобильном приложении, но и в браузере или даже PostMan

В браузере:

браузер также не воспроизводит аудио

и в PostMan он также просит меня загрузить .mpga файл:

введите описание изображения здесь

Если я получаю другую ссылку, например, с Google Диска, звук воспроизводится, и он работает в моем мобильном приложении.

Ссылка на Google Drive в PostMan:

введите описание изображения здесь

Я застрял на этом неделями. Есть идеи, как это можно решить? Заранее благодарю вас.

Обновить

С ogg файлами поток работает просто отлично. Интересно, почему это не происходит с mp3 . Если у вас есть какие-либо идеи, дайте мне знать.

Ответ №1:

Вам необходимо получить доступ к переменной в параметрах, чтобы

 req.params
  

должен быть преобразован в

 req.params[0]
  

чтобы получить доступ к файлу, переданному из параметров.
как указано в Express API:

 // GET /file/javascripts/jquery.js
console.dir(req.params[0])
// => 'javascripts/jquery.js'
  

Комментарии:

1. Это неправильно, request.params возвращает словарь. В моем случае: { fileName: 'song.mp3' } я не получаю никаких ошибок, связанных с несуществующим файлом. На самом деле, я не получаю никаких ошибок. Песня просто не воспроизводится вообще.

Ответ №2:

Неправильный способ обработки диапазонов содержимого.

 res.set('Content-Range', `bytes ${0}-${stat.size - 1}/${stat.size}`)
  

Вы жестко запрограммировали начальный диапазон, но обычно бывает так, что запрошенный диапазон не всегда начинается с 0 .

Я бы настоятельно рекомендовал просто использовать express.static() в этом случае или даже обычный веб-сервер, такой как Nginx. Он уже выполняет всю работу за вас.

Кроме того, в вашем коде есть серьезная уязвимость в системе безопасности, поскольку любой пользователь может запросить любой файл на вашем жестком диске, передав относительные пути ../../../etc .