Java 如果播放全流,Red5 RTMPClient播放示例将开始删除消息
下面的客户端旨在运行在本地主机上的red5上的Lademo应用程序。它包含阿凡达电影宣传片 问题是客户端读取15秒的电影并挂起。为什么? 要编译下面的程序,只需从这里下载red5,安装并运行它。打开根目录页并导航到演示安装页。安装Lademo的Java 如果播放全流,Red5 RTMPClient播放示例将开始删除消息,java,streaming,red5,playback,rtmp,Java,Streaming,Red5,Playback,Rtmp,下面的客户端旨在运行在本地主机上的red5上的Lademo应用程序。它包含阿凡达电影宣传片 问题是客户端读取15秒的电影并挂起。为什么? 要编译下面的程序,只需从这里下载red5,安装并运行它。打开根目录页并导航到演示安装页。安装Lademo的示例。然后导航到oflaDemo页面并检查它是否正常工作 然后创建新的Java项目,将red5中的所有JAR作为库。用红色5运行它 客户端通过端口1935与服务器通信 应用程序的结构如下: 1) connect()方法连接到应用程序 2) connectC
示例。然后导航到oflaDemo页面并检查它是否正常工作
然后创建新的Java项目,将red5中的所有JAR作为库。用红色5运行它
客户端通过端口1935与服务器通信
应用程序的结构如下:
1) connect()
方法连接到应用程序
2) connectCallback
根据上一个操作的结果创建新流;库函数不用于注入自定义流类
3) createStreamCallback
它正在注入流创建的结果
4) 自定义流是MyClientStream
;它只是打印发送的内容
在我的机器上,它工作到时间戳15203并挂起
public class SSCCE_RTMPPlayer extends RTMPClient{
private String server = "localhost";
private int port = 1935;
private String application = "oflaDemo";
private String filename = "avatar.flv";
private static boolean finished = false;
public static void main(String[] args) throws InterruptedException {
final SSCCE_RTMPPlayer player = new SSCCE_RTMPPlayer ();
player.connect();
synchronized( SSCCE_RTMPPlayer.class ) {
if( !finished ) SSCCE_RTMPPlayer.class.wait();
}
System.out.println("Ended");
}
public void connect() {
connect(server, port, application, connectCallback);
setExceptionHandler(new ClientExceptionHandler() {
@Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
}
});
}
private IPendingServiceCallback connectCallback = new IPendingServiceCallback() {
@Override
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
invoke("createStream", null, createStreamCallback);
}
};
private IPendingServiceCallback createStreamCallback = new IPendingServiceCallback() {
@Override
public void resultReceived(IPendingServiceCall call) {
Integer streamIdInteger = (Integer) call.getResult();
MyClientStream myClientStream = new MyClientStream();
myClientStream.setStreamId(streamIdInteger.intValue());
myClientStream.setConnection(conn);
conn.addClientStream(myClientStream);
play(streamIdInteger.intValue(), filename, 0, -2);
}
};
protected void onInvoke(RTMPConnection conn, Channel channel, Header header, Notify notify, RTMP rtmp) {
super.onInvoke(conn, channel, header, notify, rtmp);
System.out.println("onInvoke, header = " + header.toString());
System.out.println("onInvoke, notify = " + notify.toString());
System.out.println("onInvoke, rtmp = " + rtmp.toString());
};
public static class MyClientStream extends AbstractClientStream implements IEventDispatcher {
@Override
public void start() {
// TODO Auto-generated method stub
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void close() {
// TODO Auto-generated method stub
}
@Override
public void dispatchEvent(IEvent event) {
System.out.println("AudioListenerClientStream.dispachEvent()" + event.toString());
}
}
}
更新1
使用传统的setStreamEventDispatcher()
的版本的行为方式相同
public class SSCCE_RTMPPlayer2 extends RTMPClient {
private String server = "localhost";
private int port = 1935;
private String application = "oflaDemo";
private String filename = "avatar.flv";
private static boolean finished = false;
public static void main(String[] args) throws InterruptedException {
final SSCCE_RTMPPlayer2 player = new SSCCE_RTMPPlayer2();
player.connect();
synchronized( SSCCE_RTMPPlayer.class ) {
if( !finished ) SSCCE_RTMPPlayer.class.wait();
}
System.out.println("Ended");
}
public void connect() {
setExceptionHandler(new ClientExceptionHandler() {
@Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
}
});
setStreamEventDispatcher(streamEventDispatcher);
connect(server, port, application, connectCallback);
}
private IEventDispatcher streamEventDispatcher = new IEventDispatcher() {
@Override
public void dispatchEvent(IEvent event) {
System.out.println("AudioListenerClientStream.dispachEvent()" + event.toString());
}
};
private IPendingServiceCallback connectCallback = new IPendingServiceCallback() {
@Override
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
createStream(createStreamCallback);
}
};
private IPendingServiceCallback createStreamCallback = new IPendingServiceCallback() {
@Override
public void resultReceived(IPendingServiceCall call) {
Integer streamIdInteger = (Integer) call.getResult();
play(streamIdInteger.intValue(), filename, 0, -2);
}
};
protected void onInvoke(RTMPConnection conn, Channel channel, Header header, Notify notify, RTMP rtmp) {
super.onInvoke(conn, channel, header, notify, rtmp);
System.out.println("onInvoke, header = " + header.toString());
System.out.println("onInvoke, notify = " + notify.toString());
System.out.println("onInvoke, rtmp = " + rtmp.toString());
/*
ObjectMap<String, String> map = (ObjectMap) notify.getCall().getArguments()[0];
String code = map.get("code");
if (StatusCodes.NS_PLAY_STOP.equals(code)) {
synchronized( SSCCE_RTMPPlayer.class ) {
finished = true;
SSCCE_RTMPPlayer.class.notifyAll();
}
disconnect();
System.out.println("Disconnected");
}
*/
};
}
由于它的作用仅仅是根据它的值来改变拖期,所以我认为整个问题是由于red5 bug造成的,这使得它无法正确计算拖期 某些文件的视频流出现问题,导致播放停止。但我已经在服务器上修复了它;使用修订版4329或更高版本。供您参考的问题如下:如果您或任何人对改进计算有任何想法,我很乐意听取。
conn.ping(new Ping(Ping.CLIENT_BUFFER, streamId, 5000));