Most commonly known modes of working in RTMP servers are the live, record and append modes. However a most commonly required mode which is not provided in the flash API is the Live-Record mode. Each RTMP server has its own way of implementing it on the server side. Here we will see how to use flash client and Red5 to do live-record.
Red5 Server Application Code: – [ Goes into Application Class ]
@Override
public boolean connect(IConnection conn, IScope scope, Object[] params) {
return true;
}
/** {@inheritDoc} */
@Override
public void disconnect(IConnection conn, IScope scope) {
super.disconnect(conn, scope);
}
@Override
public void streamPublishStart(IBroadcastStream stream)
{
try {
stream.saveAs(stream.getPublishedName(), false);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void streamBroadcastClose(IBroadcastStream stream)
{
System.out.print("Broadcast Closed");
}
@Override
public void streamBroadcastStart(IBroadcastStream stream)
{
System.out.print("Broadcast Started");
}
In the above code you will see there are two events for handling BroadcastStart: streamBroadcastStart and streamPublishStart. We will typically use streamPublishStart which is safer. The method saveAs takes two parameters: savefilename and append. When append is true Red5 will try to append new stream data to existing file , in which case it may throw exception if file was not existing. Thus we surround the statement by a try… catch block to handle such situations.
Flash Client Sample:
In your flash client code you create a simple publisher and publish the stream as live stream. Red5 will automatically begin recording the stream at server end.
import flash.events.StatusEvent;
import flash.media.*;
import flash.system.*;
import flash.events.MouseEvent;
import fl.controls.Button;
var mic:Microphone;
var cam:Camera;
var micAllowed:Boolean = false;
var camAllowed:Boolean = false;
var nc:NetConnection = new NetConnection();
var ns:NetStream;
nc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatus);
nc.connect("rtmp://localhost/customstreamer");
function onNetStatus(e:NetStatusEvent):void
{
switch(e.info.code)
{
case "NetConnection.Connect.Success":
initStream();
attachDevices();
break;
}
}
function onStreamStatus(e:NetStatusEvent):void
{
trace(e.info.code);
}
function initStream()
{
ns = new NetStream(nc);
ns.addEventListener(NetStatusEvent.NET_STATUS,onStreamStatus);
}
function attachDevices():void
{
mic = Microphone.getMicrophone();
cam = Camera.getCamera();
if(mic != null) configureMic();
if(cam != null) configureCam();
}
function configureMic()
{
mic.rate = 22;
mic.gain = 50;
mic.setLoopBack(true);
mic.setUseEchoSuppression(true);
mic.addEventListener(StatusEvent.STATUS, onMicStatus);
}
function configureCam()
{
cam.setLoopback(true);
cam.setMode(176,144,15);
cam.setKeyFrameInterval(5);
cam.setQuality(0,70);
cam.addEventListener(StatusEvent.STATUS, onCamStatus);
vid.attachCamera(cam);
}
function onMicStatus(s:StatusEvent):void
{
switch(s.code)
{
case "Microphone.Unmuted":
micAllowed = true;
break;
case "Microphone.Muted":
micAllowed = false;
break;
}
validateRecorder();
}
function onCamStatus(s:StatusEvent):void
{
switch(s.code)
{
case "Camera.Unmuted":
camAllowed = true;
break;
case "Camera.Muted":
camAllowed = false;
break;
}
validateRecorder();
}
function validateRecorder()
{
if(camAllowed || micAllowed)
{
btnStart.addEventListener(MouseEvent.CLICK,onStart);
btnStop.addEventListener(MouseEvent.CLICK,onStop);
}
}
function onStart(me:MouseEvent):void
{
ns.attachAudio(mic);
ns.attachCamera(cam);
ns.publish("demostream","live");
}
function onStop(me:MouseEvent):void
{
ns.close();
}
You will notice that in the above code we stream cam/mic data in live mode. And our server side code captures the live broadcast into a flv container.
Download FLA: (required Flash CS5)