首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用sip.js记录SIP呼叫的麦克风和音频

使用sip.js记录SIP呼叫的麦克风和音频
EN

Stack Overflow用户
提问于 2017-08-22 21:17:09
回答 1查看 3.2K关注 0票数 6

晚上好,堆叠溢出!在我的一个项目中,我真的需要帮助,在那里我使用sip.js和VoIP来给电话号码打真正的电话。

目标

我希望允许用户记录音频和麦克风,并将数据保存在服务器上(以base64编码或作为文件)。因此,谈话结束后,我可以再次听到对话,并将其用于我的目的(员工培训)。

问题

我无法听到说话的人的声音,这是通过和-HTML标签(使用sip.js插件)。到目前为止,我还没有找到任何方法来成功地保存声音流通过这个音频标签。

我到目前为止做了什么,

我已经成功地找到了如何使用一个名为AudioRecorder的插件来记录麦克风的音频,这个插件允许我通过麦克风记录音频并保存它。我稍微修改了代码,以便将其保存为base64。虽然我只听到我自己的声音,而不是和我说话的人,但这一切都像预期的那样起作用。

因为我成功地录制了自己声音的音频,所以我查看了AudioRecorder插件,并试图将插件反转到音频标记上。我在AudioRecorder中找到了“AudioRecorder”函数,我想使用的-tag没有工作(正如我所怀疑的那样,因为它本身中的-tag不是一个流(我理解它))。

代码

我基本上是使用sip.js插件通过使用下面的代码来建立对电话号码的呼叫(只使用一个示例,匹配我的代码,因为我的原始代码包含一些不需要在这里显示的附加值):

代码语言:javascript
运行
复制
// 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") } } };

然后,我使用invite函数中的build调用一个电话号码,这将完成剩下的工作。音频和麦克风现在启动并运行。

代码语言:javascript
运行
复制
userAgent.invite("+4512345678", options);

我现在可以和我最好的新朋友鲍勃谈谈了。但到目前为止,除了我自己的声音之外,我不能录制其他的音乐。

下一步是什么?

我真的想要一些帮助,以了解我如何能够录制"Bob“的声音,并将其存储在与我自己的声音相同的文件中。如果我必须录制两个单独的文件,并播放它们同步,我不会介意,但如果愿意的话。

我知道这可能只是一个求助电话,而没有给出我自己尝试过的任何真正的代码,但我不得不承认,我只是花了几个小时来处理这个代码,没有任何好的结果,现在我在大声呼救。

感谢您的所有提前和抱歉的错误的语法和(错误)的语言使用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-29 20:45:09

好吧,我终于找到了解决问题的办法,我想在这里分享一下。

为了解决这个问题,我所做的就是在麦克风的“正常”录音脚本中添加一行简单的代码。记录麦克风音频的脚本是:

代码语言:javascript
运行
复制
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(),所以我所做的是添加这个函数:

代码语言:javascript
运行
复制
function gotAudioOutputStream() {
    var source = audioGlobalContext.createMediaElementSource(document.getElementById("outputAudio"));
    source.connect(inputPoint);
    source.connect(audioGlobalContext.destination);
}

在initAudio()函数中,就在navigator.getUserMedia添加了对函数的调用之后。完成的代码(使用HTML)如下所示

代码语言:javascript
运行
复制
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才能工作。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45827103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档