Формат mp3 был разработан для потоковой передачи, что делает некоторые вещи проще, чем вы могли ожидать. Данные представляют собой поток аудиокадров со встроенными граничными маркерами, а не чем заголовок файла, за которым следуют необработанные данные. Это означает, что как только клиент ожидает получить аудиоданные, вы можете просто начать отправлять ему байты из любой точки существующего источника mp3, будь то живой или файл, и клиент будет синхронизироваться со следующим найденным кадром и начать воспроизведение аудио. Ура!
Конечно, вам придется предоставить клиентам возможность установить соединение. Стандартом де-факто является протокол SHOUTcast (ICY). Это очень похоже на HTTP, но поля состояния и заголовка настолько отличаются, что несовместимы напрямую со встроенными библиотеками http-сервера Python. Вы могли бы заставить эти библиотеки сделать часть работы за вас, но их документированных интерфейсов будет недостаточно, чтобы сделать это; вам придется прочитать их код, чтобы понять, как заставить их говорить SHOUTcast.
Вот несколько ссылок для начала:
http://forums.winamp.com/showthread.php?threadid=70403
http://forums.radiotoolbox.com/viewtopic.php?t=74
http://www.smackfu.com/stuff/programming/shoutcast.html
http://en.wikipedia.org/wiki/Shoutcast
Я предлагаю начать с одного mp3-файла в качестве источника данных, настроить соединение клиент-сервер и запустить воспроизведение, а затем перейти к таким проблемам, как живые источники, несколько битрейтов кодирования, внутриполосные метаданные и списки воспроизведения.
Списки воспроизведения обычно представляют собой файлы .pls или .m3u и, по сути, просто статические текстовые файлы, указывающие на URL-адрес вашего прямого эфира. Они не сложны и даже не обязательны, поскольку многие (большинство?) потоковых mp3-клиентов будут принимать URL-адрес прямой трансляции вообще без плейлиста.
Что же касается архитектуры, то поле здесь довольно широкое. У вас столько же вариантов, сколько и для HTTP-серверов. Резьбовой? Рабочие процессы? События? Тебе решать. Для меня более интересным является вопрос, как разделить данные из одного входного потока (вещателя) с сетевыми обработчиками, обслуживающими несколько выходных потоков (проигрыватели). Чтобы избежать сложностей с IPC и синхронизацией, я бы, вероятно, начал с однопоточного дизайна, управляемого событиями. В Python 2 такая библиотека, как gevent, даст вам очень хорошая производительность ввода-вывода, позволяя вам структурировать свой код очень понятным образом. В python 3 я бы предпочел сопрограммы asyncio.
person
ʇsәɹoɈ
schedule
18.01.2013