Add video output to host view
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
87959d0f3b
commit
a30db82afe
|
@ -5,9 +5,9 @@
|
||||||
<i class="pi pi-upload"></i>
|
<i class="pi pi-upload"></i>
|
||||||
<h2>{{ message }}</h2>
|
<h2>{{ message }}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
<input type="file" hidden="true" ref="fileInput" @change="selected" />
|
||||||
</template>
|
</template>
|
||||||
</Card>
|
</Card>
|
||||||
<input type="file" hidden="true" ref="fileInput" @change="selected" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Wire statistics
|
Wire statistics
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<DataTable :value="wires" autoLayout=true>
|
<DataTable :value="wires" :autoLayout="true">
|
||||||
<Column field="peerId" header="Wire ID"></Column>
|
<Column field="peerId" header="Wire ID"></Column>
|
||||||
<Column field="remoteAddress" header="Remote address"></Column>
|
<Column field="remoteAddress" header="Remote address"></Column>
|
||||||
<Column field="uploadSpeed" header="Upload speed"></Column>
|
<Column field="uploadSpeed" header="Upload speed"></Column>
|
||||||
|
|
|
@ -15,6 +15,7 @@ import DataTable from 'primevue/datatable'
|
||||||
import InputText from 'primevue/inputtext'
|
import InputText from 'primevue/inputtext'
|
||||||
import MenuBar from 'primevue/menubar'
|
import MenuBar from 'primevue/menubar'
|
||||||
import ProgressBar from 'primevue/progressbar'
|
import ProgressBar from 'primevue/progressbar'
|
||||||
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
import Toast from 'primevue/toast'
|
import Toast from 'primevue/toast'
|
||||||
import ToastService from 'primevue/toastservice'
|
import ToastService from 'primevue/toastservice'
|
||||||
import 'primeflex/primeflex.css'
|
import 'primeflex/primeflex.css'
|
||||||
|
@ -36,6 +37,7 @@ app.component('DataTable', DataTable)
|
||||||
app.component('InputText', InputText)
|
app.component('InputText', InputText)
|
||||||
app.component('MenuBar', MenuBar)
|
app.component('MenuBar', MenuBar)
|
||||||
app.component('ProgressBar', ProgressBar)
|
app.component('ProgressBar', ProgressBar)
|
||||||
|
app.component('ProgressSpinner', ProgressSpinner)
|
||||||
app.component('Toast', Toast)
|
app.component('Toast', Toast)
|
||||||
|
|
||||||
// Register VCinemaApp components.
|
// Register VCinemaApp components.
|
||||||
|
|
|
@ -1,9 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="p-p-6">
|
<div class="p-p-6">
|
||||||
<h1 class="p-my-0">Host</h1>
|
<h1 class="p-my-0">Host</h1>
|
||||||
<FileSelect v-if="!state.active" message="Drag a H.264 encoded MP4 here to start a screen." @selected="filesSelected" />
|
<template v-if="!state.active">
|
||||||
<div v-else>
|
<FileSelect class="p-mb-4" v-if="!state.fileSelected" message="Drag a H.264 encoded MP4 here to start a screen." @selected="filesSelected" />
|
||||||
<Card>
|
<Card class="p-mb-4" v-else>
|
||||||
|
<template #content>
|
||||||
|
<div class="p-text-center">
|
||||||
|
<ProgressSpinner />
|
||||||
|
<h2>Generating hash. Please wait...</h2>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Card>
|
||||||
|
</template>
|
||||||
|
<Card class="p-mb-4" v-show="state.active">
|
||||||
|
<template #content>
|
||||||
|
<video id="player" controls="true"></video>
|
||||||
|
</template>
|
||||||
|
</Card>
|
||||||
|
<Card class="p-mb-4" v-show="state.active">
|
||||||
<template #title>
|
<template #title>
|
||||||
Info hash
|
Info hash
|
||||||
</template>
|
</template>
|
||||||
|
@ -11,13 +25,12 @@
|
||||||
<InputText id="infoHash" type="text" v-model="state.infoHash" disabled />
|
<InputText id="infoHash" type="text" v-model="state.infoHash" disabled />
|
||||||
</template>
|
</template>
|
||||||
</Card>
|
</Card>
|
||||||
<HostWires class="p-mt-4" :wires="wires" />
|
<HostWires class="p-mb-4" :wires="wires" v-show="state.active" />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { inject, onBeforeUnmount, onMounted, reactive } from 'vue'
|
import { inject, onBeforeUnmount, reactive } from 'vue'
|
||||||
import { useToast } from 'primevue/usetoast'
|
import { useToast } from 'primevue/usetoast'
|
||||||
import prettyBytes from 'pretty-bytes'
|
import prettyBytes from 'pretty-bytes'
|
||||||
import sha1 from 'crypto-js/sha1'
|
import sha1 from 'crypto-js/sha1'
|
||||||
|
@ -29,52 +42,59 @@ export default {
|
||||||
const trackers = inject('trackers')
|
const trackers = inject('trackers')
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
active: false,
|
active: false,
|
||||||
|
fileSelected: false,
|
||||||
infoHash: '',
|
infoHash: '',
|
||||||
size: 0,
|
size: 0,
|
||||||
uploaded: 0,
|
uploaded: 0,
|
||||||
uploadSpeed: 0,
|
uploadSpeed: 0,
|
||||||
wires: []
|
wires: []
|
||||||
})
|
})
|
||||||
|
const webTorrent = new WebTorrent()
|
||||||
const wires = reactive([])
|
const wires = reactive([])
|
||||||
var webTorrent
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
webTorrent = new WebTorrent()
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
webTorrent.destroy()
|
webTorrent.destroy()
|
||||||
})
|
})
|
||||||
|
|
||||||
const filesSelected = (files) => {
|
const filesSelected = (f) => {
|
||||||
if (files?.length !== 1 || !files[0].name.endsWith('.mp4') || files[0].type !== 'video/mp4') {
|
if (f?.length !== 1 || !f[0].name.endsWith('.mp4') || f[0].type !== 'video/mp4') {
|
||||||
toast.add({ severity: 'error', summary: 'Bad file input', detail: 'You must select a single H.264 encoded MP4.', life: 3000 })
|
toast.add({ severity: 'error', summary: 'Bad file input', detail: 'You must select a single H.264 encoded MP4.', life: 3000 })
|
||||||
return
|
} else {
|
||||||
|
state.fileSelected = true
|
||||||
}
|
}
|
||||||
|
|
||||||
seedFile(files[0])
|
seedFile(f[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
const seedFile = (file) => {
|
const seedFile = (file) => {
|
||||||
webTorrent.seed(file, { announce: trackers }, (torrent) => {
|
webTorrent.seed(file, { announce: trackers }, (torrent) => {
|
||||||
toast.add({ severity: 'success', summary: 'File added', detail: `You are now sharing ${file.name}`, life: 5000 })
|
var file = torrent.files.find(file => {
|
||||||
|
return file.name.endsWith('.mp4')
|
||||||
|
})
|
||||||
|
|
||||||
|
state.size = file.size
|
||||||
state.active = true
|
state.active = true
|
||||||
state.infoHash = torrent.infoHash
|
state.infoHash = torrent.infoHash
|
||||||
state.size = file.size
|
|
||||||
|
|
||||||
torrent.on('upload', (bytes) => {
|
file.createReadStream().on('data', () => {
|
||||||
|
file.renderTo('#player')
|
||||||
|
})
|
||||||
|
|
||||||
|
torrent.on('upload', bytes => {
|
||||||
state.uploaded += bytes
|
state.uploaded += bytes
|
||||||
})
|
})
|
||||||
|
|
||||||
torrent.on('wire', (wire) => {
|
torrent.on('wire', wire => {
|
||||||
state.wires.push(wire)
|
state.wires.push(wire)
|
||||||
toast.add({ severity: 'info', summary: 'New watcher', detail: 'Someone has joined your screen.', life: 3000 })
|
toast.add({ severity: 'info', summary: 'New watcher', detail: 'Someone has joined your screen.', life: 3000 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
toast.add({ severity: 'success', summary: 'File added', detail: `You are now sharing ${file.name}`, life: 5000 })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const newWires = state.wires.map((wire) => ({
|
const newWires = state.wires.map(wire => ({
|
||||||
peerId: sha1(wire.peerId).toString().substring(0, 100),
|
peerId: sha1(wire.peerId).toString().substring(0, 100),
|
||||||
remoteAddress: wire.remoteAddress,
|
remoteAddress: wire.remoteAddress,
|
||||||
uploadSpeed: prettyBytes(wire.uploadSpeed()) + 'ps',
|
uploadSpeed: prettyBytes(wire.uploadSpeed()) + 'ps',
|
||||||
|
@ -95,7 +115,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#infoHash {
|
#infoHash, video#player {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue