This commit is contained in:
parent
6d0250bbef
commit
9b967c2dde
@ -31,13 +31,9 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style>
|
||||||
.dropZone {
|
.dropZone {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
i, h2 {
|
|
||||||
color: #aaaaaa
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i.pi.pi-upload {
|
i.pi.pi-upload {
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
<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>
|
||||||
<template v-if="!state.active">
|
<Card class="p-mb-4" v-show="state.active">
|
||||||
<FileSelect class="p-mb-4" v-if="!state.fileSelected" message="Drag a H.264 encoded MP4 here to start a screen." @selected="filesSelected" />
|
<template #content>
|
||||||
<Card class="p-mb-4" v-else>
|
<video id="player" controls="true"></video>
|
||||||
|
</template>
|
||||||
|
</Card>
|
||||||
|
<div v-if="!state.active" key="host-pending">
|
||||||
|
<FileSelect class="p-mb-4" v-if="!state.fileSelected" key="file-select" message="Drag a H.264 encoded MP4 here to start a screen." @selected="onFilesSelected" />
|
||||||
|
<Card class="p-mb-4" v-else key="file-selected">
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="p-text-center">
|
<div class="p-text-center">
|
||||||
<ProgressSpinner />
|
<ProgressSpinner />
|
||||||
@ -11,13 +16,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Card>
|
</Card>
|
||||||
</template>
|
</div>
|
||||||
<Card class="p-mb-4" v-show="state.active">
|
<div v-else key="host-live">
|
||||||
<template #content>
|
<Card class="p-mb-4">
|
||||||
<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>
|
||||||
@ -25,12 +26,13 @@
|
|||||||
<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-mb-4" :wires="wires" v-show="state.active" />
|
<HostWires class="p-mb-4" :wires="wires"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { inject, onBeforeUnmount, reactive } from 'vue'
|
import { inject, onBeforeUnmount, onMounted, 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'
|
||||||
@ -49,14 +51,20 @@ export default {
|
|||||||
uploadSpeed: 0,
|
uploadSpeed: 0,
|
||||||
wires: []
|
wires: []
|
||||||
})
|
})
|
||||||
const webTorrent = new WebTorrent()
|
var webTorrent = null
|
||||||
const wires = reactive([])
|
const wires = reactive([])
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onMounted(() => {
|
||||||
webTorrent.destroy()
|
webTorrent = new WebTorrent()
|
||||||
})
|
})
|
||||||
|
|
||||||
const filesSelected = (f) => {
|
onBeforeUnmount(() => {
|
||||||
|
if (webTorrent) {
|
||||||
|
webTorrent.destroy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const onFilesSelected = (f) => {
|
||||||
if (f?.length !== 1 || !f[0].name.endsWith('.mp4') || f[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 })
|
||||||
} else {
|
} else {
|
||||||
@ -76,8 +84,13 @@ export default {
|
|||||||
state.active = true
|
state.active = true
|
||||||
state.infoHash = torrent.infoHash
|
state.infoHash = torrent.infoHash
|
||||||
|
|
||||||
|
var fileRendered = false
|
||||||
|
|
||||||
file.createReadStream().on('data', () => {
|
file.createReadStream().on('data', () => {
|
||||||
|
if (!fileRendered) {
|
||||||
file.renderTo('#player')
|
file.renderTo('#player')
|
||||||
|
fileRendered = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
torrent.on('upload', bytes => {
|
torrent.on('upload', bytes => {
|
||||||
@ -106,7 +119,7 @@ export default {
|
|||||||
}, 500)
|
}, 500)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filesSelected,
|
onFilesSelected,
|
||||||
state,
|
state,
|
||||||
wires
|
wires
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,51 @@
|
|||||||
<template>
|
<template>
|
||||||
<h1>Join</h1>
|
<div class="p-p-6">
|
||||||
<InputText />
|
<h1 class="p-my-0">Join</h1>
|
||||||
|
<Card>
|
||||||
|
<template #content>
|
||||||
|
<div class="p-fluid p-formgrid p-grid p-jc-center">
|
||||||
|
<div class="p-field p-col-12 p-lg-8">
|
||||||
|
<InputText :placeholder="defaultId" v-model="id" @keydown.enter="onIdSelected" />
|
||||||
|
</div>
|
||||||
|
<div class="p-field p-col-12 p-lg-2">
|
||||||
|
<Button label="Join" @click="onIdSelected" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
import { ref } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useToast } from 'primevue/usetoast'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup () {
|
||||||
|
const router = useRouter()
|
||||||
|
const toast = useToast()
|
||||||
|
const id = ref()
|
||||||
|
const defaultId = '08ada5a7a6183aae1e09d831df6748d566095a10'
|
||||||
|
const onIdSelected = () => {
|
||||||
|
if (!id.value) {
|
||||||
|
id.value = defaultId
|
||||||
|
}
|
||||||
|
if (!/^([a-f0-9]{40})$/.test(id.value)) {
|
||||||
|
toast.add({ severity: 'error', summary: 'Bad ID', detail: 'Please enter a valid ID.', life: 3000 })
|
||||||
|
} else {
|
||||||
|
router.push(`/join/${id.value}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
defaultId,
|
||||||
|
onIdSelected
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,14 +1,84 @@
|
|||||||
<template>
|
<template>
|
||||||
<h1>Screen {{ id }}</h1>
|
<div class="p-p-6">
|
||||||
|
<h1 class="p-my-0">Watch</h1>
|
||||||
|
<Card class="p-mb-4" v-if="state.wires.length === 0">
|
||||||
|
<template #content>
|
||||||
|
<div class="p-text-center">
|
||||||
|
<ProgressSpinner />
|
||||||
|
<h2>Waiting for connections. Please wait...</h2>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Card>
|
||||||
|
<Card class="p-mb-4" v-show="state.wires.length !== 0">
|
||||||
|
<template #content>
|
||||||
|
<video id="player" controls="true"></video>
|
||||||
|
</template>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { inject, onBeforeMount, onBeforeUnmount, onMounted, reactive } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useToast } from 'primevue/usetoast'
|
||||||
|
import WebTorrent from 'webtorrent/webtorrent.min.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
id: {
|
id: {
|
||||||
required: true,
|
required: true,
|
||||||
type: String
|
type: String
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
setup (props) {
|
||||||
|
const router = useRouter()
|
||||||
|
const toast = useToast()
|
||||||
|
const trackers = inject('trackers')
|
||||||
|
const state = reactive({
|
||||||
|
wires: []
|
||||||
|
})
|
||||||
|
var webTorrent = null
|
||||||
|
|
||||||
|
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()
|
||||||
|
webTorrent.add(props.id, { announce: trackers }, function (torrent) {
|
||||||
|
var file = torrent.files.find(function (file) {
|
||||||
|
return file.name.endsWith('.mp4')
|
||||||
|
})
|
||||||
|
|
||||||
|
var fileRendered = false
|
||||||
|
|
||||||
|
file.createReadStream().on('data', () => {
|
||||||
|
if (!fileRendered) {
|
||||||
|
file.renderTo('#player')
|
||||||
|
fileRendered = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
torrent.on('wire', wire => {
|
||||||
|
console.log(wire)
|
||||||
|
state.wires.push(wire)
|
||||||
|
toast.add({ severity: 'info', summary: 'New watcher', detail: 'Someone has joined your screen.', life: 3000 })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (webTorrent) {
|
||||||
|
webTorrent.destroy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user