+
+
@@ -29,8 +31,16 @@ const { tracksMap } = useQall()
diff --git a/src/composables/qall/useLiveKitSDK.ts b/src/composables/qall/useLiveKitSDK.ts
index 288be36ce..6e5d33a49 100644
--- a/src/composables/qall/useLiveKitSDK.ts
+++ b/src/composables/qall/useLiveKitSDK.ts
@@ -12,15 +12,24 @@ import type {
LocalTrackPublication,
LocalParticipant,
Participant,
- TrackPublication
+ LocalTrack
} from 'livekit-client'
import { ref, type Ref } from 'vue'
import { useToastStore } from '/@/store/ui/toast'
+import apis from '/@/lib/apis'
const { addErrorToast } = useToastStore()
-type TrackInfo = {
- trackPublication: TrackPublication | undefined
+export type TrackInfo = (
+ | {
+ isRemote: true
+ trackPublication: RemoteTrackPublication
+ }
+ | {
+ isRemote: false
+ trackPublication: LocalTrackPublication | undefined
+ }
+) & {
participantIdentity: string
}
@@ -36,6 +45,7 @@ function handleTrackSubscribed(
if (track.kind === Track.Kind.Video || track.kind === Track.Kind.Audio) {
// attach it to a new HTMLVideoElement or HTMLAudioElement
tracksMap.value.set(publication.trackSid, {
+ isRemote: true,
trackPublication: publication,
participantIdentity: participant.identity
})
@@ -64,8 +74,9 @@ function handleLocalTrackPublished(
participant: LocalParticipant
) {
// when local tracks are ended, update UI to remove them from rendering
- if (!publication.track || publication.track.kind === Track.Kind.Audio) return
+ if (!publication.track) return
tracksMap.value.set(publication.trackSid, {
+ isRemote: false,
trackPublication: publication,
participantIdentity: participant.identity
})
@@ -82,14 +93,28 @@ function handleDisconnect() {
const joinRoom = async (roomName: string, userName: string) => {
try {
+ const traQtoken = (await apis.getMyQRCode(true)).data
+ console.log(traQtoken)
const res = await fetch(
- `http://localhost:3000/getToken?roomName=${roomName}&participantName=${userName}`
+ `https://easy-livekit-token-publisher.trap.show/token`,
+ {
+ method: 'GET',
+ headers: {
+ Authorization: `Bearer ${traQtoken}`,
+ 'Content-Type': 'application/json'
+ }
+ }
)
- const token = await res.text()
+ const json = await res.json()
+ const token = json.token
+
// pre-warm connection, this can be called as early as your page is loaded
//room.prepareConnection("https://livekit-test.trap.show:39357", token);
room.value = new Room()
- await room.value.prepareConnection('ws://localhost:7880', token)
+ await room.value.prepareConnection(
+ 'wss://livekit.qall-dev.trapti.tech',
+ token
+ )
console.log(token)
// set up event listeners
@@ -102,7 +127,7 @@ const joinRoom = async (roomName: string, userName: string) => {
.on(RoomEvent.LocalTrackPublished, handleLocalTrackPublished)
// connect to room
- await room.value.connect('ws://localhost:7880', token)
+ await room.value.connect('wss://livekit.qall-dev.trapti.tech', token)
console.log('connected to room', room.value.name)
// publish local camera and mic tracks
@@ -121,9 +146,7 @@ const joinRoom = async (roomName: string, userName: string) => {
dtx: false
}
)
- await room.value.localParticipant.setScreenShareEnabled(true, {
- audio: true
- })
+ await room.value.localParticipant.setAttributes({})
} catch {
addErrorToast('Qallの接続に失敗しました')
await leaveRoom()
@@ -143,26 +166,105 @@ async function leaveRoom() {
window.removeEventListener('beforeunload', leaveRoom)
}
+const Attributes = ref<{ [key: string]: string }>({})
+
const addScreenShareTrack = async () => {
try {
if (!room.value) {
addErrorToast('ルームが存在しません')
return
}
- const localTrack = await createLocalScreenTracks({})
- localTrack.map(async t => {
- await room.value?.localParticipant.publishTrack(t)
+ const localTracks = await createLocalScreenTracks({
+ audio: true
})
+
+ await Promise.all(
+ localTracks.map(async t => {
+ await room.value?.localParticipant.publishTrack(t)
+ })
+ )
+ const videoSid = localTracks.find(t => t.kind === Track.Kind.Video)?.sid
+ const audioSid = localTracks.find(t => t.kind === Track.Kind.Audio)?.sid
+ if (audioSid && videoSid) {
+ Attributes.value = {
+ ...room.value.localParticipant.attributes,
+ [videoSid]: audioSid
+ }
+ await room.value.localParticipant.setAttributes({
+ ...room.value.localParticipant.attributes,
+ [videoSid]: audioSid
+ })
+ }
} catch {
addErrorToast('スクリーン共有に失敗しました')
}
}
+const removeScreenShareTrack = async (
+ localpublication: LocalTrackPublication
+) => {
+ if (localpublication.track) {
+ if (!room.value) {
+ addErrorToast('ルームが存在しません')
+ return
+ }
+
+ const { [localpublication.trackSid]: audioSid, ...newAttributes } =
+ Attributes.value
+ //room.value.localParticipant.attributes
+ console.log(audioSid)
+ await room.value.localParticipant.unpublishTrack(
+ localpublication.track,
+ true
+ )
+ console.log(audioSid)
+ room.value.localParticipant.setAttributes(newAttributes)
+ Attributes.value = newAttributes
+ if (!audioSid) {
+ return
+ }
+
+ const audioTrack = tracksMap.value.get(audioSid)
+ console.log(audioTrack)
+ console.log(tracksMap.value)
+ if (
+ !audioTrack ||
+ audioTrack.isRemote ||
+ !audioTrack.trackPublication?.track
+ ) {
+ return
+ }
+
+ await room.value.localParticipant.unpublishTrack(
+ audioTrack.trackPublication.track,
+ true
+ )
+ }
+}
+
+const setLocalTrackMute = async (track: LocalTrack, muted: boolean) => {
+ if (muted) {
+ await track.mute()
+ } else {
+ await track.unmute()
+ }
+}
+
+const setTrackEnabled = (
+ publication: RemoteTrackPublication,
+ muted: boolean
+) => {
+ publication.setEnabled(!muted)
+}
+
export const useLiveKitSDK = () => {
return {
joinRoom,
leaveRoom,
addScreenShareTrack,
+ removeScreenShareTrack,
+ setTrackEnabled,
+ setLocalTrackMute,
tracksMap
}
}
diff --git a/src/composables/qall/useQall.ts b/src/composables/qall/useQall.ts
index ba7152909..8577104b4 100644
--- a/src/composables/qall/useQall.ts
+++ b/src/composables/qall/useQall.ts
@@ -2,11 +2,27 @@ import { ref } from 'vue'
import { useLiveKitSDK } from '/@/composables/qall/useLiveKitSDK'
import { useMeStore } from '/@/store/domain/me'
import { useToastStore } from '/@/store/ui/toast'
+import type { LocalAudioTrack, LocalVideoTrack } from 'livekit-client'
const isCalling = ref(false)
-const { joinRoom, leaveRoom, addScreenShareTrack, tracksMap } = useLiveKitSDK()
+const {
+ joinRoom,
+ leaveRoom,
+ addScreenShareTrack,
+ removeScreenShareTrack,
+ setLocalTrackMute,
+ tracksMap
+} = useLiveKitSDK()
const { myId } = useMeStore()
const { addErrorToast } = useToastStore()
+
+const setSpeakerMute = (track: LocalAudioTrack, muted: boolean) => {
+ setLocalTrackMute(track, muted)
+}
+
+const setVideoMute = (track: LocalVideoTrack, muted: boolean) => {
+ setLocalTrackMute(track, muted)
+}
export const useQall = () => {
const toggleCalling = (channelName: string) => {
if (isCalling.value) {
@@ -23,6 +39,8 @@ export const useQall = () => {
return {
isCalling,
toggleCalling,
+ addScreenShareTrack,
+ removeScreenShareTrack,
tracksMap
}
}