- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经在 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/
我正在尝试解决 A/V 同步问题。视频将比音频延迟 1 秒。 (请看我下面的注释) 来自 Android 媒体框架部分, 我可以延迟音频时间戳让它与视频同步,我应该从哪里开始?是音频源吗? MPEG4
我正在使用带有 SignalR 的 MassTransit 请求和响应。该网站向创建文件的 Windows 服务发出请求。创建文件后,Windows 服务会将响应消息发送回网站。该网站将打开该文件并使
我正在尝试创建一个允许用户发出一些声音的应用程序,然后以回放方式使用它。 我想让我的应用程序播放用户将记录的.wav文件。 由于不断出现错误,我在弄清楚如何编写此代码时遇到了麻烦。 ====
有没有办法禁止网页上视频的屏幕共享? 例如,当您尝试录制或屏幕共享(例如通过 Skype)Netflix 视频时,它仅显示黑屏并且没有音频。 我的问题是,他们是如何实现的?我只能想到JavaScrip
我正在尝试使用 html5 .getUserMedia 录制视频,然后在不上传到服务器的情况下再次播放。我尝试了很多教程,我通过使用 canvas 绘制 webp 图像然后使用 Whammy.js 转
我想为我的网站的用户实现屏幕录制功能。这将适用于便士拍卖风格的网站,以便用户可以记录他们的出价,并在拍卖出现问题时提供证据。 这是在线录音机的演示。 http://www.screentoaster.
所以在我的应用程序中,我尝试使用屏幕截图“记录”屏幕。我必须将这些单独的帧作为图像,因为它们稍后会在服务器上进行修改和组合。增加这种复杂性的是,它是在使用 Cocos2D 的慢节奏游戏中。我目前截屏的
是否可以使用单个 ffmpeg 命令同时捕获(记录)RTSP 流和捕获场景变化事件?我几乎可以做我想做的事: ffmpeg -i 'rtsp://mystream' \ -map 0:v -map 0
我是 Objective-c 和 iPhone 编程新手,但我正在开发一个自学应用程序。我一直在尝试弄清楚如何在 iPhone 上录制声音。 Apple 提供了使用 AVAudioRecorder 从
我无法写任何东西来允许这样做,但我希望有人能指出我找到可以做到这一点的代码的正确方向。我擅长 HTML 和 CSS,对 JS 非常陌生。 我需要的是能够使用我的麦克风在单页网站上讲话,并将其流回。这样
想象一下您在浏览器中观看体育赛事直播。这意味着您收到了视频流,对吗?我需要记录这个流并保存到磁盘。问题是我不知道从哪里开始。我对编程并不陌生,但在视频直播方面有一些经验。我看到这个问题分为以下几个部分
我在开始录制时遇到文件未找到异常。此外,我无法在 JMeter 可安装文件夹中找到 RootCA 证书。 最佳答案 根据 TestRecording210 JMeter Wiki 页面当用户(您在其下
我有这个源代码可以在浏览器中录制音频。 Record.js 调用另一个脚本提供录音并将其保存到服务器。 index.html record.js //starts by click on butt
我允许用户按下按钮以通过 SoundPool 播放声音。是否可以录制 SoundPool 正在播放的任何内容,以便用户可以录制一系列声音? 最佳答案 实际上不可能捕捉到播放的声音。我也有同样的愿望,但
我正在尝试使用 xcrun simctl io booted recordVideo recording.mov 录制我的 iOS 11.4 模拟器的屏幕。这将创建一个具有该名称的文件,但不幸的是该文
好的,我将尝试尽可能清楚地说明我的问题,但我很困惑,所以如果我没有传达信息,请告诉我。 我正在尝试使用 getUserMedia 来使用网络摄像头,然后使用这个 http://www.w3.org/T
是否可以使用 html5 录制声音?我已经下载了最新的 canary 版本的 chrome 并使用以下代码: navigator.getUserMedia = navigator.webkitGetU
很多人都在问这个,似乎没有人有答案,所以我也没有。 某些应用程序如何提供记录android系统音频输出的功能?我发现的所有内容都是在 1432 个不同站点上的相同教程,您可以在其中记录 MIC 输入。
不小心撞到了qq而不是 @q ,我的 vim 现在正在记录到寄存器 q . 如果我输入 q再次,它将覆盖以前录制的宏。 有没有办法 取消录制以免覆盖之前的宏或 恢复之前的宏而不从头开始重新录制? 最佳
当我们接到电话时,我们会向来电者播放提示,内容类似于“我们可能会出于质量和培训目的记录通话”。 我们为响应来电而发送的 TWiML 如下所示。 http://domain.tld/may_r
我是一名优秀的程序员,十分优秀!