Let's create an application based on the previous article. We will log connecting client’s ip, referrer and connection time to a database, then send back a list of the avaiable videos based on the database to the client, and 20 seconds after the client started playing a stream disconnect client because time is up.

We need a database first, I used mySQL 5.0, download and install it from here.  For administration, use its own admin tool, or download phpMyAdmin from here.

Create a new table named red5first_users in the test database. In this table, create four fileds: counter( int , auto increment, primary ), ip ( varchar 256 ) . referrer ( varchar 256 ) , flashversion ( varchar 256 ) , connection ( double ). Then create a new table named red5first_streams with four fields: counter ( int , auto increment , primary ) , id ( varchar 256 ) , filename ( varchar 256 ) , duration ( integer 11 ).

After this download the java mysql driver from mysql home. Copy mysql-connector-java*.jar to the Eclipse project root. Switch back to Eclipse, Project menuitem -> Properties -> Build Path -> Libraries -> Add External JARs, and choose the connector java from project root.

We also need to copy the driver to red5/lib, and export it to the java classpath, so the red5 application will reach it.

On os x, it looks like this:
export CLASSPATH=$CLASSPATH:/Applications/Red5/lib/mysql-connector-java-5.0.6-bin.jar


Application code:

package com.milgra;

// amf object
import org.red5.io.utils.ObjectMap;

import java.util.Map;
import java.util.Vector;
import java.util.Iterator;

import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.red5.server.api.IScope;
import org.red5.server.api.IClient;
import org.red5.server.api.IConnection;
import org.red5.server.api.stream.ISubscriberStream;
import org.red5.server.api.service.IServiceCapableConnection;
import org.red5.server.api.scheduling.IScheduledJob;
import org.red5.server.api.scheduling.ISchedulingService;
import org.red5.server.adapter.ApplicationAdapter;

// IScheduledJob implementation is needed for timing

public class Application extends ApplicationAdapter implements IScheduledJob
{

    //dbase adress
    private static final String url = "jdbc:mysql://127.0.0.1:3306/test";
    private static final String user = "youruser";
    private static final String pass = "yourpass";
    //logger
    private static final Log log = LogFactory.getLog( Application.class );

    // we want class initialization at start, so its static

    static
    {

        try
        {
            Class.forName("com.mysql.jdbc.Driver");
        }
        catch ( ClassNotFoundException exception )
        {
            log.error( "ClassNotFoundException " + exception.getMessage( ) );
        }

    }

    public boolean appStart ( IScope scope )
    {

        //start timer, cheking user presence every second

        addScheduledJob( 1000 , this );

        return true;

    }

    public void appStop ( IScope scope )
    {

        log.info( "Red5First.appStop" );

    }

    public boolean appConnect( IConnection conn , Object[] params )
    {

        log.info( "Red5First.appConnect " + conn.getClient().getId() );

        // getting client parameters

        Map properties = conn.getConnectParams();

        //connection time

        Long stamp = System.currentTimeMillis( );

        // client ip


        String ip = (String)conn.getRemoteAddress( );

        // agent

        String agent = (String)properties.get( "flashVer" );

        // referrer

        String referrer = (String)properties.get( "swfUrl" );

        // this will be our stream list

        Object[ ] streamList = { };

        try
        {

            // trying to connect

            Connection mySQLConn = DriverManager.getConnection( url , user , pass );

            // we put the parameters into the dbase

            Statement sttmnt = mySQLConn.createStatement( );

            String insert = "INSERT INTO "
                           + "`test`.`red5first_users` "
                           + "(`counter`,`ip`,`referrer`,`flashversion`,`connection`)"
                           + "VALUES(NULL,'" + ip + "','" + referrer + "','" + agent + "','" + stamp + "')";

            // execute query

            sttmnt.executeUpdate( insert );

            // getting stream list

            String query = "SELECT * FROM "
                           + "`red5first_streams`";

            ResultSet streamSet = sttmnt.executeQuery( query );

            // converting resultSet to ObjectMap-based Vector

            Vector results = new Vector( );
            int counter = 0;

            while ( streamSet.next( ) )
            {

                int duration = streamSet.getInt( “duration” );
                String id = streamSet.getString( “id” );
                String filename = streamSet.getString( “filename” );
                ObjectMap oneRow = new ObjectMap( );

                oneRow.put( “id” , id );
                oneRow.put( “filename” , filename );
                oneRow.put( “duration” , duration );

                results.add( oneRow );
                counter++;

            }

            //creating streamList

            streamList = new Object[counter];
            for ( int a = 0 ; a < results.size( ) ; a++ )
                streamList[a] = results.get( a );

        }
        catch ( SQLException exception )
        {

            log.error( "SQLException at appConnect: " + exception.getMessage( ) );

        }

        // if streamlist is not empty, sending it to client

        if ( streamList.length != 0 )
        {

            IServiceCapableConnection iconn = (IServiceCapableConnection)conn;
            iconn.invoke( "message" , new Object[] {streamList} );

        }

        IClient client = conn.getClient( );

        // setting client timestamp to 0, because it doesn't started any stream


        client.setAttribute( "stamp" , new Long( 0 ) );

        return true;

    }

    public void appDisconnect( IConnection conn , Object[] params )
    {

        log.info( "Red5First.appDisconnect " + conn.getClient().getId() );

    }

    public void streamSubscriberStart ( ISubscriberStream stream )
    {

        log.info( "Red5First.streamSubscriberStart" );

        // somebody started a stream

        IConnection conn = stream.getConnection( );
        IClient client = conn.getClient( );
        Long stamp = (Long)client.getAttribute( "stamp" );

        // if client isn't already watching, setting stamp

        if ( stamp == 0 ) client.setAttribute( "stamp" , System.currentTimeMillis( ) );

    }

    public void streamSubscriberStop ( ISubscriberStream stream )
    {

        log.info( "Red5First.streamSubscriberStop" );        

    }

    // this function is called every second by SchedulingService

    public void execute ( ISchedulingService isservice )
    {

        log.info( "Red5First.execute" );

        long now = System.currentTimeMillis( );
        Iterator it = this.getScope( ).getClients( ).iterator( );

        // iterating through clients

        while ( it.hasNext() )
        {

            IClient client = ( IClient )it.next( );
            long stamp = ( Long ) client.getAttribute( "stamp" );

            // if client is watching a stream

            if ( stamp > 0 )
            {

                long duration = ( now - stamp ) / 1000;

                // if time is up, disconnect

                if ( duration > 20 ) client.disconnect( );

            }

        }

    }

}


And that's it.

Create a directory in red5/webapps/firstapp called streams, and copy a few flv streams here, then fill up red5first_streams table in the database with the attributes of these streams. Our application will reach them by default, because if we check WEB-INF/web.xml:

<security-constraint>
        <web-resource-collection>
            <web-resource-name>Forbidden</web-resource-name>
            <url-pattern>/streams/*</url-pattern>
        </web-resource-collection>
        <auth-constraint/>
    </security-constraint>


This folder will be enabled by Tomcat.
After Eclipse auto-built the application, copy your project's WEB-INF under red5/webapps/firstapp, and you can start the server.