Windows8システムでRED51.0Finalをセットアップしましたが、記録を正しく機能させようとしています。私が読んだチュートリアルでは、クライアント側(Flash内)でデータをバッファリングし、バッファが空になったら接続を閉じます。
私が抱えている問題は、バッファの記録を開始すると、バッファが空であるとすぐに報告することです(NetStream.Buffer.Empty)。バッファが実際にいっぱいになる場所で1〜2回動作させましたが、何らかの理由でそのように動作しなくなりました。
サーバー側のファイルが増え続けているため、カメラをネットストリームから切り離した後でも、クライアントがサーバーにデータを送信していることがわかります。現時点での私の解決策は、録音が停止してから60秒待ってから、接続を閉じることです。
興味深いのは、送信するパケットがなくなると、サーバー側でファイルがmystream.serからmystream.flvに切り替わり、サイズが大きくならないことです。このイベントが発生するのを待ってから、ストリームを閉じることができることをクライアントに通知するために、サーバー側でコードを作成することを考えていました。
これはアクションスクリプトへの私の最初の進出なので、ここで完全に間違ったことをしている可能性があります。私にお知らせください。
編集これがクライアントコードです
<?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 (e.g., 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>
ありがとう