|
|
|
<template>
|
|
|
|
<v-container>
|
|
|
|
<v-btn @click="deviceSelectDialog = true">change</v-btn>
|
|
|
|
<v-dialog
|
|
|
|
v-model="deviceSelectDialog"
|
|
|
|
max-width="290"
|
|
|
|
>
|
|
|
|
<v-card>
|
|
|
|
<v-card-title class="headline">Configuration</v-card-title>
|
|
|
|
|
|
|
|
<v-card-text>
|
|
|
|
<v-row>
|
|
|
|
<v-col md="12" cols="12">
|
|
|
|
<v-select
|
|
|
|
label="Please select video device"
|
|
|
|
v-model="selectedVideo"
|
|
|
|
:items="videoDevices"
|
|
|
|
item-value="deviceId"
|
|
|
|
item-text="label"
|
|
|
|
></v-select>
|
|
|
|
<v-checkbox label="No Video" v-model="noVid"></v-checkbox>
|
|
|
|
</v-col>
|
|
|
|
<v-col md="12" cols="12">
|
|
|
|
<v-select
|
|
|
|
label="Please select audio device"
|
|
|
|
:items="audioDevices"
|
|
|
|
v-model="selectedAudio"
|
|
|
|
item-value="deviceId"
|
|
|
|
item-text="label"
|
|
|
|
></v-select>
|
|
|
|
</v-col>
|
|
|
|
</v-row>
|
|
|
|
</v-card-text>
|
|
|
|
|
|
|
|
<v-card-actions>
|
|
|
|
<v-spacer></v-spacer>
|
|
|
|
|
|
|
|
<v-btn
|
|
|
|
color="green darken-1"
|
|
|
|
text
|
|
|
|
@click="deviceSelectDialog = false"
|
|
|
|
>
|
|
|
|
Disagree
|
|
|
|
</v-btn>
|
|
|
|
|
|
|
|
<v-btn
|
|
|
|
color="green darken-1"
|
|
|
|
text
|
|
|
|
@click="selectDevice"
|
|
|
|
>
|
|
|
|
Agree
|
|
|
|
</v-btn>
|
|
|
|
</v-card-actions>
|
|
|
|
</v-card>
|
|
|
|
</v-dialog>
|
|
|
|
<v-row>
|
|
|
|
<v-col cols="12" md="3">
|
|
|
|
<video ref="ownstream" class="rounded centered" id="myvideo" width="100%" height="100%" autoplay
|
|
|
|
playsinline muted="muted"/>
|
|
|
|
</v-col>
|
|
|
|
<v-col cols="12" md="3" v-for="remoteStream in remoteStreams" :key="remoteStream.id">
|
|
|
|
<RemoteFeed :opaqueId="opaqueId" :mypvtid="mypvtid" :feedid="remoteStream.id" :janusInit="janusInit" :room="room" ></RemoteFeed>
|
|
|
|
</v-col>
|
|
|
|
</v-row>
|
|
|
|
</v-container>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import RemoteFeed from "@/lib/RemoteFeed";
|
|
|
|
export default {
|
|
|
|
components: {RemoteFeed},
|
|
|
|
props: {
|
|
|
|
server: String,
|
|
|
|
room: Number,
|
|
|
|
username: String
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
janusInit: null,
|
|
|
|
opaqueId: null,
|
|
|
|
pluginHandle: null,
|
|
|
|
mystream: null,
|
|
|
|
myid: '',
|
|
|
|
mypvtid: '',
|
|
|
|
selectedVideo: null,
|
|
|
|
selectedAudio: null,
|
|
|
|
started: false,
|
|
|
|
videoDevices: [],
|
|
|
|
audioDevices: [],
|
|
|
|
deviceSelectDialog: false,
|
|
|
|
noVid: false,
|
|
|
|
remoteStreams: []
|
|
|
|
}
|
|
|
|
},
|
|
|
|
name: "VueJanus",
|
|
|
|
mounted() {
|
|
|
|
this.janusInit = new this.$janus({
|
|
|
|
success: this.janusSuccess,
|
|
|
|
server: this.server,
|
|
|
|
error: function (error) {
|
|
|
|
this.$janus.error(error);
|
|
|
|
},
|
|
|
|
destroyed: function () {
|
|
|
|
window.location.reload();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
screenShare () {
|
|
|
|
|
|
|
|
},
|
|
|
|
janusPluginError (error) {
|
|
|
|
console.log(error)
|
|
|
|
},
|
|
|
|
consentDialog (on) {
|
|
|
|
// this.$janus.debug("Consent dialog should be " + (on ? "on" : "off") + " now");
|
|
|
|
console.log(on)
|
|
|
|
},
|
|
|
|
janusPluginSuccess (pluginHandle) {
|
|
|
|
this.pluginHandle = pluginHandle
|
|
|
|
this.$janus.log("Plugin attached! (" + this.pluginHandle.getPlugin() + ", id=" + this.pluginHandle.getId() + ")");
|
|
|
|
this.$janus.log(" -- This is a publisher/manager");
|
|
|
|
|
|
|
|
this.$janus.listDevices(this.initDevices);
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
initDevices (devices) {
|
|
|
|
console.log(devices)
|
|
|
|
devices.forEach(device => {
|
|
|
|
if (device.kind === 'videoinput') {
|
|
|
|
this.videoDevices.push(device)
|
|
|
|
}
|
|
|
|
if (device.kind === 'audioinput') {
|
|
|
|
this.audioDevices.push(device)
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
this.deviceSelectDialog = true
|
|
|
|
},
|
|
|
|
genRemoteFeed () {
|
|
|
|
this.remoteStreams.forEach(item => {
|
|
|
|
this.createRemoteFeed(item)
|
|
|
|
})
|
|
|
|
},
|
|
|
|
offerSend (jsep) {
|
|
|
|
console.log('vid offer')
|
|
|
|
var publish = {"request": "configure", "audio": true, "video": true};
|
|
|
|
|
|
|
|
this.pluginHandle.send({"message": publish, "jsep": jsep});
|
|
|
|
},
|
|
|
|
controlPublishers(msg) {
|
|
|
|
msg["publishers"].forEach(item => {
|
|
|
|
var has = false
|
|
|
|
this.remoteStreams.forEach(rm => {
|
|
|
|
if (item.id === rm.id) has = true
|
|
|
|
})
|
|
|
|
if (!has) {
|
|
|
|
this.remoteStreams.push(item)
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
},
|
|
|
|
janusMessage (msg, jsep) {
|
|
|
|
console.log(msg);
|
|
|
|
var event = msg["videoroom"];
|
|
|
|
if (event !== undefined) {
|
|
|
|
if (event === "joined") {
|
|
|
|
this.myid = msg["id"];
|
|
|
|
this.mypvtid = msg["private_id"];
|
|
|
|
this.$janus.log("Successfully joined room " + msg["room"] + " with ID " + this.myid);
|
|
|
|
this.restartDevices()
|
|
|
|
if (msg["publishers"] !== undefined && msg["publishers"] !== null) {
|
|
|
|
this.controlPublishers(msg)
|
|
|
|
}
|
|
|
|
} else if(event === "event") {
|
|
|
|
if (msg["publishers"] !== undefined && msg["publishers"] !== null) {
|
|
|
|
this.controlPublishers(msg)
|
|
|
|
|
|
|
|
} else if(msg["leaving"] !== undefined && msg["leaving"] !== null) {
|
|
|
|
console.log("leaving")
|
|
|
|
this.remoteStreams.forEach(item => {
|
|
|
|
if (item.id === msg['leaving']) this.remoteStreams.splice(this.remoteStreams.indexOf(item),1)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (jsep !== undefined && jsep !== null) {
|
|
|
|
|
|
|
|
console.log("Handling SDP as well...");
|
|
|
|
console.log(jsep);
|
|
|
|
this.pluginHandle.handleRemoteJsep({jsep: jsep});
|
|
|
|
var audio = msg["audio_codec"];
|
|
|
|
if (this.mystream && this.mystream.getAudioTracks() && this.mystream.getAudioTracks().length > 0 && !audio) {
|
|
|
|
console.log("Our audio stream has been rejected, viewers won't hear us");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onlocalstream (stream) {
|
|
|
|
this.mystream = stream
|
|
|
|
console.log(this.$refs)
|
|
|
|
console.log(this.$refs["ownstream"])
|
|
|
|
this.$refs.ownstream.srcObject = this.mystream
|
|
|
|
|
|
|
|
},
|
|
|
|
restartDevices () {
|
|
|
|
this.deviceSelectDialog = false
|
|
|
|
|
|
|
|
var media = {
|
|
|
|
audioRecv: false, videoRecv: false, audioSend: true, videoSend: !this.noVid,
|
|
|
|
audio: {
|
|
|
|
deviceId: {
|
|
|
|
exact: this.selectedAudio
|
|
|
|
}
|
|
|
|
},
|
|
|
|
replaceAudio: true, // This is only needed in case of a renegotiation
|
|
|
|
video: {
|
|
|
|
deviceId: {
|
|
|
|
exact: this.selectedVideo
|
|
|
|
}
|
|
|
|
},
|
|
|
|
replaceVideo: true,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
this.pluginHandle.createOffer(
|
|
|
|
{
|
|
|
|
media: media,
|
|
|
|
success: this.offerSend,
|
|
|
|
error: function (error) {
|
|
|
|
// An error has occurred ...
|
|
|
|
console.log(error)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
},
|
|
|
|
webrtcState (on) {
|
|
|
|
this.$janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
|
|
|
|
},
|
|
|
|
mediaState (medium, on) {
|
|
|
|
this.$janus.log("Janus " + (on ? "started" : "stopped") + " receiving our " + medium);
|
|
|
|
},
|
|
|
|
changeDevice () {
|
|
|
|
this.$refs.ownstream.setSinkId(this.selectedVideo)
|
|
|
|
this.$refs.ownstream.setSinkId(this.selectedAudio)
|
|
|
|
},
|
|
|
|
selectDevice () {
|
|
|
|
if (!this.started) {
|
|
|
|
console.log(this.selectedVideo)
|
|
|
|
console.log(this.selectedAudio)
|
|
|
|
this.started = true
|
|
|
|
var register = {
|
|
|
|
"request": "join",
|
|
|
|
"room": this.room,
|
|
|
|
"ptype": "publisher",
|
|
|
|
"display": this.username
|
|
|
|
};
|
|
|
|
this.pluginHandle.send({"message": register});
|
|
|
|
} else {
|
|
|
|
this.restartDevices()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
janusSuccess () {
|
|
|
|
this.opaqueId = "videoroomtest-" + this.$janus.randomString(12);
|
|
|
|
|
|
|
|
this.janusInit.attach(
|
|
|
|
{
|
|
|
|
plugin: "janus.plugin.videoroom",
|
|
|
|
opaqueId: this.opaqueId,
|
|
|
|
success: this.janusPluginSuccess,
|
|
|
|
consentDialog: this.consentDialog,
|
|
|
|
error: this.janusPluginError,
|
|
|
|
mediaState: this.mediaState,
|
|
|
|
webrtcState: this.webrtcState,
|
|
|
|
onmessage: this.janusMessage,
|
|
|
|
onlocalstream: this.onlocalstream
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
|
|
</style>
|