package
{
import flash.events.NetStatusEvent;
import flash.media.Camera;
import flash.media.H264Level;
import flash.media.H264Profile;
import flash.media.H264VideoStreamSettings;
import flash.media.Microphone;
import flash.media.SoundCodec;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.utils.clearInterval;
import flash.utils.setInterval;
public class VideoStreamer extends Object {
protected var connection :NetConnection;
protected var stream :NetStream;
public var camera :Camera;
public var microphone :Microphone;
protected var serverName :String;
protected var streamName :String;
//Class constructor
public function VideoStreamer(serverName:String, streamName:String) {
this.serverName = serverName;
this.streamName = streamName;
}
protected function setupCamera():void {
// get the default Flash camera and microphone
camera = Camera.getCamera();
if (!camera) {
return;
}
var width:int = 640;
var height:int = 480;
var rate:int = width * height;
var quality:int = 80;
var fps:int = 30;
// set camera properties
camera.setMode(width, height, fps, true);
// keyframes
camera.setKeyFrameInterval(2);
// quality
// @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Camera.html#setQuality()
// camera.setQuality(90000, 90); // new
// camera.setQuality(rate, quality); // new
camera.setQuality(0, quality); // new
// debug
trace('width: ', width, 'height: ', height)
trace('rate:' + rate)
}
protected function setupMicrophone():void {
microphone = Microphone.getMicrophone();
if (!microphone) {
return;
}
microphone.rate = 11;
microphone.setSilenceLevel(0, -1);
microphone.codec = SoundCodec.SPEEX;
}
public function connect():void {
setupCamera();
setupMicrophone();
connection = new NetConnection();
connection.addEventListener(NetStatusEvent.NET_STATUS, onConnectionStatus);
connection.connect(protected::serverName);
}
public function disconnect():void {
cleanup();
}
protected function cleanup():void {
// camera record
stream = null;
// connection close
connection = null;
camera = null;
microphone = null;
}
protected function onConnectionStatus(event:NetStatusEvent):void {
var code:String = event.info.code;
trace("NetConnection: " + code+" (" + event.info.description + ")");
switch(code) {
case 'NetConnection.Connect.Success':
startStreaming();
break;
default:
// reconnect all the time
connect();
break;
}
}
// ----------------------------------------------------------------------------------------------------------
// { region : Recording
// Start recording video to the server
protected function startStreaming():void {
// create a new NetStream object for publishing
stream = new NetStream(connection);
stream.addEventListener(NetStatusEvent.NET_STATUS, onStreamPublishStatus);
// client
stream.client = { };
// set the buffer time to 0 seconds to buffer 0 seconds of video
// data for better live performance
stream.bufferTime = 0.1;
// add h264 settings
var h264Settings:H264VideoStreamSettings = new H264VideoStreamSettings();
h264Settings.setProfileLevel(H264Profile.BASELINE, H264Level.LEVEL_3_1);
stream.videoStreamSettings = h264Settings;
// publish the stream by name
var mode:String = 'live'; //'default', 'append', 'record', 'live'
stream.publish(protected::streamName, mode);
// attach the camera and microphone to the server
stream.attachCamera(camera);
stream.attachAudio(microphone);
}
protected function stopStreaming():void {
// variables
var intervalId:Number;
// this function gets called every 250 ms to monitor the progress of flushing the video buffer.
// Once the video buffer is empty we close publishing stream
function onCheckBufferInterval():void {
trace('NetStream: Waiting for buffer to empty');
if (stream.bufferLength == 0)
{
trace('NetStream: Buffer is empty!');
clearInterval(intervalId);
closeStream();
}
}
// stop streaming video and audio to the publishing NetStream object
stream.attachCamera(null);
// disabled audio so that mp4 will record
stream.attachAudio(null);
// After stopping the publishing we need to check if there is video content in the NetStream buffer.
// If there is data we are going to monitor the video upload progress by calling flushVideoBuffer every 250ms.
if (stream.bufferLength > 0) {
// monitor buffer length
intervalId = setInterval(onCheckBufferInterval, 250);
} else {
// finish
closeStream();
}
}
protected function closeStream():void {
// debug
trace('> finished recording')
trace('NetStream.publish: (null)');
// after we have hit "Stop" recording, and after the buffered video data has been
// sent to the Wowza Media Server, close the publishing stream
stream.publish("null");
stream.close();
}
protected function onStreamPublishStatus(event:NetStatusEvent):void {
// debug
trace("NetStream.publish: "+event.info.code+" ("+event.info.description+")");
}
}
}