Реализация веб-плеера на FastAPI

Дано:

  1. Плейлисты, содержащие некоторое количество аудиозаписей разной длины (1мин - ?). Плейлисты хранятся в MinIO - <bucket-name>/<playlist-id>/<file.mp3>.
  2. Фронтенд - обычный html для отображения данных плейлиста, на котором расположен плеер (обычный html <audio>) для воспроизведения аудио, под плеером список аудиозаписей для данного плейлиста. При клике на аудиозапись формируется url и подставляется в плеер <audio src=<url> ...
  3. Бэкенд - 2 эндпоинта. 1й для рендеринг страницы. 2й для загрузки аудиозаписи /api/{playlist_id}/{audio_id} .

Код

@router.get("/api/{playlist_id}/{audio_id}")
async def get_audio(request: Request, playlist_id: UUID, audio_id: str):
    audio_data, audio_size = await get_content_from_minio( # здесь идет обращение к MinIO, достается аудиофайл, читается и возвращается
        playlist_id,
        audio_id,
    )

    headers = {
        'Content-Range': f'bytes=0-{audio_size}/{audio_size}',
        'Accept-Ranges': 'bytes'
    }
    return Response( # здесь я возвращаю полный файл
        audio_data,
        status_code=200,
        headers=headers,
        media_type="audio/mpeg"
    )

Формирование и подстановка url в html:

playlistItems.forEach(function (item) {
  item.addEventListener('click', function () {
    const audioId = item.getAttribute('data-audio-id');
    const newSource = `/api/${playlistId}/${audioId}`;
    console.log('newSource: ', newSource);
    audio.src = newSource;
    });

Проблемы\Вопросы:

  1. Бэкенд отправляет полный файл на фронтенд. При попытке перемотки аудиозаписи (нажатие на ползунок в рандомном месте) идет новый запрос на эндпоинт с новым range'ем, и таким образом весь процесс выгрузки аудиозаписи идет по новой. Как избежать повторного вызова эндпоинта, если аудиозапись целиком летит клиенту при первом вызове?
  2. Я понимаю, что данный подход скорее является плохим. Можно было бы грузить аудиофайл чанками на фронт, НО - надо ли в таком случае сохранять аудиофайл локально, чтобы не дергать постоянно аудиохранилище? Не придется ли в таком случае создавать сессию, чтобы при смене аудиозаписи на фронте (или вообще выходе со страницы) удалялась сохраненная локально предыдущая запись?
  3. Подскажите материалы по данной теме как правильно строить такие сервисы, настраивать фронт и бэк.

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