に行われた後、whileループを継続するタスクを使用する必要があるのawaitキーワード
theSubscriber.WriteAsync
なしで実行を取得する必要があります密接
ほとんどのファイル形式は、特にビデオ形式、構造化されています。彼らは、フレーム(圧縮形式に応じて、すなわち、完全なまたは部分的なスクリーンショット)を含有します。
あなたが新しい加入者にストリーミングを開始するとき、特定のフレームを打つために管理する場合は、本当に幸運でなければなりません。したがって、ストリームの受信を開始すると、フレームが部分的であるため、フォーマットを識別できません。
あなたはwikipedia articleでより多くのFLVフレームを読み取ることができます。これはおそらくあなたの問題です。
簡単な試みは、第1の加入者が接続しているときに、ストリーミングサーバから受信した最初のヘッダを保存しようとするだろう。あなたは次の接続加入者にヘッダを送信することができます
static byte _header = new byte[9]; //signature, version, flags, headerSize
public void YourStreamMethod()
{
int bytesRec = handler.Receive(bytes);
if (!_headerIsStored)
{
//store header
Buffer.BlockCopy(bytes, 0, _header, 0, 9);
_headerIsStored = true;
}
}
..::のような
何か一度行わ
private async Task WriteToStream(Stream arg1, HttpContent arg2, TransportContext arg3)
{
// send the FLV header
arg1.Write(_header, 0, 9);
Startup.AddSubscriber(arg1);
await Task.Yield();
}
、受信機は部分的フレームを無視することを祈ります。そうでない場合は、ストリームを分析して次のフレームの場所を特定する必要があります。
BytesLeftToNextFrame
変数を作成します:あなたはこのような何かをする必要があることを行うには 。
- ストアバッファ
- で受信したパケットのヘッダint型
- に「ペイロードサイズ」ビットの変換では、ヘッダーを読み取る必要があり、次回まで
BytesLeftToNextFrame
-
解析された値へのカウントダウンをリセットします。
最後に、新しいクライアントが接続すると、次のフレームが到着することを知るまでストリーミングを開始しないでください。
擬似コード:
var bytesLeftToNextFrame = 0;
while (true)
{
bytes = new byte[8024000];
int bytesRec = handler.Receive(bytes);
foreach (var subscriber in Startup.Subscribers.ToList())
{
var theSubscriber = subscriber;
try
{
if (subscriber.IsNew && bytesLeftToNextFrame < bytesRec)
{
//start from the index where the new frame starts
await theSubscriber.WriteAsync(bytes, bytesLeftToNextFrame, bytesRec - bytesLeftToNextFrame);
subscriber.IsNew = false;
}
else
{
//send everything, since we've already in streaming mode
await theSubscriber.WriteAsync(bytes, 0, bytesRec);
}
}
catch
{
Startup.Subscribers.Remove(theSubscriber);
}
}
//TODO: check if the current frame is done
// then parse the next header and reset the counter.
}
は、シンプルなFLVメタデータリーダーを発見しました – jgauffin