Реализация веб-плеера на FastAPI
Дано:
- Плейлисты, содержащие некоторое количество аудиозаписей разной длины (1мин - ?). Плейлисты хранятся в MinIO -
<bucket-name>/<playlist-id>/<file.mp3>. - Фронтенд - обычный html для отображения данных плейлиста, на котором расположен плеер (обычный
html <audio>) для воспроизведения аудио, под плеером список аудиозаписей для данного плейлиста. При клике на аудиозапись формируетсяurlи подставляется в плеер<audio src=<url> ... - Бэкенд - 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;
});
Проблемы\Вопросы:
- Бэкенд отправляет полный файл на фронтенд. При попытке перемотки аудиозаписи (нажатие на ползунок в рандомном месте) идет новый запрос на эндпоинт с новым
range'ем, и таким образом весь процесс выгрузки аудиозаписи идет по новой. Как избежать повторного вызова эндпоинта, если аудиозапись целиком летит клиенту при первом вызове? - Я понимаю, что данный подход скорее является плохим. Можно было бы грузить аудиофайл чанками на фронт, НО - надо ли в таком случае сохранять аудиофайл локально, чтобы не дергать постоянно аудиохранилище? Не придется ли в таком случае создавать сессию, чтобы при смене аудиозаписи на фронте (или вообще выходе со страницы) удалялась сохраненная локально предыдущая запись?
- Подскажите материалы по данной теме как правильно строить такие сервисы, настраивать фронт и бэк.