RED5 1.0 Write error NetStream.Buffer.Empty

I have a RED5 1.0 Final installation on my Windows 8 system and I am trying to get the recording to work correctly. The tutorial that I read said to buffer the data on the client side (in Flash), and then when the buffer is empty, close the connection.

The problem that I encountered is that when I start recording, the buffer immediately reports that it is empty (NetStream.Buffer.Empty). I worked once or twice where the buffer really fills, but for some reason it stops working that way.

I see that the client still sends data to the server even after I disconnect the camera from the network stream because the file on the server side continues to grow. My solution for now is to wait 60 seconds after the recording stops before closing the connection.

Interestingly, when there are no more packages, I see on the server side that the file switches from mystream.ser to mystream.flv and stops growing in size. I was thinking of writing server-side code to wait for this event to happen, and then tell the client that it can close the stream.

This is my first foray into the action script, so I can do something completely wrong here. Please let me know.

EDIT Here is the client code

<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:ns1="*" minWidth="955" minHeight="600" applicationComplete="init()" > <fx:Script> <![CDATA[ import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.NetStatusEvent; import flash.media.Camera; import flash.media.H264Level; import flash.media.H264Profile; import flash.media.H264VideoStreamSettings; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; var cam:Camera = Camera.getCamera(); var mic:Microphone = Microphone.getMicrophone(); var nc:NetConnection = new NetConnection(); var activeStream:NetStream; private var bufferCheckTimer:Timer; var recordHalted:Boolean = false; protected function init(): void{ recordButton.enabled = false; stopButton.enabled = false; nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus); nc.connect("rtmp://localhost/oflaDemo"); nc.client = this; } public function onMetaData(info:Object):void { trace("playback called onMetaData"); } public function onBWDone(... rest) : void { // have to have this for an RTMP connection trace('onBWDone'); } public function onBWCheck(... rest) : uint { trace('onBWCheck'); //have to return something, so returning anything :) return 0; } protected function onNetStatus(event:NetStatusEvent):void{ trace(event.info.code); if(nc.connected) { SetupCameraAndMic(); recordButton.enabled = true; stopButton.enabled = true; } } protected function SetupCameraAndMic(): void{ activeStream = new NetStream(nc); activeStream.bufferTime = 60; activeStream.client = this; activeStream.addEventListener(NetStatusEvent.NET_STATUS, handleStreamStatus,false,0,true); var h264Settings:H264VideoStreamSettings = new H264VideoStreamSettings(); h264Settings.setProfileLevel(H264Profile.BASELINE, H264Level.LEVEL_2); activeStream.videoStreamSettings = h264Settings; cam.addEventListener(StatusEvent.STATUS, handleCameraStatus, false, 0, true); mic.addEventListener(StatusEvent.STATUS, handleMicrophoneStatus, false, 0, true); cam.setMode(320,240, 15); cam.setQuality(0, 80); cam.setKeyFrameInterval(7); mic.rate = 44; mic.gain = 75; mic.setSilenceLevel(0); mic.setUseEchoSuppression(true); activeStream.attachCamera(cam); activeStream.attachAudio(mic); videoContainer.attachCamera(cam); } private function handleCameraStatus(e:StatusEvent):void { trace("handleCameraStatus - " + e.code); switch(e.code) { case 'Camera.muted': // Show a message break; case 'Camera.Unmuted': //finishCamAndMicSetup(); break; } } private function handleMicrophoneStatus(e:StatusEvent):void { trace("handleMicrophoneStatus - " + e.code); switch(e.code) { case 'Microphone.Muted': // Show a message break; case 'Microphone.Unmuted': //finishCamAndMicSetup(); break; } } private function handleStreamStatus(e:NetStatusEvent):void { switch(e.info.code) { case 'NetStream.Buffer.Empty': trace("NetStream.Buffer.Empty"); break; case 'NetStream.Buffer.Full': trace("NetStream.Buffer.Full"); break; case 'NetStream.Buffer.Flush': trace("NetStream.Buffer.Flush"); break; } } protected function recordButton_clickHandler(event:MouseEvent):void { if(activeStream == null) { SetupCameraAndMic(); } if(activeStream != null){ var tempDate:Date = new Date(); var uniqueFileName:String = "RecordME_" + String(tempDate.getMinutes()) + String(tempDate.getMilliseconds()); bufferLabel.text = ""+ activeStream.bufferTime; activeStream.publish(uniqueFileName, "record"); bufferCheckTimer = new Timer(100); bufferCheckTimer.addEventListener(TimerEvent.TIMER, handleBufferCheck, false, 0, true); bufferCheckTimer.start(); } } private function handleBufferCheck(e:TimerEvent):void { if(activeStream != null) { trace("Buffer: " + activeStream.bufferLength); statusLabel.text = "Buffer: " + activeStream.bufferLength; if (recordHalted == true) { if ( activeStream.bufferLength == 0 ) { activeStream.close(); activeStream = null; bufferCheckTimer.stop(); bufferCheckTimer.removeEventListener(TimerEvent.TIMER, handleBufferCheck); bufferCheckTimer = null; // OK - playback time //doRecordingPlayback(); } } if (bufferCheckTimer != null) { bufferCheckTimer.reset(); bufferCheckTimer.start(); } } } protected function stopButton_clickHandler(event:MouseEvent):void { activeStream.attachCamera(null); activeStream.attachAudio(null); videoContainer.attachCamera(null); recordHalted = true; } ]]> </fx:Script> <fx:Declarations> <!-- Place non-visual elements (eg, services, value objects) here --> </fx:Declarations> <mx:VideoDisplay id="videoContainer" x="158" y="53" width="640" height="480" chromeColor="#3C2020" /> <s:Button id="recordButton" x="396" y="546" label="Record" click="recordButton_clickHandler(event)"/> <s:Button id="stopButton" x="491" y="546" label="Stop Recording" click="stopButton_clickHandler(event)"/> <s:Label id="statusLabel" x="158" y="555" width="207"/> <s:Label x="14" y="408" text="Buffer Set to:"/> <s:Label id="bufferLabel" x="91" y="408" text="0"/> </s:Application> 

thanks

+4
source share
3 answers

I think this is the result of an error in the release of RED5 final V1.0. I returned to version 0.80 and I can record perfectly.

+1
source

I don't have an RTMP server running right now, so I'm just commenting on what I see in your code.

I think the advice you got about buffering at first may not be such a good idea when publishing (writing) a stream. Perhaps the tutorial was not about publishing, but subscribing to an existing stream, in which case buffering is a great idea.

You set bufferTime to 60 seconds. docs say you should set bufferTime to 0 for live recording. That is, you want to send data as soon as it is generated by the camera / microphone.

The following is the Timer that you are using. It seems to be checking the length of the buffer to find that the recording is stopped. There are really only two cases where recording stops:

  • when the user clicks the stop button and your code stops it
  • any scenario where the server or something else causes it to stop (network problem, etc.).

I would suggest using the NetStatusEvent handler method ( handleStreamStatus() ) to check the message "NetStream.Record.Stop" instead of using a timer to check bufferLength . This allows your code to detect when the recording stopped for some other reason than the user by pressing "stop".

A timer is the likely cause of the problem. Even if you set the bufferTime to a large value, it may not work or behave differently with the Red 5 server, or it may be overridden by the server-side setting. Regardless of the fact that the point does not use bufferLength to detect recording stop.

There are tons of useful messages sent from NetStatusEvent , I recommend reading them and see if any of them are useful in your script. They are fairly reliable and seem to cope with most situations that may arise.

The last thing I noticed (not a problem, but worth fixing): you activate the echo cancellation on the microphone, but this will not work if you do not get an amplified microphone:

 var mic:Microphone = Microphone.getEnhancedMicrophone(); 
+1
source

Recording works well with Red5 V1.0.2, changing the queue threshold. I saw a video processing site called jobma that records videos very well. it seems like they are using red5

0
source

All Articles