Add peer statistics and seeding
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			This commit is contained in:
		
							parent
							
								
									285d35bc2a
								
							
						
					
					
						commit
						3211828695
					
				
							
								
								
									
										32
									
								
								src/components/HostWires.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/components/HostWires.vue
									
									
									
									
									
										Normal 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>
 | 
				
			||||||
@ -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',
 | 
				
			||||||
 | 
				
			|||||||
@ -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>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user