All checks were successful
continuous-integration/drone/push Build is passing
172 lines
4.4 KiB
Vue
172 lines
4.4 KiB
Vue
<template>
|
|
<h1>Watch</h1>
|
|
<Card class="p-text-center" v-if="!state.active">
|
|
<template #content>
|
|
<ProgressSpinner />
|
|
<h2>Waiting for connections. Please wait...</h2>
|
|
</template>
|
|
</Card>
|
|
<div v-show="state.active">
|
|
<Card >
|
|
<template #content>
|
|
<ProgressBar class="p-mb-2" :value="progress" :showValue="false" />
|
|
<video ref="player" controls="true"></video>
|
|
</template>
|
|
</Card>
|
|
<Card>
|
|
<template #title>
|
|
Properties
|
|
</template>
|
|
<template #content>
|
|
<div class="p-grid">
|
|
<div class="p-col-12 p-md-4">
|
|
<h5>Filename</h5>
|
|
<span>{{video.name}}</span>
|
|
</div>
|
|
<div class="p-col-12 p-md-4">
|
|
<h5>Duration</h5>
|
|
<span>{{video.hDuration}}</span>
|
|
</div>
|
|
<div class="p-col-12 p-md-4">
|
|
<h5>File size</h5>
|
|
<span>{{video.hSize}}</span>
|
|
</div>
|
|
<div class="p-col-12">
|
|
<h5>ID</h5>
|
|
<div class="p-fluid">
|
|
<InputText class="p-inputtext-sm" :value="state.infoHash" disabled />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</Card>
|
|
<WireStatistics :wireStatistics="wireStatistics"/>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { inject, onBeforeMount, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useToast } from 'primevue/usetoast'
|
|
import prettyBytes from 'pretty-bytes'
|
|
import prettyMilliseconds from 'pretty-ms'
|
|
import WebTorrent from 'webtorrent/webtorrent.min.js'
|
|
import generateWireStatistics from '@/helpers/wire-statistics'
|
|
|
|
export default {
|
|
props: {
|
|
id: {
|
|
required: true,
|
|
type: String
|
|
}
|
|
},
|
|
setup (props) {
|
|
const router = useRouter()
|
|
const toast = useToast()
|
|
const trackers = inject('trackers')
|
|
var webTorrent = null
|
|
const player = ref(null)
|
|
const progress = ref()
|
|
const video = reactive({
|
|
file: null,
|
|
name: '',
|
|
size: 0,
|
|
duration: 0,
|
|
hSize: '',
|
|
hDuration: ''
|
|
})
|
|
const state = reactive({
|
|
active: false,
|
|
torrent: null,
|
|
infoHash: '',
|
|
downloaded: 0,
|
|
wires: []
|
|
})
|
|
const wireStatistics = reactive([])
|
|
|
|
onBeforeMount(() => {
|
|
if (!/^([a-f0-9]{40})$/.test(props.id)) {
|
|
toast.add({ severity: 'error', summary: 'Bad ID', detail: 'Please enter a valid ID.', life: 3000 })
|
|
router.push('/join')
|
|
}
|
|
})
|
|
|
|
onMounted(() => {
|
|
webTorrent = new WebTorrent()
|
|
downloadVideo(props.id)
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
if (webTorrent) {
|
|
webTorrent.destroy()
|
|
}
|
|
})
|
|
|
|
const downloadVideo = (infoHash) => {
|
|
webTorrent.add(infoHash, { announce: trackers }, torrent => {
|
|
torrent.on('wire', () => {
|
|
updateWireStatistics()
|
|
toast.add({ severity: 'info', summary: 'New watcher', detail: 'Someone has joined your screen.', life: 3000 })
|
|
})
|
|
|
|
torrent.on('noPeers', () => {
|
|
toast.add({ severity: 'warning', summary: 'No peers', detail: 'No one is sharing this video at the moment.', life: 3000 })
|
|
})
|
|
|
|
torrent.on('upload', bytes => {
|
|
updateWireStatistics()
|
|
})
|
|
|
|
torrent.on('download', bytes => {
|
|
if (!state.active) {
|
|
state.active = true
|
|
initialise(torrent)
|
|
}
|
|
state.downloaded += bytes
|
|
progress.value = state.downloaded / video.size * 100
|
|
updateWireStatistics()
|
|
})
|
|
})
|
|
}
|
|
|
|
const initialise = (torrent) => {
|
|
state.torrent = torrent
|
|
state.infoHash = torrent.infoHash
|
|
state.wires = torrent.wires
|
|
|
|
var file = torrent.files.find(file => {
|
|
return file.name.endsWith('.mp4')
|
|
})
|
|
|
|
video.file = file
|
|
video.name = file.name
|
|
video.size = file.length
|
|
video.hSize = prettyBytes(file.length)
|
|
player.value.addEventListener('loadedmetadata', (e) => {
|
|
video.duration = e.target.duration
|
|
video.hDuration = prettyMilliseconds(e.target.duration * 1000)
|
|
})
|
|
|
|
file.renderTo(player.value)
|
|
}
|
|
|
|
const updateWireStatistics = () => {
|
|
var newWireStatistics = generateWireStatistics(state.wires)
|
|
wireStatistics.splice.apply(wireStatistics, [0, newWireStatistics.length].concat(newWireStatistics))
|
|
}
|
|
|
|
return {
|
|
player,
|
|
video,
|
|
state,
|
|
progress,
|
|
wireStatistics
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
|
|
</style>
|