web-dev-qa-db-ja.com

Pythonミュージックストリーマーを書く

Pythonで、HTTP経由でMP3形式で音楽をストリーミングするサーバーを実装したいと思います。クライアントがストリームに接続して何でも聴き始めることができるように音楽をブロードキャストしたいと思います。ラジオ局のように、現在再生中です。

以前、私はSocketServer.TCPServerを使用してPythonに独自のHTTPサーバーを実装しました(はい、BaseHTTPServerが存在することは知っていますが、ミニHTTPスタックを自分で作成したかっただけです)。アーキテクチャが異なりますか?ネットワーク側とMP3側でどのライブラリを確認する必要がありますか?

24
AJ.

Mp3形式はストリーミング用に設計されているため、予想よりも簡単なことがいくつかあります。データは基本的に、ファイルヘッダーの後に生データが続くのではなく、境界マーカーが組み込まれた オーディオフレーム のストリームです。つまり、クライアントがオーディオデータの受信を期待している場合は、ライブかファイルかに関係なく、既存のmp3ソースの任意のポイントからバイトを送信し始めることができ、クライアントは検出した次のフレームに同期します。オーディオの再生を開始します。わーい!

もちろん、接続を設定する方法をクライアントに提供する必要があります。デファクトスタンダードはSHOUTcast(ICY)プロトコルです。これはHTTPに非常によく似ていますが、ステータスフィールドとヘッダーフィールドが十分に異なるため、Pythonの組み込みhttpサーバーライブラリと直接互換性がありません。あなたはそれらのライブラリにあなたのためにいくつかの仕事をさせることができるかもしれません、しかしそれらの文書化されたインターフェースはそれを成し遂げるのに十分ではありません。彼らにSHOUTcastを話させる方法を理解するには、彼らのコードを読む必要があります。

開始するためのリンクは次のとおりです。

http://forums.winamp.com/showthread.php?threadid=704

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、私はasynciocoroutinesを好みます。

38
ʇsәɹoɈ

あなたはすでに良いpython経験を持っているので(あなたがすでにHTTPサーバーを書いているとすれば)私はあなたがすでに行った基礎を拡張する方法についてのいくつかの指針しか提供できません:

  • サーバーの準備リクエストヘッダーの処理次のように:_Accept-Encoding_、RangeTE (Transfer Encoding)など。MP3-over-HTTPプレーヤー(つまりVLC) )は、HTTPを「話す」方法と、ファイル内のさまざまな位置に「探す」方法を知っているmp3プレーヤーに他なりません。

  • Mp3 over HTTPを再生するときは、wiresharkまたはtcpdumpを使用してVLCによって実行された実際のHTTPリクエストをスニッフィングなので、どのリクエストヘッダーを受信して​​実装するかがわかります。

あなたのプロジェクトで頑張ってください!

1
Oerd

m または pls ファイルの提供を検討する必要があります。これにより、プレーヤーがhttpサーバーでmp3ファイルを探すのに十分な理解が得られるファイル形式が得られるはずです。

最小限のm3uファイルは、1行に1曲のURLを持つ単純なテキストファイルです。サーバーで次のURLを使用できると仮定します。

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

次のURLからプレイリストを提供します。

/playlists/myfirstplaylist

そして、リソースの内容は次のようになります。

/songs/1
/songs/mysong.mp3

プレーヤー(Winampなど)は、HTTPサーバー上のm3uファイルへのURLを開くことができ、プレイリストの最初の曲のストリーミングを開始します。これをサポートするために必要なのは、他の静的コンテンツを提供するのと同じようにmp3ファイルを提供することだけです。

サポートするクライアントの数に応じて、非同期IO Twisted などのライブラリを使用して大量の同時ストリームをサポートすることを検討することをお勧めします。

0
stderr

行き過ぎる前にこれらを研究してください:

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

具体的には

http://edna.sourceforge.net/

0
qneill

静的URIを指す.m3uまたは.plsファイル(例: http://example.com/now_playing.mp )を作成し、どこにいてもmp3データを提供する必要があります。彼らがそのファイルを要求したときの曲。おそらく、私がここで説明している小さな問題がたくさんあります...しかし、少なくともフォレストが指摘しているように、任意のバイトからmp3データのストリーミングを開始できます。

0
mike