首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果播放完全流,Red5 RTMPClient回放示例将开始删除消息。

如果播放完全流,Red5 RTMPClient回放示例将开始删除消息。
EN

Stack Overflow用户
提问于 2012-04-06 18:52:42
回答 1查看 3.3K关注 0票数 3

下面的客户端打算在oflaDemo应用程序上运行,在本地主机上运行red5。它包含了阿凡达电影宣传片。

问题是客户端读取15秒的电影并挂起。为什么?

要编译下面的程序,只需从这里下载red5 http://wiki.red5.org/wiki/1_0_RC1,安装并运行它。打开根页面http://localhost:5080并导航到演示安装页面。安装oflaDemo示例。然后导航到oflaDemo页面并检查它是否工作。

然后,使用red5中的所有jars作为库创建新的Java项目。运行red5运行它。

客户端通过端口1935与服务器通信。

app的结构如下:

1) connect()方法连接到应用程序

2)根据以前操作的结果创建新流;库函数不用于注入自定义流类。

3) createStreamCallback正在注入流的生成结果。

4)自定义流是MyClientStream,它只打印分派的内容。

在我的机器上,它工作到时间戳15203并挂起。

代码语言:javascript
复制
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()版本的行为也是一样的。

代码语言:javascript
复制
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");
    }
    */
};

}

更新2

我发现包在挂起后开始下降。滴法是RTMPProtocolEncoder#dropMessage()

更新3

我看到'tardiness`‘正在以实时的速度增长,当它超过8000的值时,就开始下降。

更新4

更确切地说,在服务器端,进程大约在经过8秒后才开始丢弃数据包。这可能是8000的值,也就是容忍时间。与此同时,数据包时间戳达到了大约15-16秒。客户端在此之前一直在播放,然后才停止。

因此,当服务器超过客户端2次时,当它达到某个限制时,它不会等待,而是开始丢弃数据包。

看来正确的行为会等到客户端到达时间戳,然后继续.

更新5

可能Client类不打算从服务器侦听流,因此不包含适当的同步逻辑?

幻解

在观察使用oflaDemo客户端和我的应用程序播放流时日志中的差异时,我发现标准客户端报告的缓冲区大小为5000 ms,而我的客户端则没有。我不明白这是怎么回事,但是当我将RTMP ping添加到我的应用程序中时,它就开始工作了。魔法线如下

代码语言:javascript
复制
conn.ping(new Ping(Ping.CLIENT_BUFFER, streamId, 5000));

由于它的作用仅仅是通过它的值来改变延迟,我认为总体问题是由于red5错误,这使得它无法正确地计算延迟。

EN

回答 1

Stack Overflow用户

发布于 2012-05-01 17:18:43

一些文件的视频流出现了问题,导致播放停止。但是我已经在服务器中修复了它;使用Version4329或更高版本。供您参考的问题是:http://code.google.com/p/red5/issues/detail?id=200

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10047898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档