初始提交

This commit is contained in:
fsy
2025-03-18 16:40:47 +08:00
commit 1dfedce690
23 changed files with 4025 additions and 0 deletions

164
src/services/agora.js Normal file
View File

@@ -0,0 +1,164 @@
import AgoraRTC from 'agora-rtc-sdk-ng';
class AgoraService {
constructor() {
this.client = null;
this.localAudioTrack = null;
this.uid = null;
this.isJoined = false;
this.remoteUsers = {};
this.volumeIndicator = null;
this.vadEnabled = true;
this.vadParams = {
interruptDurationMs: 160,
prefixPaddingMs: 300,
silenceDurationMs: 480,
threshold: 0.5
};
}
/**
* Initialize the Agora RTC client
*/
init() {
this.client = AgoraRTC.createClient({ mode: 'rtc', codec: 'vp8' });
this.setupEventListeners();
return this.client;
}
/**
* Set up event listeners for the Agora client
*/
setupEventListeners() {
this.client.on('user-published', async (user, mediaType) => {
await this.client.subscribe(user, mediaType);
if (mediaType === 'audio') {
user.audioTrack.play();
this.remoteUsers[user.uid] = user;
}
});
this.client.on('user-unpublished', (user) => {
if (user.audioTrack) {
user.audioTrack.stop();
}
delete this.remoteUsers[user.uid];
});
this.client.on('user-left', (user) => {
delete this.remoteUsers[user.uid];
});
this.client.on('volume-indicator', (volumes) => {
volumes.forEach((volume) => {
// Handle volume indicator
if (volume.uid === this.uid) {
// Local user's volume
const event = new CustomEvent('local-volume', {
detail: { level: volume.level }
});
window.dispatchEvent(event);
}
});
});
}
/**
* Join a channel with the given token and channel name
* @param {string} token - The token for authentication
* @param {string} channel - The channel name to join
* @param {string} uid - The user ID (optional)
*/
async join(token, channel, uid = null) {
try {
this.uid = uid || `user_${Math.floor(Math.random() * 1000000)}`;
// Join the channel
await this.client.join(token, channel, this.uid);
this.isJoined = true;
// Create and publish local audio track
this.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack({
AEC: true,
AGC: true,
ANS: true
});
// Enable VAD (Voice Activity Detection)
if (this.vadEnabled && this.localAudioTrack.setVADMode) {
this.localAudioTrack.setVADMode(true, this.vadParams);
}
// Publish local audio track
await this.client.publish([this.localAudioTrack]);
// Enable volume indicator
this.client.enableAudioVolumeIndicator();
return true;
} catch (error) {
console.error('Error joining channel:', error);
return false;
}
}
/**
* Leave the channel and release resources
*/
async leave() {
if (this.localAudioTrack) {
this.localAudioTrack.close();
this.localAudioTrack = null;
}
await this.client.leave();
this.isJoined = false;
this.remoteUsers = {};
}
/**
* Mute or unmute the local audio
* @param {boolean} mute - Whether to mute the audio
*/
muteAudio(mute) {
if (this.localAudioTrack) {
if (mute) {
this.localAudioTrack.setEnabled(false);
} else {
this.localAudioTrack.setEnabled(true);
}
}
}
/**
* Check if the local audio is muted
* @returns {boolean} - Whether the audio is muted
*/
isAudioMuted() {
return this.localAudioTrack ? !this.localAudioTrack.enabled : true;
}
/**
* Set the VAD parameters
* @param {Object} params - The VAD parameters
*/
setVADParams(params) {
this.vadParams = { ...this.vadParams, ...params };
if (this.localAudioTrack && this.localAudioTrack.setVADMode) {
this.localAudioTrack.setVADMode(this.vadEnabled, this.vadParams);
}
}
/**
* Enable or disable VAD
* @param {boolean} enabled - Whether to enable VAD
*/
enableVAD(enabled) {
this.vadEnabled = enabled;
if (this.localAudioTrack && this.localAudioTrack.setVADMode) {
this.localAudioTrack.setVADMode(enabled, this.vadParams);
}
}
}
export default new AgoraService();