UDPホールパンチングをつかえばP2Pができる、ただしUDPのパケットはすべて確実に送信されるわけではない・・・
red5_phpのBroadcastStreamを改善するときに、H.264やVP6の動画データを扱う場合はヘッダ情報をRed5の内部データに登録しておかないと、再生がうまくできないという問題があったので、UDPでH.264やVP6の映像のやりとりをするときにヘッダ情報がきちんとおくれないと動作しないのでは?という懸念があります。
というわけでUDPホールパンチングではないけど、パケットロスを適当におりまぜてやった場合に動画がどうなるか・・・やってみました。
まずはソースコード
public class Application extends ApplicationAdapter{
private BroadcastStream gstream;
@Override
public boolean appStart(IScope scope) {
gstream = new BroadcastStream("error");
gstream.setScope(scope);
IProviderService providerService = (IProviderService)this.getContext().getBean(IProviderService.BEAN_NAME);
if(providerService.registerBroadcastStream(scope, "error", gstream)) {
IBroadcastScope bsScope = (BroadcastScope)providerService.getLiveProviderInput(scope, "error", true);
bsScope.setAttribute(IBroadcastScope.STREAM_ATTRIBUTE, gstream);
}
gstream.start();
return super.appStart(scope);
}
@Override
public void streamBroadcastStart(IBroadcastStream stream) {
stream.addStreamListener(new IStreamListener() {
private boolean first = false;
@Override
public void packetReceived(IBroadcastStream stream, IStreamPacket packet) {
if(packet instanceof IRTMPEvent) {
if(!first) {
first = true;
return;
}
else {
first = false;
}
gstream.dispatchEvent((IRTMPEvent)packet);
}
});
super.streamBroadcastStart(stream);
}
}
これとは別にred5_phpのリポジトリにいれてあるBroadcastStreamが必須。
やっていることはアプリが生成されたときに、errorという名前のストリームを作成する。
なんらかの放送がはじまったらストリームパケットをerrorのストリームに受け流す。
(ただしfirstのフラグで適度に邪魔してやる。)
結果は実際にやってみてみてもらえればいいと思いますが
FLV1の場合。普通にみれる動画になった。(音声は不明)
VP6の場合。ピンクや青の四角いのが大量にわいてきた。ffmpegのエンコードミスしたときみたいなやつ。静止画にするとそれなりの絵になる。
H.264の場合。よくわからんもやもやがついてきた。これもエンコ失敗したときにでてくるやつっぽい感じ。
VP6にしろH.264にしろ画像がでてこないという現象はとりあえずなかった。
前のプログラムを組んだときの手応えからすると、画像がうつらないという結果を期待したのだが・・・
ちょっと組んでためしただけなので、確定ではないですが、仮にUDPでP2Pの生放送をつくった場合高画質を狙うと回線の状態とかによると、めちゃくちゃな映像のやりとりになる可能性あり・・・みたいですね。
0 件のコメント:
コメントを投稿