VCinema/src/views/Screen.vue
Jack Hadrill 201ee9813f
All checks were successful
continuous-integration/drone/push Build is passing
Improve playback
2021-01-06 03:55:38 +00:00

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>