问题
我以这种方式在基于 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 连接和流式传输正确,例如直播电视。