живой аудио поток через сокет IO.alsa shutdown, как это исправить? - PullRequest
1 голос
/ 19 июня 2019

Я хочу создать сервис для потоковой передачи аудио в реальном времени через socket.io и ionic 4.Для клиента я использую cordova-plugin-audioinput и ng-socket-io для угловыхДля сервера я использую стандартный пакет npmВерсия узла: 10.16.0Npm версия: 6.9.0Я получаю звук и воспроизводю его, но alsa отключаюсь после получения 58-60 аудиопакетов (кадров).

Код моего клиента:

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");
  }
}

Код моего сервера:

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');
});

После 58-60 аудиопакетов отключение alsa со следующим:

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)

Как исправить ошибку?

1 Ответ

0 голосов
/ 02 июля 2019

Я решил эту проблему.моя клиентская сторона для трансляции живого аудио с микрофона:

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");
  }
}

и моя серверная сторона для воспроизведения голоса с мобильного микрофонаСервер получил чанк через socket.io и воспроизвел его через динамик:

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');
});
...