问题
我以这种方式在基于 oflaDemo 的自定义应用程序中创建并启动了 Red5 服务器端流:
serverStream = StreamUtils.createServerStream( app , "mystream" );
// repeats /streams/prometheus.flv from oflaDemo several times (20sec):
serverStream.addItem( SimplePlayItem.build( "prometheus" , 0 , 20000 ) );
serverStream.addItem( SimplePlayItem.build( "prometheus" , 0 , 20000 ) );
// now I want to add "camsource" stream, wich is published from Flash client:
serverStream.addItem( SimplePlayItem.build( "camsource" , 0 , 20000 ) );
...
serverStream.play();
prometheus.flv 可以很好地播放 2 倍,但是当“camsource”时间到来时,结果是:
[Red5_Scheduler_Worker-3] org.red5.server.stream.ProviderService - Exception attempting to lookup file: ServletContext resource [/streams/camsource.flv] cannot be resolved to URL because it does not exist
如何创建重新发布从 Flash 客户端发布的用户流的 IServerStream?
我可以在 Flash 中看到 flv 流和 cam 流NetStream .play(...),但我无法以编程方式创建 IServerStream 以从实时源发布。
comsource发布和在serverStream同一个范围内。
我目前的工作路径
由于Red5 group 上的此响应,我创建了自己的 ServerStream,我可以在其中手动推送重定向/伪造数据包(我不确定这是否正确完成):
public static class LiveTVServerStream extends ServerStream {
public void manuallyPushPacket( IStreamPacket packet ) {
for ( IStreamListener listener : getStreamListeners() ) {
listener.packetReceived( this , packet );
}
}
}
然后我创建这样的流并将其注册在appStart():
liveTVServerStream = new LiveTVServerStream();
liveTVServerStream.setScope( appScope );
liveTVServerStream.setName( "livetv" );
liveTVServerStream.setPublishedName( "livetv" );
// Add single starting video because ServerStream requires at least 1 item
liveTVServerStream.addItem( SimplePlayItem.build( "prometheus" , 0 , 20000 ) );
liveTVServerStream.start();
IContext context = scope.getContext();
IProviderService providerService = (IProviderService) context.getBean( IProviderService.BEAN_NAME );
providerService.registerBroadcastStream( scope , "livetv" , liveTVServerStream);
然后,如果我的“新闻记者”(来自网络摄像头的 Flash 视频源)开始广播,我会将数据包重定向到liveTVServerStream:
public void streamPublishStart( final IBroadcastStream stream ) {
if ( !stream.getPublishedName().equals( "newsreporter" ) ) {
return;
}
logInfo( "News reporter connected - redirecting packets" );
stream.addStreamListener( new IStreamListener() {
volatile int dispatchedPacketCount = 0;
volatile int ignoredPacketCount = 0;
@Override
public void packetReceived( IBroadcastStream newsReporterStream , IStreamPacket packet ) {
if ( packet instanceof IRTMPEvent ) {
dispatchedPacketCount++;
if ( (dispatchedPacketCount % 50) == 0 ) {
logInfo( "Dispatched packets: " + dispatchedPacketCount + " ignored packets: " + ignoredPacketCount );
}
// delta-time calculations
long t1 = newsReporterStream.getCreationTime();
long t2 = liveTVServerStream.getCreationTime();
long delta = t2 - t1;
int t3 = ((IRTMPEvent) packet).getTimestamp();
t3 += delta;
((IRTMPEvent) packet).setTimestamp( t3 );
liveTVServerStream.manuallyPushPacket( packet );
} else {
ignoredPacketCount++;
}
}
} );
当前结果
Red5 控制台的日志可以在这里找到。
“新闻记者”闪光灯工作正常 - 从网络摄像头发送视频。但是当我订阅观看“livetv”流时,没有视频。Flash 部件工作 - 对其进行了测试,其中ServerStream包含队列中的多个 .flv 文件,并且 Flash 连接和流式传输正确,例如直播电视。