Red5视频服务器中监控视频的记录

2015年07月31日   /  

red5-recorder

Red5 是一个Java实现的开源Flash服务器,它支持:

·        
视频流(FLV, F4V, MP4, 3GP

·        
音频流(MP3, F4A, M4A, AAC)

·        
记录客户端推送的流(FLV容器中的FLVAVC+AAC)

 

请猛戳这里

 

本文中,我们将尝试在Red5服务器中实现一个限制记录视频尺寸的简单逻辑。如果一个记录中的视频文件增长超过100MB,我们就停止记录并通知客户端。

 

Red5服务器是基于一个嵌入式的Tomcat服务器,它有一个包含不同“scope”的层次,一个运行于Red5服务器的程序应该是一个带web.xml声明的Java web应用,并定义它自己的“scope”来接入到Red5服务器的Scope中。

 

web.xml (因为Red5服务器1.0.5版基于Tomcat 7,它支持Servlet3.0标准。)

<?xml version="1.0"
encoding="ISO-8859-1"?>

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
>

 

    <display-name>video_app</display-name>

 

    <filter>

        <filter-name>encodingFilter</filter-name>

        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <init-param>

            <param-name>encoding</param-name>

            <param-value>UTF-8</param-value>

        </init-param>

        <init-param>

            <param-name>forceEncoding</param-name>

            <param-value>true</param-value>

        </init-param>

    </filter>

    <filter-mapping>

        <filter-name>encodingFilter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

    <context-param>

        <param-name>globalScope</param-name>

        <param-value>default</param-value>

    </context-param>

    <context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>/WEB-INF/red5-*.xml</param-value> <!—引用red5-*.xml配置文件–>

    </context-param>

<!—other configurations–>

</web-app>

 

Red5服务器也是一个基于Spring的应用;开发者可以用SpringRed5服务器中扩展/织入业务逻辑。

我们也可以直接利用Red5服务器的Spring库,例如把这一段maven依赖加入到(假定是)maven项目的pom.xml文件中。

 

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context</artifactId>

            <version>4.0.8.RELEASE</version> <!–  for red5 1.0.5
–>

            <scope>provided</scope>

</dependency>

 

Web.xml中引用的red5-*.xml配置文件实际上是Spring配置文件,可以被Red5服务器识别和加载。

 

<?xml version="1.0"
encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

   
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xmlns:lang="http://www.springframework.org/schema/lang"

        xmlns:context="http://www.springframework.org/schema/context"

        xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

       
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang-3.1.xsd

       
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd"
>

 

<!–

上下文, 当一个Spring应用程序的上下文中包含着多个上下文时,每个上下文都应当被指定一个唯一的名字.

Web根上下文被命名为web.context, 其他上下文根据这个名字加上各自的web应用程序名; 例如video_app的上下文

可以命名成web.context.video_app. web上下文中的子上下文可以配置成以下样子.

–>

    <bean id=" web.context.video_app" class="org.red5.server.Context"
autowire="byType">

        <property name="clientRegistry" ref="global.clientRegistry" />

       

        <!—执行客户端调用的接口引用. –>

        <!—进行远端调用,服务调用,解析系统处理模块 –>

        <property name="serviceInvoker" ref="global.serviceInvoker" />

    </bean>    

   

    <bean id="video_app.handler" class="your.video.app.handler.Application"/>

   

<!— 一个scope包含以下属性:

1.  服务器: 引用red5.server

2.  scope: 当前scope的上级通常是global.scope

        3.
上下文: 当前scope的上下文

        4.
处理模块: 当前scope的处理模块

        5.
上下文路径: 连接到这个scope时用到的路径.

        6.
虚拟主机: 一组逗号分隔的主机名或者ip地址. Scope监听在这些地址上–>

 

    <bean id="web.scope" class="org.red5.server.scope.WebScope">

        
<!—
代表Red5服务器的接口 –>

        <property name="server"
ref="red5.server" />

       

        <!– org.red5.server.scope.BasicScope.parent –>

        <!—上级scope –>

        <property name="parent"
ref="global.scope"
/>

       

        <!—当前上下文, 这个对象会包装Spring上下文. –>

        <property name="context"
ref="video_app.context"
/>

       

        <!–

        
Scope
处理模块控制在scope对象上执行的操作, 并且接受事件通知.

        
通过实现can*方法控制什么操作可以执行.
        
通过on*方法来得到scope的状态.

        
这个接口是实现用户逻辑的核心接口.

        
可以通过Red5对象来取得线程本地连接.

         –>

        <property name="handler"
ref="video_app.handler"
/>

        <property name="contextPath" value="/video_app" />

        <property name="virtualHosts" value="*"
/>     

       

    </bean>

 

    <bean id="clientBroadcastStream"
class="your.video.app.YourClientBroadcastStream"
lazy-init="true"
scope="prototype">

        <property name="sizeLimit"
value="104857600" />

        <!– 100MB –>

    </bean>

</beans>

 

为了能监控flash视频记录,我们可以创建一个子类:

 

/**

 * 代表一个从客户端来的直播视频流. 作为一个Flash媒体服务器, Red5支持从直播流中记录. 广播流可以是直播或者记录”, Red5服务器可以在记录模式中记录视频流.
*/

org.red5.server.stream.ClientBroadcastStream

 

在子类中我们可以实现检查接受到的数据大小的逻辑。

 

Your.video.app.YourClientBroadcastStream

public class YourClientBroadcastStream
extends ClientBroadcastStream
{

    public final static String NS_RECORD_STOP_OVERSIZE = StatusCodes.NS_RECORD_STOP + ".oversize";

    public YourClientBroadcastStream()
{

        log.info("\n\tYourClientBroadcastStream()");

    }

   

    private long sizeLimit = -1;

    public long getSizeLimit() {

        if (sizeLimit <= 0) {       // 如果大小限制没有指定

            sizeLimit = 104857600L; // 默认限制为100MB

        }

        return sizeLimit;

    }

    //大小限制可以在red5-web.xmlspring方式来设置

    public void setSizeLimit(long sizeLimit) {

        this.sizeLimit = sizeLimit;

    }

 

    private static final Logger log = LoggerFactory.getLogger(YourClientBroadcastStream.class);

    //视频流数据被包装在IEvent对象中,被这个方法所处理.

    public void dispatchEvent(IEvent
event) {

        super.dispatchEvent(event);

        if (super.closed || !super.isRecording()) return;

           

        if (super.getBytesReceived() > sizeLimit) { //如果接收的数据超过大小限制

            log.info(String.format("\n%s (%d) exceeds size limit of
%s\n"
, super.getSaveFilename(), super.getBytesReceived(), sizeLimit));

           

            sendRecordStopNotifyForOversize(); //发送一个消息通知客户端.

            log.info(String.format("\n\toversize is sent for video: %s", super.getSaveFilename()));

           

            super.stop(); // 停止记录

            log.info(String.format("\n\trecording for video: %s has been
stopped due to oversize: %d"
, super.getSaveFilename(), super.getBytesReceived()));

        }

    }

   

    private void sendRecordStopNotifyForOversize() {

        Status
stopStatus = new Status(NS_RECORD_STOP_OVERSIZE);

        stopStatus.setClientid(getStreamId());

        stopStatus.setDetails(getPublishedName());

 

        StatusMessage stopMsg = new StatusMessage();

        stopMsg.setBody(stopStatus);

        pushMessage(stopMsg);

    }

}

 

 

red5-web.xml中把子类绑定在“clientBroadcastStream”名下。

这样就是实现了.不光是监控视频文件大小,其他许多功能都可以在Red5服务器上实现。

Scan the QR code with WeChat.

请扫描二维码
关注我们的微信公众号!