- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
晚上好 Stack Overflow!对于我的一个项目,我真的需要帮助,我正在使用 sip.js 和 VoIP 调用电话号码。
目标
我想让用户录制音频和麦克风并将数据保存在服务器上(以 base64 编码或作为文件)。所以在谈话之后我可以再次听到谈话并将其用于我的目的(员工培训)。
问题
我听不到说话人的声音,它来自 -HTML 标签(使用 sip.js 插件)。截至目前,我还没有找到任何方法可以通过此音频标签成功保存声音流。
到目前为止我做了什么
我已经成功地找到了如何使用一个名为 AudioRecorder 的插件来录制麦克风的音频,它允许我通过麦克风录制音频并保存它。我稍微更改了代码,以便将其保存为 base64 编码。这一切都按预期工作,尽管我只能听到我自己的声音,而不是与我交谈的人的声音。
因为我成功地录制了自己的声音,所以我查看了 AudioRecorder 插件并尝试反转插件以从音频标签进行录制。我在 AudioRecorder 中找到了“createMediaStreamSource”函数,我想使用它不起作用的 -tag(正如我所怀疑的那样,因为它本身的 -tag 不是一个流(我理解)。
代码
我基本上是使用 sip.js 插件通过以下代码建立对电话号码的调用(仅使用示例,匹配我的代码,因为我的原始代码包含一些不需要的附加值显示在这里):
// Create a user agent called bob, connect, and register to receive invitations.
var userAgent = new SIP.UA({
uri: 'bob@example.com',
wsServers: ['wss://sip-ws.example.com'],
register: true
});
var options = { media: { constraints: { audio: true, video: false }, render: { remote: document.getElementById("audio") } } };
然后我使用内置的邀请功能调用一个电话号码,剩下的就交给它了。音频和麦克风现已启动并运行。
userAgent.invite("+4512345678", options);
我现在可以和我最好的新 friend 鲍勃聊天了。但是我现在不能录制除了我自己的声音。
下一步是什么?
我真的很想知道如何录制“Bob”的声音并将其存储在与我自己的声音相同的文件中。如果我必须录制两个单独的文件并同步播放它们,我不会介意,但如果愿意的话。
我知道这可能只是一个求助电话,没有显示我自己尝试做的任何真实代码,但我不得不承认我只是摆弄了几个小时的代码,但没有任何好的结果,现在我'我在尖叫求救。
提前感谢大家,对于语法错误和语言使用不当感到抱歉。
最佳答案
好吧,我终于找到了解决我的问题的方法,虽然我想在这里分享。
我为解决这个问题所做的是在麦克风的“正常”录音脚本中添加一行简单的代码。录制麦克风音频的脚本是:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioGlobalContext = new AudioContext();
var audioOutputAnalyser
var inputPoint = null,
audioRecorder = null;
var recording = false;
// Controls the start and stop of recording
function toggleRecording( e ) {
if (recording == true) {
recording = false;
audioRecorder.stop();
audioRecorder.getBuffers( gotBuffers );
console.log("Stop recording");
} else {
if (!audioRecorder)
return;
recording = true;
audioRecorder.clear();
audioRecorder.record();
console.log("Start recording");
}
}
function gotBuffers(buffers) {
audioRecorder.exportWAV(doneEncoding);
}
function doneEncoding(blob) {
document.getElementById("outputAudio").pause();
Recorder.setupDownload(blob);
}
function gotAudioMicrophoneStream(stream) {
var source = audioGlobalContext.createMediaStreamSource(stream);
source.connect(inputPoint);
}
function initAudio() {
if (!navigator.getUserMedia)
navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
if (!navigator.cancelAnimationFrame)
navigator.cancelAnimationFrame = navigator.webkitCancelAnimationFrame || navigator.mozCancelAnimationFrame;
if (!navigator.requestAnimationFrame)
navigator.requestAnimationFrame = navigator.webkitRequestAnimationFrame || navigator.mozRequestAnimationFrame;
inputPoint = audioGlobalContext.createGain();
navigator.getUserMedia({
"audio": {
"mandatory": {
"googEchoCancellation": "true",
"googAutoGainControl": "false",
"googNoiseSuppression": "true",
"googHighpassFilter": "false"
},
"optional": []
},
}, gotAudioMicrophoneStream, function(e) {
alert('Error recording microphone');
console.log(e);
});
var analyserNode = audioGlobalContext.createAnalyser();
analyserNode.fftSize = 2048;
inputPoint.connect(analyserNode);
var zeroGain = audioGlobalContext.createGain();
zeroGain.gain.value = 0.0;
inputPoint.connect(zeroGain);
zeroGain.connect(audioGlobalContext.destination);
audioRecorder = new Recorder(inputPoint);
}
window.addEventListener('load', initAudio );
我一直在寻找将音频标签声音转换为音频源的函数是 createMediaElementSource()
所以我所做的就是添加这个函数:
function gotAudioOutputStream() {
var source = audioGlobalContext.createMediaElementSource(document.getElementById("outputAudio"));
source.connect(inputPoint);
source.connect(audioGlobalContext.destination);
}
并且在 navigator.getUserMedia 之后的 initAudio() 函数中添加了对该函数的调用。完成的代码(带有 HTML)看起来像这样
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioGlobalContext = new AudioContext();
var audioOutputAnalyser
var inputPoint = null,
audioRecorder = null;
var recording = false;
// Controls the start and stop of recording
function toggleRecording( e ) {
if (recording == true) {
recording = false;
audioRecorder.stop();
audioRecorder.getBuffers( gotBuffers );
console.log("Stop recording");
} else {
if (!audioRecorder)
return;
recording = true;
audioRecorder.clear();
audioRecorder.record();
console.log("Start recording");
}
}
function gotBuffers(buffers) {
audioRecorder.exportWAV(doneEncoding);
}
function doneEncoding(blob) {
document.getElementById("outputAudio").pause();
Recorder.setupDownload(blob);
}
function gotAudioMicrophoneStream(stream) {
var source = audioGlobalContext.createMediaStreamSource(stream);
source.connect(inputPoint);
}
function gotAudioOutputStream() {
var source = audioGlobalContext.createMediaElementSource(document.getElementById("outputAudio"));
source.connect(inputPoint);
source.connect(audioGlobalContext.destination);
}
function initAudio() {
if (!navigator.getUserMedia)
navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
if (!navigator.cancelAnimationFrame)
navigator.cancelAnimationFrame = navigator.webkitCancelAnimationFrame || navigator.mozCancelAnimationFrame;
if (!navigator.requestAnimationFrame)
navigator.requestAnimationFrame = navigator.webkitRequestAnimationFrame || navigator.mozRequestAnimationFrame;
inputPoint = audioGlobalContext.createGain();
navigator.getUserMedia({
"audio": {
"mandatory": {
"googEchoCancellation": "true",
"googAutoGainControl": "false",
"googNoiseSuppression": "true",
"googHighpassFilter": "false"
},
"optional": []
},
}, gotAudioMicrophoneStream, function(e) {
alert('Error recording microphone');
console.log(e);
});
gotAudioOutputStream();
var analyserNode = audioGlobalContext.createAnalyser();
analyserNode.fftSize = 2048;
inputPoint.connect(analyserNode);
var zeroGain = audioGlobalContext.createGain();
zeroGain.gain.value = 0.0;
inputPoint.connect(zeroGain);
zeroGain.connect(audioGlobalContext.destination);
audioRecorder = new Recorder(inputPoint);
}
window.addEventListener('load', initAudio );
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Audio Recorder</title>
<script src="assets/js/AudioRecorder/js/recorderjs/recorder.js"></script>
<script src="assets/js/AudioRecorder/js/main.js"></script>
</head>
<body>
<audio id="outputAudio" autoplay="true" src="test.mp3" type="audio/mpeg"></audio>
<audio id="playBack"></audio>
<div id="controls">
<img id="record" src="assets/js/AudioRecorder/img/mic128.png" onclick="toggleRecording(this);">
</div>
</body>
</html>
这会记录您的声音和来自音频元素标签的声音。简单的。希望所有和我有同样问题的人“倒转”你的头围绕音频 API 会发现这很有帮助。
上面显示的代码片段需要 Recorder.js 才能工作。
关于javascript - 使用 sip.js 从 SIP 通话中录制麦克风和音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45827103/
我正在尝试解决 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
我是一名优秀的程序员,十分优秀!