Add peer statistics and seeding
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Jack Hadrill 2021-01-04 05:28:58 +00:00
parent 285d35bc2a
commit 3211828695
3 changed files with 98 additions and 20 deletions

View File

@ -0,0 +1,32 @@
<template>
<Card>
<template #title>
Peer statistics
</template>
<template #content>
<DataTable :value="wires">
<Column field="ip" header="IP"></Column>
<Column field="downloadSpeed" header="Download Speed"></Column>
<Column field="downloaded" header="Downloaded"></Column>
</DataTable>
</template>
</Card>
</template>
<script>
export default {
props: {
wires: {
type: Object,
required: true
}
},
setup (props) {
}
}
</script>
<style>
</style>

View File

@ -4,13 +4,17 @@ import Router from './router'
// Import global components. // Import global components.
import FileSelect from '@/components/FileSelect.vue' import FileSelect from '@/components/FileSelect.vue'
import HostWires from '@/components/HostWires.vue'
// Import PrimeVue dependencies. // Import PrimeVue dependencies.
import PrimeVue from 'primevue/config' import PrimeVue from 'primevue/config'
import Button from 'primevue/button' import Button from 'primevue/button'
import Card from 'primevue/card' import Card from 'primevue/card'
import Column from 'primevue/column'
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 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'
@ -27,12 +31,16 @@ app.use(ToastService)
// Register PrimeVue components. // Register PrimeVue components.
app.component('Button', Button) app.component('Button', Button)
app.component('Card', Card) app.component('Card', Card)
app.component('Column', Column)
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('Toast', Toast) app.component('Toast', Toast)
// Register VCinemaApp components. // Register VCinemaApp components.
app.component('FileSelect', FileSelect) app.component('FileSelect', FileSelect)
app.component('HostWires', HostWires)
app.provide('trackers', [ app.provide('trackers', [
'wss://tracker.sloppyta.co:443/announce', 'wss://tracker.sloppyta.co:443/announce',

View File

@ -1,50 +1,88 @@
<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="!file" message="Drag a H.264 encoded MP4 here to start a screen." @selected="filesSelected" /> <FileSelect v-if="!state.active" message="Drag a H.264 encoded MP4 here to start a screen." @selected="filesSelected" />
<div v-else>
<Card>
<template #title>
Info hash
</template>
<template #content>
<InputText id="infoHash" type="text" v-model="state.infoHash" disabled />
</template>
</Card>
<HostWires class="p-mt-4" :wires="wires" />
</div>
</div> </div>
</template> </template>
<script> <script>
import { inject, reactive } from 'vue'
import { useToast } from 'primevue/usetoast' import { useToast } from 'primevue/usetoast'
import { inject, ref, reactive } from 'vue' import WebTorrent from 'webtorrent/webtorrent.min.js'
const validateFileInput = (files) => {
if (files?.length !== 1 || !files[0].name.endsWith('.mp4') || files[0].type !== 'video/mp4') {
return false
}
return true
}
export default { export default {
setup () { setup () {
const toast = useToast() const toast = useToast()
const trackers = inject('trackers') const trackers = inject('trackers')
const file = ref() const state = reactive({
const torrentState = reactive({ active: false,
active: false infoHash: '',
size: 0,
uploaded: 0,
uploadSpeed: 0,
wires: []
}) })
const wires = reactive([])
setInterval(() => {
const newWires = state.wires.map((wire) => ({
ip: wire.remoteAddress,
downloadSpeed: wire.uploadSpeed(),
downloaded: wire.uploaded
}))
wires.splice.apply(wires, [0, newWires.length].concat(newWires))
}, 500)
const filesSelected = (files) => { const filesSelected = (files) => {
if (!validateFileInput(files)) { if (files?.length !== 1 || !files[0].name.endsWith('.mp4') || files[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 })
} else { return
file.value = files[0]
} }
console.log(trackers) seedFile(files[0])
}
const seedFile = (file) => {
const webTorrent = new WebTorrent()
webTorrent.seed(file, { announce: trackers }, (torrent) => {
toast.add({ severity: 'success', summary: 'File added', detail: `You are now sharing ${file.name}`, life: 5000 })
state.active = true
state.infoHash = torrent.infoHash
state.size = file.size
torrent.on('upload', (bytes) => {
state.uploaded += bytes
})
torrent.on('wire', (wire) => {
state.wires.push(wire)
toast.add({ severity: 'info', summary: 'New watcher', detail: 'Someone has joined your screen.', life: 3000 })
})
})
} }
return { return {
filesSelected, filesSelected,
file, state,
torrentState wires
} }
} }
} }
</script> </script>
<style> <style>
#infoHash {
width: 100%;
}
</style> </style>