Skip to content
This repository was archived by the owner on Feb 27, 2023. It is now read-only.

Commit 72c45ac

Browse files
kuruk-mmmenduz
andauthored
refactor: new voice chat sagas and add livekit voice chat (#443)
* w * checkpoint * wip * wip * split voice chat sagas * wip * wip * checkpoint: new voice sagas working with opus * delete old voice sagas * add missing libopus.wasm.js add livekit voice handler * fix * change token handle * update unity-renderer * livekit with custom and temporal server to get token * improve livekit voice chat * room names by realm and island * todo comment * better logs * fix: remove initialization of voice chat sagas from kernel (#453) * feat: add spatial sound (need more test) feat: add ff for livekit connection (independent from transport) * checkpoint * working for chrome * remove logs * typo * fix ff * fix * fix * remove undefined type * use ff * minor issues (#465) Co-authored-by: menduz <github@menduz.com>
1 parent 1573518 commit 72c45ac

35 files changed

Lines changed: 1078 additions & 375 deletions

package-lock.json

Lines changed: 104 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"devDependencies": {
2828
"@dcl/eslint-config": "^1.0.5-20220608210046.commit-d51d9ec",
2929
"@dcl/posix": "^1.0.3",
30-
"@dcl/unity-renderer": "^1.0.41205-20220623213209.commit-67ba18f",
30+
"@dcl/unity-renderer": "^1.0.49884-20220818143841.commit-421e39d",
3131
"@microsoft/api-documenter": "^7.2.2",
3232
"@microsoft/api-extractor": "^7.1.7",
3333
"@tweenjs/tween.js": "^17.2.0",
@@ -98,6 +98,7 @@
9898
"gifuct-js": "^2.0.0",
9999
"google-protobuf": "^3.6.1",
100100
"hls.js": "^0.14.17",
101+
"livekit-client": "^1.2.10",
101102
"mitt": "^3.0.0",
102103
"mz-observable": "^1.0.1",
103104
"p-queue": "^7.1.0",

packages/shared/Html.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ export default class Html {
22
static loopbackAudioElement() {
33
const audio = document.getElementById('voice-chat-audio')
44
if (!audio) {
5-
console.error('There is no #voice-chat-audio element to use with VoiceChat')
5+
console.error('There is no #voice-chat-audio element to use with VoiceChat. Returning a `new Audio()`')
6+
return new Audio()
67
}
78
return audio as HTMLAudioElement | undefined
89
}

packages/shared/comms/actions.ts

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,5 @@
11
import { action } from 'typesafe-actions'
2-
import type { VoiceCommunicator } from 'voice-chat-codec/VoiceCommunicator'
32
import type { CommsContext } from './context'
4-
import type { VoicePolicy } from './types'
5-
6-
export const VOICE_PLAYING_UPDATE = '[COMMS] voicePlayingUpdate'
7-
export const voicePlayingUpdate = (userId: string, playing: boolean) =>
8-
action(VOICE_PLAYING_UPDATE, { userId, playing })
9-
export type VoicePlayingUpdate = ReturnType<typeof voicePlayingUpdate>
10-
11-
export const INIT_VOICE_COMMUNICATOR = '[COMMS] setVoiceCommunicator'
12-
export const setVoiceCommunicator = (voiceCommunicator: VoiceCommunicator | null) =>
13-
action(INIT_VOICE_COMMUNICATOR, { voiceCommunicator })
14-
15-
/**
16-
* Action to join voice chat
17-
*/
18-
export const JOIN_VOICE_CHAT = '[COMMS] joinVoiceChat'
19-
export const joinVoiceChat = () => action(JOIN_VOICE_CHAT)
20-
21-
/**
22-
* Action to leave voice chat
23-
*/
24-
export const LEAVE_VOICE_CHAT = '[COMMS] leaveVoiceChat'
25-
export const leaveVoiceChat = () => action(LEAVE_VOICE_CHAT)
26-
27-
/**
28-
* Action to trigger voice chat recording
29-
*/
30-
export const SET_VOICE_CHAT_RECORDING = '[COMMS] setVoiceChatRecording'
31-
export const setVoiceChatRecording = (recording: boolean) => action(SET_VOICE_CHAT_RECORDING, { recording })
32-
export type SetVoiceChatRecording = ReturnType<typeof setVoiceChatRecording>
33-
34-
/**
35-
* Action to toggle voice chat recording
36-
*/
37-
export const TOGGLE_VOICE_CHAT_RECORDING = '[COMMS] toggleVoiceChatRecording'
38-
export const toggleVoiceChatRecording = () => action(TOGGLE_VOICE_CHAT_RECORDING)
39-
export type ToggleVoiceChatRecording = ReturnType<typeof toggleVoiceChatRecording>
40-
41-
/**
42-
* Action triggered when recording starts or stops
43-
*/
44-
export const VOICE_RECORDING_UPDATE = '[COMMS] voiceRecordingUpdate'
45-
export const voiceRecordingUpdate = (recording: boolean) => action(VOICE_RECORDING_UPDATE, { recording })
46-
export type VoiceRecordingUpdate = ReturnType<typeof voiceRecordingUpdate>
47-
48-
export const SET_VOICE_VOLUME = '[COMMS] setVoiceVolume'
49-
export const setVoiceVolume = (volume: number) => action(SET_VOICE_VOLUME, { volume })
50-
export type SetVoiceVolume = ReturnType<typeof setVoiceVolume>
51-
52-
export const SET_VOICE_MUTE = '[COMMS] setVoiceMute'
53-
export const setVoiceMute = (mute: boolean) => action(SET_VOICE_MUTE, { mute })
54-
export type SetVoiceMute = ReturnType<typeof setVoiceMute>
55-
56-
export const SET_VOICE_POLICY = '[COMMS] setVoicePolicy'
57-
export const setVoicePolicy = (voicePolicy: VoicePolicy) => action(SET_VOICE_POLICY, { voicePolicy })
58-
export type SetVoicePolicy = ReturnType<typeof setVoicePolicy>
593

604
export const SET_COMMS_ISLAND = '[COMMS] setCommsIsland'
615
export const setCommsIsland = (island: string | undefined) => action(SET_COMMS_ISLAND, { island })

packages/shared/comms/handlers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { messageReceived } from '../chat/actions'
2323
import { getBannedUsers } from 'shared/meta/selectors'
2424
import { getIdentity } from 'shared/session'
2525
import { CommsContext } from './context'
26-
import { processVoiceFragment } from './voice-over-comms'
26+
import { processVoiceFragment } from 'shared/voiceChat/handlers'
2727
import future, { IFuture } from 'fp-future'
2828
import { handleCommsDisconnection } from './actions'
2929
import { Avatar } from '@dcl/schemas'
@@ -34,7 +34,7 @@ import { trackEvent } from 'shared/analytics'
3434
import { ProfileType } from 'shared/profiles/types'
3535
import { ensureAvatarCompatibilityFormat } from 'shared/profiles/transformations/profileToServerFormat'
3636
import { scenesSubscribedToCommsEvents } from './sceneSubscriptions'
37-
import { isBlockedOrBanned } from './voice-selectors'
37+
import { isBlockedOrBanned } from 'shared/voiceChat/selectors'
3838

3939
const receiveProfileOverCommsChannel = new Observable<Avatar>()
4040
const sendMyProfileOverCommsChannel = new Observable<Record<string, never>>()

packages/shared/comms/reducer.ts

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,12 @@ import { AnyAction } from 'redux'
22

33
import { COMMS_ESTABLISHED } from 'shared/loading/types'
44

5-
import { CommsState, VoicePolicy } from './types'
6-
import {
7-
INIT_VOICE_COMMUNICATOR,
8-
SET_COMMS_ISLAND,
9-
SET_VOICE_CHAT_RECORDING,
10-
SET_VOICE_POLICY,
11-
SET_WORLD_CONTEXT,
12-
TOGGLE_VOICE_CHAT_RECORDING
13-
} from './actions'
5+
import { CommsState } from './types'
6+
import { SET_COMMS_ISLAND, SET_WORLD_CONTEXT } from './actions'
147

158
const INITIAL_COMMS: CommsState = {
169
initialized: false,
17-
voiceChatRecording: false,
18-
voicePolicy: VoicePolicy.ALLOW_ALL,
19-
context: undefined,
20-
voiceCommunicator: null
10+
context: undefined
2111
}
2212

2313
export function commsReducer(state?: CommsState, action?: AnyAction): CommsState {
@@ -30,15 +20,6 @@ export function commsReducer(state?: CommsState, action?: AnyAction): CommsState
3020
switch (action.type) {
3121
case COMMS_ESTABLISHED:
3222
return { ...state, initialized: true }
33-
case INIT_VOICE_COMMUNICATOR:
34-
return { ...state, voiceCommunicator: action.payload.voiceCommunicator }
35-
case SET_VOICE_CHAT_RECORDING:
36-
if (action.payload.recording === state.voiceChatRecording) return state
37-
return { ...state, voiceChatRecording: action.payload.recording }
38-
case TOGGLE_VOICE_CHAT_RECORDING:
39-
return { ...state, voiceChatRecording: !state.voiceChatRecording }
40-
case SET_VOICE_POLICY:
41-
return { ...state, voicePolicy: action.payload.voicePolicy }
4223
case SET_COMMS_ISLAND:
4324
return { ...state, island: action.payload.island }
4425
case SET_WORLD_CONTEXT:

packages/shared/comms/sagas.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { commsEstablished, FATAL_ERROR } from 'shared/loading/types'
44
import { CommsContext, commsLogger } from './context'
55
import { getCommsContext, getRealm } from './selectors'
66
import { BEFORE_UNLOAD } from 'shared/protocol/actions'
7-
import { voiceSaga } from './voice-sagas'
87
import {
98
HandleCommsDisconnection,
109
HANDLE_COMMS_DISCONNECTION,
@@ -192,8 +191,6 @@ function* handleNewCommsContext() {
192191
// disconnect previous context
193192
yield call(disconnectContext, oldContext)
194193
}
195-
196-
yield call(voiceSaga)
197194
})
198195
}
199196

packages/shared/comms/selectors.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,10 @@
11
import { Realm } from 'shared/dao/types'
2-
import { isFeatureToggleEnabled } from 'shared/selectors'
3-
import { VOICE_CHAT_FEATURE_TOGGLE } from 'shared/types'
4-
import { lastPlayerScene } from 'shared/world/sceneState'
5-
import type { VoiceCommunicator } from 'voice-chat-codec/VoiceCommunicator'
62
import type { CommsContext } from './context'
73
import { RootCommsState } from './types'
84

9-
export const isVoiceChatRecording = (store: RootCommsState) => store.comms.voiceChatRecording
10-
export const getVoicePolicy = (store: RootCommsState) => store.comms.voicePolicy
115
export const getCommsIsland = (store: RootCommsState): string | undefined => store.comms.island
126
export const getRealm = (store: RootCommsState): Realm | undefined => store.comms.context?.realm
137
export const getCommsContext = (state: RootCommsState): CommsContext | undefined => state.comms.context
14-
export const getVoiceCommunicator = (store: RootCommsState): VoiceCommunicator | null => {
15-
return store.comms.voiceCommunicator
16-
}
17-
18-
export function isVoiceChatAllowedByCurrentScene() {
19-
return isFeatureToggleEnabled(VOICE_CHAT_FEATURE_TOGGLE, lastPlayerScene?.entity.metadata)
20-
}
218

229
export function sameRealm(realm1: Realm, realm2: Realm) {
2310
return (

0 commit comments

Comments
 (0)