Installing Red5 on a Linux system
Installing Red5 : Open Source Flash Server on an Ubuntu system from the source
Building and installing a Red5 server on a Linux box.
Adding a new user
First we create a new user for the Red5 service.server:~> adduser red5and deactivate the interactive shell.
red5:x:10xy:10xy:,,,:/home/red5:/bin/false
Installing a Red5 server on a Linux server.
Building a Red5 installer
To get a grip on Red5 we import the source into an IDE and build the server locally using the current stable release (as of May 2010 this is version 0.9.1).server:~> svn checkout http://red5.googlecode.com/svn/java/server/tags/0_9_1 server:~> mv 0_9_1 red5-server-0.9.1 server:~> ln -s red5-server-0.9.1 red5-server-0.9.xLook into the interior of the server, adapt code as needed.
server:~> cd red5-server-0.9.x server:~> ant distCreate a
server:~> ant dist-installerOr download the latest release from http://code.google.com/p/red5/ if the binary distribution is all you need.
Add a Red5 server startup script
Based on the/etc/init.d/skeleton a startup script for the installation above could look like this:
#! /bin/sh ### BEGIN INIT INFO # Provides: red5-server # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Red5 server script # Description: Based on skeleton ### END INIT INFO # Author: fluffi# # Do NOT "set -e" # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="Red5 server" NAME=red5-server DAEMON=/home/red5/red5-server-0.9.x/dist/red5.sh DAEMON_STOP=/home/red5/red5-server-0.9.x/dist/red5-shutdown.sh DAEMON_ARGS="" PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME JAVA_HOME=/usr/lib/jvm/java-6-sun/jre RED5_HOME=/home/red5/red5-server-0.9.x/dist # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions DAEMON_OPTS="--quiet" DAEMON_OPTS="--chdir $RED5_HOME --chuid red5" # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --background --chdir $RED5_HOME --chuid red5 --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --background --chdir $RED5_HOME --chuid red5 --pidfile $PIDFILE --startas $DAEMON -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON [ "$?" = 2 ] && return start-stop-daemon --start --background --chdir $RED5_HOME --chuid red5 --pidfile $PIDFILE --startas $DAEMON_STOP -- \ sleep 10 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; restart|force-reload) # # If the "reload" option is implemented then remove the # 'force-reload' alias # log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 exit 3 ;; esac :
Starting the Red5 server manually
With thered5-server startup script the Red5 server should start with uid=red5.
server:~> sudo /etc/init.d/red5-server startPoint your web browser to http://localhost:5080/ to verify the basic installation:

Making Red5 script run at boot time
server:~> update-rc.d red5-server defaults
First experiments with the installed Red5 server.
Pimp some Spring beans in the Red5 server installation
First experiments with the installed Red5 server.
The oflaDemo streams from data files inside the exploded war. In this experiment i want to stream from outside the Red5 installation. Take a deep breath and dive into the code of the Red5 server: Some small changes inDefaultStreamFilenameGenerator and the class is configurable via Spring: First i refactored the hardwired local variable "streams/" into a field to make to make the prefix configurable and added an appropriate setter.
private String prefix = "streams/";
...
public void setPrefix(String prefix) {
this.prefix = prefix;
}
Next was to refactor the hardwired absolute path flag:
public boolean resolvesToAbsolutePath() {
return false;
}
To make it configurable, too.
private boolean absolutePath = false;
...
public boolean resolvesToAbsolutePath() {
return absolutePath;
}
public void setAbsolutePath(boolean absolutePath) {
this.absolutePath = absolutePath;
}
The resulting bean definition in our example is added to red5-default.xml and looks is as follows (beware! name/id matters with Red5 bean resolving strategy):
<bean id="streamFilenameGenerator" class="org.red5.server.stream.DefaultStreamFilenameGenerator">
<property name="prefix" value="${sfg.prefix}" />
<property name="absolutePath" value="${sfg.absolutePath}" />
</bean>
With the configuration inside red5.properties.
# streamFilenameGenerator configuration sfg.prefix=/tmp/upload/ sfg.absolutePath=true
Test the pimped version of Red5 with some small changes in the oflaDemo.
As with the Red5DefaultStreamFilenameGenerator the oflaDemo, DemoService is given a configurable field:
private String fileDirectory = "streams/";
...
public void setFileDirectory(String fileDirectory) {
this.fileDirectory = fileDirectory;
}
The resulting configurable bean definition inside WEB-INF/red5-web.xml:
<bean id="demoService.service" class="org.red5.demos.oflaDemo.DemoService">
<property name="fileDirectory" value="${fileDirectory}" />
</bean>
is configured via WEB-INF/red5-web.properties
#fileDirectory=streams/ fileDirectory=file:/tmp/upload/Drop the oflaDemo.war into the embedded Tomcat deploy directory.
server:~> cp oflaDemo.war ~red5/red5/webappsRed5 will "explode" the web archive and start the application. Point your browser to see the oflaDemo in action.
