8

librtmp ライブラリを使用してストリームを公開するには? librtmp の man ページを読み、公開するために RTMP_Write() を使用しています。

私はこのようにしています。

//Code
//Init RTMP code
RTMP *r;
char uri[]="rtmp://localhost:1935/live/desktop";
r= RTMP_Alloc();
RTMP_Init(r);
RTMP_SetupURL(r, (char*)uri);
RTMP_EnableWrite(r);
RTMP_Connect(r, NULL);
RTMP_ConnectStream(r,0);

次に、サーバーからのping/その他のメッセージに応答するために、スレッドを使用して次のように応答しています:

//Thread
While (ThreadIsRunning && RTMP_IsConnected(r) && RTMP_ReadPacket(r, &packet))
{
   if (RTMPPacket_IsReady(&packet))
   {
 if (!packet.m_nBodySize)
         continue;
    RTMP_ClientPacket(r, &packet); //This takes care of handling ping/other messages
    RTMPPacket_Free(&packet);
   }
}

この後、RTMP_Write() を使用してファイルを Wowza メディア サーバーに公開する方法に行き詰まっていますか?

4

2 に答える 2

9

私自身の経験では、RTMPサーバーへのビデオデータのストリーミングは、実際にはlibrtmp側では非常に簡単です。トリッキーな部分は、ビデオ/オーディオデータを正しくパケット化し、正しいレートで読み取ることです。

FLVビデオファイルを使用していると仮定すると、ファイル内の各タグを正しく分離し、1回のRTMP_Write呼び出しで各タグを送信できる限り、着信パケットを処理する必要はありません。

トリッキーな部分は、FLVファイルがどのように作成されるかを理解することです。公式仕様はこちらから入手できます:http ://www.adobe.com/devnet/f4v.html

まず、9バイトで構成されるヘッダーがあります。このヘッダーはサーバーに送信する必要はありませんが、ファイルが実際にFLVであることを確認するために読み飛ばすだけです。

次に、タグのストリームがあります。各タグには、タグタイプ(ビデオ/オーディオ/メタデータ)、本文の長さ、タグのタイムスタンプなどを含む11バイトのヘッダーがあります。

タグヘッダーは、次の構造を使用して記述できます。

typedef struct __flv_tag {
  uint8       type;
  uint24_be   body_length; /* in bytes, total tag size minus 11 */
  uint24_be   timestamp; /* milli-seconds */
  uint8       timestamp_extended; /* timestamp extension */
  uint24_be   stream_id; /* reserved, must be "\0\0\0" */
  /* body comes next */
} flv_tag;

本体の長さとタイムスタンプは24ビットのビッグエンディアン整数として表示され、必要に応じてタイムスタンプを32ビットに拡張するための補助バイトが付いています(これは約4時間のマークです)。

タグヘッダーを読み取ったら、本体の長さ(body_length)がわかったので、本体自体を読み取ることができます。

その後、タグの完全な長さ(11バイト+ body_length)を含む32ビットのビッグエンディアン整数値があります。

1回の 呼び出しでタグヘッダー+本文+前のタグサイズを書き込む必要がありRTMP_Writeます(そうでない場合は再生されません)。

また、ビデオの公称フレームレートでパケットを送信するように注意してください。そうしないと、再生が大幅に低下します。

参照として使用できるGPLプロジェクトFLVmetaの一部として、完全なFLVファイルデマルチプレクサを作成しました。

于 2012-12-10T14:41:24.083 に答える
0

実際、RTMP_Write() では、RTMP パケットが buf で既に形成されている必要があるようです。

RTMPPacket *pkt = &r->m_write;
...
pkt->m_packetType = *buf++;

そのため、そこに flv データをプッシュすることはできません。最初にそれをパケットに分割する必要があります。

RTMP_ReadPacket() という便利な関数がありますが、これはネットワーク ソケットから読み取ります。

私はあなたと同じ問題を抱えています。すぐに解決できることを願っています。

編集:

RTMP_Write() には特定のバグがあります。パッチを作成したところ、動作するようになりました。それを公開します。

于 2011-03-15T14:57:09.720 に答える