Написание Python Music Streamer - PullRequest
       34

Написание Python Music Streamer

22 голосов
/ 16 апреля 2011

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

Ранее я реализовал свой собственный HTTP-сервер в Python, используя SocketServer.TCPServer (да, я знаю, что BaseHTTPServer существует, я просто хотел написать мини-стек HTTP самостоятельно), так как музыкальный стример будет отличаться архитектурно? Какие библиотеки мне нужно посмотреть на стороне сети и на стороне MP3?

Ответы [ 5 ]

35 голосов
/ 18 января 2013

Формат mp3 был разработан для потоковой передачи, что делает некоторые вещи проще, чем вы могли ожидать.По сути, данные представляют собой поток звуковых кадров со встроенными граничными маркерами, а не заголовок файла, за которым следуют необработанные данные.Это означает, что, как только клиент ожидает получения аудиоданных, вы можете просто начать отправку его байтов из любой точки существующего источника MP3, будь то живой или файл, и клиент будет синхронизироваться до следующего найденного кадра иначать воспроизведение аудио.Yay!

Конечно, вам придется дать клиентам способ установить соединение.Фактическим стандартом является протокол 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 сопрограммы.

1 голос
/ 24 января 2013

Поскольку у вас уже есть хороший опыт работы с Python (учитывая, что вы уже написали HTTP-сервер), я могу лишь дать несколько советов о том, как расширить основную работу, которую вы уже сделали:

  • Подготовьте свой сервер к работе с заголовками запросов , например: Accept-Encoding, Range, TE (Transfer Encoding) и т. Д. Проигрыватель MP3-over-HTTP (то есть VLC) - это не что иное, как mp3-плеер, который умеет «говорить» по HTTP и «искать» разные позиции в файле.

  • Используйте wireshark или tcpdump для прослушивания фактических HTTP-запросов, выполняемых VLC при воспроизведении mp3 по HTTP, чтобы вы знали, какие заголовки запросов вы будете получать, и реализуйте их.

Удачи в вашем проекте!

0 голосов
/ 29 апреля 2011

Изучите их, прежде чем заходить слишком далеко:

http://wiki.python.org/moin/PythonInMusic

В частности

http://edna.sourceforge.net/

0 голосов
/ 17 января 2013

Вам понадобится файл .m3u или .pls, который указывает на статический URI (например, http://example.com/now_playing.mp3), а затем дает им данные в формате mp3, начиная с того места, где вы находитесь в песне, когда они запрашивают этот файл. Возможно, здесь есть несколько мелких проблем, о которых я здесь говорю ... Однако, по крайней мере, как указывает лес, вы можете просто начать потоковую передачу данных mp3 с любого байта.

0 голосов
/ 22 апреля 2011

Вы захотите посмотреть файлы m3u или pls .Это должно дать вам формат файла, который игроки понимают достаточно хорошо, чтобы попасть на ваш http-сервер в поисках mp3-файлов.

Минимальный файл m3u - это простой текстовый файл с одним URL-адресом песни на строку.Предполагая, что у вас есть следующие URL-адреса, доступные на вашем сервере:

/playlists/<playlist_name/playlist_id>
/songs/<song_name/song_id>

Вы бы обслуживали список воспроизведения с URL:

/playlists/myfirstplaylist

И содержимое ресурса было бы просто:

/songs/1
/songs/mysong.mp3

Плеер (например, Winamp) сможет открыть URL-адрес файла m3u на вашем HTTP-сервере, а затем начнет потоковую передачу первой песни в списке воспроизведения.Все, что вам нужно сделать, чтобы поддержать это, это подать mp3-файл, как и любой другой статический контент.

В зависимости от того, сколько клиентов вы хотите поддерживать, вы можете захотеть изучить асинхронный ввод-вывод, используя такую ​​библиотеку, как Twisted для поддержки множества одновременных потоков.

...