前端
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { MediaDevicesService } from '../../media-devices.service';
import * as io from 'socket.io-client';
import { MESSAGE_EVENT } from '@live-video-example/p2p';
@Component({
selector: 'live-video-example-get-audio',
templateUrl: './get-audio.component.html',
styleUrls: ['./get-audio.component.styl'],
})
export class GetAudioComponent implements OnInit {
constructor(private readonly mediaDevicesService: MediaDevicesService) {}
@ViewChild('audio')
audioRef: ElementRef<HTMLAudioElement>;
localStream: MediaStream;
mr: MediaRecorder;
recordedChunks: any[] = [];
private socket?: SocketIOClient.Socket;
isStart = false;
async ngOnInit() {
await this._initLocalStream();
await this._initSocket();
// await this.ngAfterViewInit();
await this._initMr();
}
private _initSocket() {
this.socket = io(`https://dev.ajanuw.com:3333/audio`);
this.socket.on(MESSAGE_EVENT, (data) => {
this.saveFile(
new Blob([data.audio], {
type: data.type,
})
);
});
}
private async _initLocalStream() {
this.localStream = await this.mediaDevicesService.getUserMedia({
audio: true,
});
}
private async _initMr() {
this.mr = new MediaRecorder(this.localStream);
this.mr.addEventListener('dataavailable', (e: any) => {
if (e.data.size > 0) this.recordedChunks.push(e.data);
});
this.mr.addEventListener('stop', () => {
const type = 'audio/mp3; codecs=opus';
const blob = new Blob(this.recordedChunks, {
type,
});
this._sendServer(blob, type);
});
}
saveFile(blob: Blob) {
const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = 'acetest.mp3';
downloadLink.click();
}
ngAfterViewInit(): void {
if (!this.localStream) return;
this.audioRef.nativeElement.srcObject = this.localStream;
}
download() {
this.isStart = false;
this.mr.stop();
}
start() {
this.isStart = true;
this.mr.start();
}
/**
* 将录制的audio blob发送给服务器
*/
private async _sendServer(audio: Blob, type: string) {
this.socket.emit(MESSAGE_EVENT, { audio, type });
}
}
服务器
import {
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Socket } from 'socket.io';
import { MESSAGE_EVENT } from '@live-video-example/p2p';
@WebSocketGateway({ namespace: 'audio' })
export class AudioGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server: Socket;
handleDisconnect(client: Socket) {}
handleConnection(client: Socket, ...args: any[]) {}
@SubscribeMessage(MESSAGE_EVENT)
onMessage(client: Socket, payload: any): any {
console.log(payload);
client.emit(MESSAGE_EVENT, payload);
}
}
See also: