Red5 0.9版本实现 的上行带宽检测

转自:http://tomyz0223.iteye.com/blog/855224

一、为什么要带宽检测?

 

在多媒体应用中,尤其在桌面共享应用系统的实现中,带宽检查通常提高用户体验一种依据:

1.可以根据用户的带宽,如果用户的带宽过低,可以降低桌面抓屏的图片的质量,从而减少发送的数据,增强用户使用的稳定性。

2.可以根据用户的带宽,如果带宽比较低,则应该降低抓屏的频率,因为在网络带宽比较差的情况下,如果capture screen频率过高,会造成网络拥堵。此时可以降低capture screen的频率,从而提高用户使用的平滑性,不会造成大的延时。

 

二、如何做带宽检测以及应该注意的问题?

 

检测带宽想想是不是很容易:

一段时间内server接收到数据的byte数 /interval(s)

 

这里需要注意问题和原则:

1.做带宽检查的参考帧,一定要大,太小了误差很大,比如说,以2KB的包为例,可能几毫秒就可以完成,这样得到的数据会非常大

2.带宽检测的检测包在检测过程中要保证数据是一直发送的,例如如果20s之内,只有少量的数据发送,这样计算的结果会偏小

 

在Red5里面要做到带宽检测,需要修改两个地方:

1.需要知道一个桌面视频帧何时开始发送

2.需要知道一个桌面视频帧何时接收完毕

3.需要知道一帧发送开始和结束发送的字节数

 

注:Red5的网络层使用的是Mina作为数据传输层,它有个api专门进行带宽的检测的,它的原理简单说来就是,你告诉它时间点,它告诉你收到了多少数据,显然,有这个api,我们的带宽检查不是问题了

 /**
     * {@inheritDoc}
     */
    public final void updateThroughput(long currentTime, boolean force) {
        int interval = (int) (currentTime - lastThroughputCalculationTime);

        long minInterval = getConfig().getThroughputCalculationIntervalInMillis();
        if (minInterval == 0 || interval < minInterval) {
            if (!force) {
                return;
            }
        }

        readBytesThroughput = (readBytes - lastReadBytes) * 1000.0 / interval;
        writtenBytesThroughput = (writtenBytes - lastWrittenBytes) * 1000.0 / interval;
        readMessagesThroughput = (readMessages - lastReadMessages) * 1000.0 / interval;
        writtenMessagesThroughput = (writtenMessages - lastWrittenMessages) * 1000.0 / interval;

        lastReadBytes = readBytes;
        lastWrittenBytes = writtenBytes;
        lastReadMessages = readMessages;
        lastWrittenMessages = writtenMessages;

        lastThroughputCalculationTime = currentTime;
    }

 

 

三、修改Red5源码达到带宽检测的效果

 

有两个时间点,我们就可以大胆做了:

1.在上一个数据帧decode完毕后,做个check point

在org.red5.server.net.rtmp.BaseRTMPHandler类中messageReceived方法末尾加上:

/** {@inheritDoc} */
    public void messageReceived(RTMPConnection conn, ProtocolState state, Object in) throws Exception {

log.info("Begin to calculate the bandwidth======");
        RTMPMinaConnection connC = (RTMPMinaConnection) Red5
        .getConnectionLocal();
        final IoSession session = connC.getIoSession();
        session.updateThroughput(System.currentTimeMillis(), true);

 

2.在一个视频数据帧收发完毕后,做个check point

修改 org.red5.server.net.rtmp.codec.RTMPProtocolDecoder,增加以下红色部分的代码;

public List<Object> decodeBuffer(ProtocolState state, IoBuffer buffer) {
-------- 省略了部分代码
                if (state.hasDecodedObject()) {
                    if (decodedObject != null) {
                        
                        if(decodedObject instanceof Packet ){
                            Header header = ((Packet) decodedObject).getHeader();
                            log.info("The check package size is====="+header.getSize()/1024+"KB.");
                            if(header.getDataType()==TYPE_VIDEO_DATA && header.getSize()>(100*1024)){
                                session.updateThroughput(System.currentTimeMillis(), true);
                                log.info("The bandwidth is ====="+session.getReadBytesThroughput()/1024d+"KB/s");
                            }
                        }
 
                        result.add(decodedObject);
                    }


你可能感兴趣的:(Red5 0.9版本实现 的上行带宽检测)