Skip to content

Commit 91e6c6a

Browse files
committed
chore: add support for preview tracks for gamesource
1 parent 34383a2 commit 91e6c6a

File tree

3 files changed

+128
-9
lines changed

3 files changed

+128
-9
lines changed

src/core/data.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
* Copyright (c) Infiniscene, Inc. All rights reserved.
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
* -------------------------------------------------------------------------------------------- */
5-
import { CoreContext, InternalSource,log } from './context'
5+
import { LayoutApiModel, LiveApiModel } from '@api.stream/sdk'
66
import { toSceneTree } from '../logic'
7-
import { Context, SDK, Compositor } from './namespaces'
8-
import { LiveApiModel, LayoutApiModel } from '@api.stream/sdk'
9-
import { getRoom } from './webrtc/simple-room'
7+
import { Permission, hasPermission } from './../helpers/permission'
8+
import { CoreContext, InternalSource } from './context'
9+
import { Compositor, Context, SDK } from './namespaces'
1010
import { ProjectBroadcastPhase } from './types'
11-
import { Permission, hasPermission } from './../helpers/permission';
11+
import { getRoom } from './webrtc/simple-room'
1212

1313
const { state } = CoreContext
1414

src/core/requests.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@
99
* Not every external request is represented here. In some cases
1010
* it is simpler to use the API SDK client interface directly.
1111
*/
12+
import { LiveApiModel } from '@api.stream/sdk'
13+
import { Helpers } from '.'
1214
import {
1315
CoreContext,
1416
InternalProject,
1517
InternalSource,
16-
InternalUser,
17-
log
18+
InternalUser
1819
} from './context'
1920
import { getAccessTokenData, getProject, getUser, hydrateProject } from './data'
20-
import { Helpers } from '.'
2121
import { Props, Role } from './types'
22-
import { LiveApiModel } from '@api.stream/sdk'
2322

2423
export const createProject = async (request: {
2524
settings?: { [prop: string]: any }

src/core/sources/Game.ts

+120
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const Game = {
4343
init({ addSource, removeSource, updateSource, getSource }) {
4444
// Updated by engine socket events
4545
let gameSourceStreams: { [id: string]: MediaStream } = {}
46+
let previousTracks: SDK.Track[] = []
4647
// Updated by corecontext events
4748
let previousGameSources: SDK.Source[] = []
4849

@@ -86,6 +87,125 @@ export const Game = {
8687
})
8788
}
8889

90+
CoreContext.on('RoomJoined', ({ projectId, room }) => {
91+
const project = toBaseProject(getProject(projectId))
92+
if (project.role !== SDK.Role.ROLE_RENDERER) {
93+
const updatePreviewStreams = () => {
94+
previousTracks
95+
.filter((p) => p?.type === 'screen_share' && p?.isExternal === true)
96+
.forEach((track) => {
97+
if (track.type === 'screen_share') {
98+
const srcObject = gameSourceStreams[track.participantId]
99+
const participant = room.getParticipant(track.participantId)
100+
// only do anything if it is for an Game source
101+
const isGameSource = previousGameSources.some(
102+
(source) => source.id === participant.id,
103+
)
104+
if (isGameSource) {
105+
const videoTrack = room.getTrack(track.id)
106+
const source = getSource(`game-${participant?.id}`)
107+
if (source) {
108+
const audioTrack = room.getTracks().find((track) => {
109+
return (
110+
track.participantId === participant.id &&
111+
track.mediaStreamTrack.kind === 'audio'
112+
)
113+
})
114+
updateMediaStreamTracks(srcObject, {
115+
video: videoTrack?.mediaStreamTrack,
116+
audio: audioTrack?.mediaStreamTrack,
117+
})
118+
119+
updateSource(`game-${participant?.id}`, {
120+
videoEnabled: Boolean(
121+
videoTrack?.mediaStreamTrack && !videoTrack.isMuted,
122+
),
123+
audioEnabled: Boolean(audioTrack && !audioTrack.isMuted),
124+
mirrored: participant?.meta[track.id]?.isMirrored,
125+
external: track?.isExternal,
126+
})
127+
}
128+
}
129+
}
130+
})
131+
}
132+
133+
// listen for changes to available tracks
134+
room.useTracks((tracks) => {
135+
// Filter for those that are game-source
136+
const gameSourceTracks = tracks
137+
.filter((t) =>
138+
previousGameSources.some((s) => s.id === t.participantId),
139+
)
140+
.filter((t) => ['screen_share'].includes(t.type))
141+
142+
// get tracks not contained in previous tracks
143+
const newTracks = gameSourceTracks.filter(
144+
(track) =>
145+
!previousTracks.some((x) => x.id === track.id) &&
146+
Boolean(track?.mediaStreamTrack),
147+
)
148+
149+
// get previous tracks not contained in current tracks
150+
const removedTracks = previousTracks.filter(
151+
(t) => !gameSourceTracks.some((x) => x.id === t.id),
152+
)
153+
154+
// Filter out racks that have a mediaStreamTrack
155+
previousTracks = gameSourceTracks.filter((t) =>
156+
Boolean(t?.mediaStreamTrack),
157+
)
158+
159+
removedTracks.forEach((track) => {
160+
const { participantId } = track
161+
const srcObject = gameSourceStreams[participantId]
162+
163+
if (track.mediaStreamTrack.kind === 'video') {
164+
updateMediaStreamTracks(srcObject, {
165+
video: null,
166+
})
167+
updateSource(`game-${participantId}`, {
168+
videoEnabled: false,
169+
})
170+
}
171+
if (track.mediaStreamTrack.kind === 'audio') {
172+
updateMediaStreamTracks(srcObject, {
173+
audio: null,
174+
})
175+
updateSource(`game-${participantId}`, {
176+
audioEnabled: false,
177+
})
178+
}
179+
})
180+
181+
newTracks.forEach((track) => {
182+
if (
183+
track.type === 'screen_share' &&
184+
track.mediaStreamTrack.kind === 'video'
185+
) {
186+
const srcObject = gameSourceStreams[track.participantId]
187+
const audioTrack = previousTracks.find((t) => {
188+
return (
189+
t.participantId === track.participantId &&
190+
t.mediaStreamTrack?.kind === 'audio'
191+
)
192+
})
193+
updateMediaStreamTracks(srcObject, {
194+
video: track?.mediaStreamTrack,
195+
audio: audioTrack?.mediaStreamTrack,
196+
})
197+
updateSource(`game-${track.participantId}`, {
198+
videoEnabled: Boolean(track && !track?.isMuted),
199+
audioEnabled: Boolean(audioTrack && !audioTrack?.isMuted),
200+
})
201+
}
202+
})
203+
204+
updatePreviewStreams()
205+
})
206+
}
207+
})
208+
89209
CoreContext.on('ActiveProjectChanged', ({ projectId }) => {
90210
const project = toBaseProject(getProject(projectId))
91211
const sources = project.sources.filter(

0 commit comments

Comments
 (0)