Embed WebRTC stream directly

master
informatic 2018-06-20 17:00:09 +02:00
parent 3e9a5cf347
commit b81b2b6fce
4 changed files with 107 additions and 3 deletions

View File

@ -21,6 +21,7 @@ const createLintingRule = () => ({
module.exports = {
context: path.resolve(__dirname, '../'),
externals: {"ws": "WebSocket"},
entry: {
app: './src/main.js'
},

View File

@ -11,6 +11,7 @@
"build": "node build/build.js"
},
"dependencies": {
"@techteamer/janus-api": "^3.1.0",
"axios": "^0.18.0",
"socket.io-client": "^2.1.1",
"vue": "^2.5.2",

View File

@ -0,0 +1,90 @@
<template>
<video controls></video>
</template>
<script>
import { Janus, StreamingJanusPlugin } from '@techteamer/janus-api'
export default {
props: ['config', 'stream'],
beforeDestroy () {
clearInterval(this.bitrateInterval)
clearInterval(this.bufferingInterval)
},
mounted () {
let janus = this.janus = new Janus(this.config, console)
let streaming = new StreamingJanusPlugin(console, false)
let peerConnection = new RTCPeerConnection()
this.bitrateInterval = setInterval(() => {
// @TODO
peerConnection.getStats().then((stats) => {
// console.info(Array.from(stats.entries()))
})
this.$emit('bitrate', 0)
}, 1000)
this.$emit('status', 'init')
janus.connect().then(() => {
return janus.addPlugin(streaming)
}).then(() => {
console.info('plugin added', janus)
peerConnection.onicecandidate = (event) => {
console.log('@onicecandidate', event)
if (!event.candidate || !event.candidate.candidate) {
streaming.candidate({completed: true})
} else {
streaming.candidate({
candidate: event.candidate.candidate,
sdpMid: event.candidate.sdpMid,
sdpMLineIndex: event.candidate.sdpMLineIndex
})
}
}
peerConnection.onaddstream = (mediaStreamEvent) => {
console.log('@onaddstream', mediaStreamEvent)
let videoElement = this.$el
videoElement.srcObject = mediaStreamEvent.stream
videoElement.play()
if (this.bufferingInterval === undefined) {
let lastPosition = 0
this.bufferintInterval = setInterval(() => {
if (lastPosition === videoElement.currentTime && !videoElement.paused) {
this.$emit('status', 'buffering')
} else {
this.$emit('status', 'playing')
}
lastPosition = videoElement.currentTime
}, 500)
}
}
streaming.on('webrtcState', (a, b) => { console.log('webrtcState', a, b) })
streaming.on('mediaState', (a, b) => { console.log('mediaState', a, b) })
streaming.on('statusChange', (status) => {
console.log('statusChange', status)
this.$emit('status', status)
})
return streaming.watch(this.stream)
}).then((jsep) => {
return peerConnection.setRemoteDescription(new RTCSessionDescription(jsep))
}).then(() => {
console.log('remoteDescription set')
return peerConnection.createAnswer({offerToReceiveAudio: true, offerToReceiveVideo: true})
}).then(answer => {
console.log('answerCreated', answer)
peerConnection.setLocalDescription(answer)
return streaming.start(answer)
}).then(({body, json}) => {
console.log('START', body, json)
})
}
}
</script>

View File

@ -2,7 +2,12 @@
<a-row>
<a-col :span="8">
<Scene v-bind:scene="currentScene" />
<iframe src="http://10.8.0.95:8080/" class="videoframe"></iframe>
<a-spin :spinning="streamStatus != 'playing'">
<JanusStream :config="{ url: 'ws://10.8.0.95:8188' }" :stream="10" class="videoframe"
@status="streamStatus = $event"
@bitrate="streamBitrate = $event" />
</a-spin>
</a-col>
<a-col :span="8" v-for="item in frames" :key="item.id">
<Frame v-bind:scene="currentScene" v-bind:frame="item" v-bind:sources="sources"/>
@ -13,12 +18,19 @@
<script>
import Scene from '@/components/Scene.vue'
import Frame from '@/components/Frame.vue'
import JanusStream from '@/components/JanusStream.vue'
export default {
name: 'SceneView',
components: {
Scene,
Frame
Frame,
JanusStream
},
data () {
return {
streamStatus: null
}
},
computed: {
sources () {
@ -42,9 +54,9 @@ export default {
}
.videoframe {
padding: 5px;
border: none;
background: #eee;
width: 100%;
height: 180px;
}
</style>