簡體   English   中英

使用 sip.js 錄制來自 SIP 呼叫的麥克風和音頻

[英]Record mic and audio from SIP call using sip.js

晚上好堆棧溢出! 我真的需要我的一個項目的幫助,我正在使用 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);

我現在可以和我最好的新朋友鮑勃交談了。 但是現在除了我自己的聲音我不能錄制。

下一步是什么?

我真的很想了解如何錄制“鮑勃”的聲音並將其存儲在與我自己的聲音相同的文件中。 如果我必須錄制兩個單獨的文件並同步播放它們,我不會介意,但如果願意的話。

我知道這可能只是尋求幫助,而沒有顯示我自己嘗試做的任何真實代碼,但我不得不承認我只是擺弄了幾個小時的代碼沒有任何好的結果,現在我在尖叫幫助。

預先感謝大家,並對語法錯誤和(錯誤)使用語言表示抱歉。

好的,所以我終於找到了解決問題的方法,盡管我想在這里分享。

我為解決這個問題所做的是在麥克風的“正常”錄音腳本中添加一行簡單的代碼。 錄制麥克風音頻的腳本是:

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 才能工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM