gpt4 book ai didi

flash - RED5 1.0 录制问题 NetStream.Buffer.Empty

转载 作者:行者123 更新时间:2023-12-01 19:29:17 31 4
gpt4 key购买 nike

我已经在 Windows 8 系统上安装了 RED5 1.0 Final,并且正在尝试让录音正常工作。我读过的一个教程说要在客户端(在Flash中)缓冲数据,然后一旦缓冲区为空就关闭连接。

我遇到的问题是,当我开始记录缓冲区时,立即报告缓冲区为空(NetStream.Buffer.Empty)。我已经让它工作了一两次,缓冲区确实填满了,但由于某种原因它停止了这种工作方式。

即使我将相机与网络流分离,我也可以看到客户端仍在向服务器发送数据,因为服务器端的文件继续增长。我目前的解决方案是在录制停止后等待 60 秒再关闭连接。

有趣的是,当没有更多数据包要发送时,我在服务器端看到文件从 mystream.ser 切换到 mystream.flv 并停止大小增长。我正在考虑在服务器端编写一些代码来等待此事件发生,然后让客户端知道它可以关闭流。

这是我第一次尝试 ActionScript ,所以我可能在这里做了一些完全错误的事情。请告诉我。

编辑这是客户端代码

<?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>

谢谢

最佳答案

我现在没有正在运行的 RTMP 服务器,所以我只是评论我在您的代码中看到的内容。

我认为在发布(记录)流时,您首先得到的关于缓冲内容的建议可能不是一个好主意。也许本教程不是关于发布,而是关于订阅现有流,在这种情况下缓冲是一个好主意。

您将 bufferTime 设置为 60 秒。 docs假设您应该将 bufferTime 设置为 0 以进行现场录音。也就是说,您希望在摄像头/麦克风生成数据后立即发送数据。

接下来是您正在使用的计时器。这似乎是在检查缓冲区长度,以检测录制是否已停止。实际上只有两种情况会停止录制:

  • 当用户单击“停止”按钮时,您的代码会停止它
  • 服务器或其他原因导致其停止的任何情况(网络问题等)

我建议使用您的 NetStatusEvent 处理程序方法 (handleStreamStatus()) 来检查消息“NetStream.Record.Stop”,而不是使用计时器来检查缓冲区长度。这允许您的代码检测录制何时因用户单击“停止”之外的其他原因而停止。

计时器可能是导致问题的原因。即使您设置了较大的 bufferTime 值,它也可能无法在 Red 5 服务器上工作或表现不同,或者可能会被服务器端设置覆盖。无论如何,重点是不要使用 bufferLength 来检测录制是否已停止。

有一堆useful messages通过 NetStatusEvent 调度,我建议仔细阅读它们,看看它们是否对您的场景有用。他们非常可靠,似乎可以处理几乎所有可能出现的情况。

我注意到的最后一件事(不是问题,但值得纠正):您在麦克风上启用了回声抑制,但除非您获得增强型麦克风,否则这不会起作用:

var mic:Microphone = Microphone.getEnhancedMicrophone();

关于flash - RED5 1.0 录制问题 NetStream.Buffer.Empty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13944136/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com