Подтвердить что ты не робот

Запись музыкального потока Python

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

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

4b9b3361

Ответ 1

Формат 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, даст вам очень хороший I/O, позволяя вам структурировать код очень понятным образом. В python 3 я бы предпочел asyncio сопрограммы.

Ответ 2

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

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

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

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

Ответ 3

Вы хотите посмотреть на 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, чтобы поддерживать тонны одновременные потоки.

Ответ 5

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