Воспроизведение MIDI-файлов Pygame в PaaS из Dockerfile

Проблема:
В настоящее время я развертываю приложение Python Flask, используя Dockerfile на PaaS (например, Heroku). История пользователя выглядит следующим образом:

  1. Пользователь нажимает «Создать MIDI»
  2. Создается MIDI, и пользователь может (на той же странице):
    1. «Загрузить MIDI» (в настоящее время отлично работает локально и при развертывании PaaS)
    1. 'Воспроизведение MIDI; (работает только при локальном развертывании Flask)

У меня было несколько ошибок NotImplemented: нет такого файла или каталога..., которые исчезли с тех пор, как я добавил несколько строк установки в свой Dockerfile. Увы, я застрял на этой ошибке ALSA:
pygame.error: ALSA: Couldn't open audio device: No such file or directory

Я точно знаю, что файл является хорошим каталогом, так как загрузка доказывает, что файл существует и ссылается на источник. Локально вы также можете увидеть, как файл генерируется.

Контекст:
Вот мой Dockerfile:

# syntax=docker/dockerfile:1

FROM python:3.9-slim-buster

WORKDIR /appname

COPY requirements.txt requirements.txt
# Added to avoid NotImplemented errors
RUN apt-get update && apt-get install -yq \
    libgtk2.0-dev \  
    libasound2 \
    alsa-tools \
    # Original Run Command
    && pip3 install -r requirements.txt
# && rm -rf /var/lib/apt/lists/* \  # Doesn't work.

COPY . .

EXPOSE 5000

CMD [ "python3", "-m" , "flask", "--app", "appname", "run", "--host=0.0.0.0"]

Вот соответствующий фрагмент моего приложения Flask:

from pygame import mixer

        if request.form.get('playback_midi') and MIDI_file:
            if 'Playback MIDI' in request.form['playback_midi']:
                mixer.init()  # <-- Here is where it fails
                mixer.music.load("temp_MIDI_File.mid")
                mixer.music.play()

"temp_MIDI_File.mid" используется для того, чтобы он постоянно перезаписывался без уникальных имен файлов (которые обрабатываются в другом месте).

Что я пробовал:
В настоящее время я работаю с этими референсами:
Запуск приложений, использующих звук, в контейнере Docker
Запуск pygame в докере

Я думаю, что «Запуск приложений с использованием аудио в контейнере Docker» может иметь там решение, я просто не уверен, может ли такое же решение работать в контексте PaaS (поскольку я не уверен, какое аудиоустройство будет возможно, будет использоваться в этом сценарии облачного хостинга или если у меня даже есть права доступа к нему). Я также открыт для использования другого пакета, кроме Pygame. Спасибо!

Дальнейшие исследования:
Запуск звука в контейнере
Звук контейнера Docker
Советы по Docker — Воспроизведение аудио в контейнере (2022)
Возможно, это лучше всего обрабатывается в JS...

Оставим пока...
Я смог использовать тег html <audio> для успешного создания звука. Все элементы управления работают. Это приводит меня к двум сложным направлениям, на которые у меня совсем нет времени, но я вставлю булавку...

  1. Рендеринг аудиофайлов без устройств. Используя FluidSynth API, возможно, я мог бы преобразовать MIDI в WAV и воспроизвести аудио, используя теги html audio. midi2audio кажется питоническим подходом к этому, но, похоже, он настроен на использование ALSA точно так же, как pygame. API FluidSynth написан на C, поэтому я не знаю, как это связать.
  2. Укажите устройство, которое будет использоваться ALSA в контейнере. Возможно, я мог бы указать --device в Dockerfile, чтобы найти аудиоустройство и использовать полный образ Ubuntu для его запуска.

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

Rabbid76 06.01.2023 20:14

Выполняются ли эти pygame.mixer вызовы как часть кода сервера? Я ожидаю, что у экземпляра Heroku нет пригодного для использования звукового оборудования, не говоря уже о проблемах Docker. То есть я не думаю, что эта настройка будет работать, если браузер и сервер находятся в разных системах, даже если контейнеры не задействованы.

David Maze 06.01.2023 23:56

Да, я тоже так думаю @DavidMaze :( . У меня есть сообщение на форуме PaaS (DigitalOcean), чтобы узнать, есть ли у меня какие-либо варианты. Я надеялся, что смогу запустить docker --device tags и использовать серверную машину /host или что-то в этом роде.Может быть, я мог бы заставить что-то работать, если бы создал дроплет/виртуальную машину...

Christopher Burrows 07.01.2023 07:04
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мое решение:

К счастью, есть отличный html MIDI-плеер, который решил эту проблему:

html-миди-плеер

Вот мой код HTML-шаблона Flask:

{% if MIDI_playback %} 
    <midi-player
     src = "{{  MIDI_playback }}"
     sound-font visualizer = "#myPianoRollVisualizer">
    </midi-player>
    <midi-visualizer type = "piano-roll" id = "myPianoRollVisualizer"
     src = "{{  MIDI_playback }}" style = "color: white">
    </midi-visualizer>
    <script src = "https://cdn.jsdelivr.net/combine/npm/[email protected],npm/@magenta/[email protected]/es`6/core.js,npm/focus-visible@5,npm/[email protected]">
    </script>

Важное примечание:

Используя скрипт в этом приложении Python Flask, я столкнулся с этой ошибкой CORS:

Заголовок Access-Control-Allow-Origin отсутствует в запрошенном ресурс. Поэтому происхождение «http://localhost:3000» не разрешено. доступ. Если непрозрачный ответ соответствует вашим потребностям, установите запрос режим «no-cors», чтобы получить ресурс с отключенным CORS

Мой обходной путь заключался в том, чтобы указать конфигурацию CORS в локальных и производственных экземплярах.

Другие вопросы по теме