Ah okay, will try to improve my naming conventions, thanks. I don’t think I’m using any kind of proxy objects or anything like that. I really just have this one monolithic frontend function and two backend functions and it works almost all of the way through (i.e. I don’t get any issue when I check canConsume
, only after, when I attempt to consume via the client consumerTransport):
Client function:
const handleViewStream = () => {
viewStream({ variables: { params: { username: streamer.username } } }).then(
async ({ data }) => {
if (data && "viewStream" in data) {
const {
viewStream: { params, routerCapabilities },
} = data
try {
const consumeDevice = new mediasoup.Device()
await consumeDevice.load({
routerRtpCapabilities: routerCapabilities,
})
const consumerTransport = consumeDevice.createRecvTransport(params)
consumerTransport.on(
"connect",
async ({ dtlsParameters }, callback, errback) => {
console.log("!!!!!!!!!!!!!!!!!!!connect")
// socket?.emit("connectConsumerTransport", {
// transportId: transport.id,
// dtlsParameters,
// streamerUsername: streamer.username,
// })
// socket.on("consumerConnected", async function (data) {
// console.log("!![ms]consumerConnected", data)
// callback()
// })
}
)
consumerTransport.on("connectionstatechange", (state) => {
console.log("!![ms]connectionStateChange", data)
switch (state) {
case "connecting":
console.log("!!Consumer: ICE State Connecting")
break
case "connected":
console.log("!!Consumer: ICE State Connected")
// socket?.emit("resume", { streamerUsername: streamer.username })
break
case "failed":
console.log("!!Consumer: ICE State Failed")
consumerTransport.close()
// socket?.emit("stopViewingStream", {
// streamerUsername: streamer.username,
// viewerUsername: user.username,
// })
break
default:
break
}
})
consume({
variables: {
rtpCapabilities: consumeDevice.rtpCapabilities,
streamerUsername: streamer.username,
},
}).then(async ({ data }) => {
if (data && "consume" in data) {
const { subData } = data.consume
const { id, producerId, kind, rtpParameters } = subData
consumerTransport
.consume({
id,
producerId,
kind,
rtpParameters,
})
.then((res) => {
console.log("!!res", res)
})
.catch((e) => {
console.log("!!e", e)
})
}
})
} catch (error) {
if (error.name === "UnsupportedError") {
console.log("!!Browser not supported")
}
}
}
}
)
}
Server side functions:
export const getStream = async (db: Kysely<Database>, { args, context }) => {
try {
const { user: currentUser } = context
const {
params: { username },
} = args
if (!currentUser) {
return new Error("Not logged in")
}
if (!streams[username]) {
return new Error("User is not live")
}
const routerCapabilities = await getRouterCapabilities()
const { transport, params } = await createWebRtcTransport(router)
streams[username] = {
...streams[username],
consumerTransports: {
...streams[username].consumerTransports,
[currentUser.username]: transport,
},
}
return { params, routerCapabilities }
} catch (error) {
console.log("!!error", error)
return new Error("Request could not be processed")
}
}
export const consume = async (db: Kysely<Database>, { args, context }) => {
try {
const { user: currentUser } = context
const { rtpCapabilities, streamerUsername } = args
if (
!router.canConsume({
producerId: streams[streamerUsername].producer.id,
rtpCapabilities,
})
) {
console.log("!!Cannot Consume")
return
}
try {
const newConsumer = await streams[streamerUsername].consumerTransports[
currentUser.username
].consume({
producerId: streams[streamerUsername].producer.id,
rtpCapabilities,
paused: streams[streamerUsername].producer.kind === "video",
})
streams[streamerUsername] = {
...streams[streamerUsername],
consumers: {
...streams[streamerUsername].consumers,
[currentUser.username]: newConsumer,
},
}
const subData = {
producerId: streams[streamerUsername].producer.id,
id: newConsumer.id,
kind: newConsumer.kind,
rtpParameters: newConsumer.rtpParameters,
type: newConsumer.type,
producerPaused: newConsumer.producerPaused,
}
return {
subData: subData,
stream: streams[streamerUsername],
}
} catch (error) {
console.log("!!error", error)
return
}
} catch (error) {
console.log("!!error", error)
}
}
I guess my use of in-memory data structures is pretty horrible but I’m kind of aware of that. I’m just trying to learn at the moment so will improve things after. I think the producer stuff is all working now and I think almost all of the consumer stuff is working, it just seems to run into this issue of the read only property right at the end when I call consumerTransport.consume
.
I appreciate you probably don’t have the time or desire to look through the above code. Just wanted to post it for the sake of a more complete thread and in case anyone else fancies taking a look.