live audio stream over socket io. alsa shutdown, how to fix it?

Viewed 844

I'm want create service for live audio streaming over socket.io and ionic 4.
For client, i'm use cordova-plugin-audioinput and ng-socket-io for angular
For server, i'm use standart npm package

Node version: 10.16.0
Npm version: 6.9.0
I'm receive sound and playback it, but alsa shutdown after received 58-60 audio packet (frames).

My client code:

export class HomePage {
  bufferSize:number = 8192;
  mediaRecorder;
  constructor(public socket:Socket) {}
  ngOnInit(){   
    this.socket.connect(); 
    window.addEventListener('audioinput', (data) => {
      this.onAudioInput(data, this.socket);
    });

    audioinput.initialize({
      sampleRate: 8000,
      bufferSize: this.bufferSize,
      channels: 1,
      format: audioinput.FORMAT.PCM_16BIT,
      audioSourceType: audioinput.AUDIOSOURCE_TYPE.MIC
    }, () => {
      audioinput.checkMicrophonePermission((hasPermission) => {
        if (hasPermission) {
          console.log("Permission already exist");
        } 
        else {          
          audioinput.getMicrophonePermission((hasPermission, message) => {
            if (hasPermission) {
              console.log("User gived permission.");
            } else {
              console.warn("User denied permission.");
            }
          });
        }
      });
    });
  }
  onAudioInput(data, socket){
    socket.emit("audioinput", data.data);
  }
  start(){
    audioinput.start({
      sampleRate: 8000,
      bufferSize: this.bufferSize,
      channels: 1,
      format: audioinput.FORMAT.PCM_16BIT,
      audioSourceType: audioinput.AUDIOSOURCE_TYPE.MIC
    });
    this.socket.emit("message", "started");
  }
  stop(){
    audioinput.stop();
    this.socket.emit("message", "stoped");
  }
}

My server code:

let app = require('express');
let http = require('http').Server(app);
let io = require('socket.io')(http);
let audioContext = require('audio-context')({
    sampleRate: 8000, 
    latencyHint: 'balanced'
});
let buff = require('audio-buffer');
const play = require('audio-play');

var audioBuffer 
= new buff(audioContext, {
    length: 8192,
    sampleRate: 8000,
    numberOfChannels: 1
});
array = new Float32Array();
var counter = 0;
io.on('connection', (socket) =>{
    socket.on('message', (data) =>{
        console.log(data);
    });
    //var outputData = new Float32Array(buffer);
    socket.on('audioinput', (data)=>{ 
        array = data;
        audioBuffer.copyToChannel(array, 0, 0);
        if(counter == 0){
            setTimeout(function audio(){
                var playback = play(audioBuffer, { 
                    start: 0,
                    end: audioBuffer.duration,
                    loop:false,
                    detune: 0,
                    rate: 8000,
                    volume: 1,
                    context: audioContext,
                    autoplay: false
                }, (result) => {});
                playback.play();
                setTimeout(audio, 1000)  
            }, 1000);
        }    
        counter ++;
        console.log(counter);
    });

});
var port = process.env.PORT || 6500;

http.listen(port, () =>{
    console.log('listening started');
});

After 58-60 audio-packets alsa shutdown with following:

ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection terminated

    [../deps/mpg123/src/output/alsa.c:165] error: cannot open device default
    events.js:174
          throw er; // Unhandled 'error' event
          ^

    Error: open() failed: -1
        at Speaker._open (/home/azat/ionicFolder/server (копия)/node_modules/audio-speaker/node_modules/speaker/index.js:168:11)
        at Speaker._write (/home/azat/ionicFolder/server (копия)/node_modules/audio-speaker/node_modules/speaker/index.js:242:21)
        at doWrite (/home/azat/ionicFolder/server (копия)/node_modules/audio-speaker/node_modules/speaker/node_modules/readable-stream/lib/_stream_writable.js:428:64)
        at writeOrBuffer (/home/azat/ionicFolder/server (копия)/node_modules/audio-speaker/node_modules/speaker/node_modules/readable-stream/lib/_stream_writable.js:417:5)
        at Speaker.Writable.write (/home/azat/ionicFolder/server (копия)/node_modules/audio-speaker/node_modules/speaker/node_modules/readable-stream/lib/_stream_writable.js:334:11)
        at write (/home/azat/ionicFolder/server (копия)/node_modules/audio-speaker/direct.js:67:11)
        at loop (/home/azat/ionicFolder/server (копия)/node_modules/audio-play/index.js:93:4)
        at Function.play (/home/azat/ionicFolder/server (копия)/node_modules/audio-play/index.js:94:4)
        at Timeout.audio [as _onTimeout] (/home/azat/ionicFolder/server (копия)/index.js:54:26)
        at ontimeout (timers.js:436:11)



How to fix it error?

1 Answers

i'm resolved this problem. my client side for live audio translation from microphone:

declare var audioinput: any;

import { Component } from '@angular/core';
import { Socket } from 'ng-socket-io';


@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  bufferSize = 2048;
  constructor(public socket: Socket) {}
  ngOnInit() {
    this.socket.connect();
    window.addEventListener('audioinput', (data) => {
      this.onAudioInput(data, this.socket);
    });

    audioinput.initialize({
      sampleRate: 8192,
      bufferSize: this.bufferSize,
      channels: 1,
      format: audioinput.FORMAT.PCM_16BIT,
      audioSourceType: audioinput.AUDIOSOURCE_TYPE.MIC,
      streamToWebAudio: false
    }, () => {
      audioinput.checkMicrophonePermission((hasPermission) => {
        if (hasPermission) {
          console.log('Разрешение уже получено');
        } else {
          audioinput.getMicrophonePermission((hasPermission, message) => {
            if (hasPermission) {
              console.log('Пользователь дал разрешение на запись.');
            } else {
              console.warn('Пользователь запретил записывать.');
            }
          });
        }
      });
    });
  }
  onAudioInput(data, socket) {
    socket.emit('audioinput', data.data);
    console.log(data.data);
  }
  start() {
    audioinput.start({
      sampleRate: 8192,
      bufferSize: this.bufferSize,
      channels: 1,
      format: audioinput.FORMAT.PCM_16BIT,
      audioSourceType: audioinput.AUDIOSOURCE_TYPE.MIC,
      streamToWebAudio: false
    });
  }
  stop() {
    audioinput.stop();
    // this.socket.emit("message", "stoped");
  }
}

and my server side for playing voice from mobile microphone
server received chunk via socket.io and playing it via speaker:

let app = require('express');
let http = require('http').Server(app);
let io = require('socket.io')(http);
var buff = require('audio-buffer');
const Speaker = require('audio-speaker/stream');

var audioBuffer = new buff({
    length: 2048,
    sampleRate: 8192,
    numberOfChannels: 1
})

array = new Float32Array();

var speakerVoice;
io.on("connection", (socket) => {
    socket.on("message", (data) =>{

    })
    socket.on("audioinput", (data) => {
        array = data;
        if(counter == 0){
            speakerVoice = new Speaker({
                sampleRate: 4096,
                float: true,
                signed: true,
                bitDepth: 16
            });         
        }
        audioBuffer.copyToChannel(array, 0, 0);
        speakerVoice.write(audioBuffer);
    })
})
var port = process.env.PORT || 6500;

http.listen(port, () =>{
    console.log('listening started');
});
Related