You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.5 KiB

<script>
import wt from '$/client/wt.js';
import { onMount, onDestroy } from 'svelte';
import { defer, random_numbers } from '$/client/helpers.js';
import { inject_remote } from "./Source.svelte";
import Spinner from './Spinner.svelte';
import ProgressMeter from './ProgressMeter.svelte';
import { log } from "$/client/logging.js";
export let media;
// whether to add a download link to download the video
export let aspect_ratio = "16/9";
export let autoplay = false;
export let muted = false;
export let controls = true;
let video_ready = false;
let video_done = false;
let progress = 0;
let peers = 0;
let up_rate = 0;
let down_rate = 0;
let time_remaining = 0;
let activated = false;
let loading_promise = defer("wt loading promise");
class VideoEvents extends wt.WTEvents {
done() {
video_done = true;
}
videoReady(file) {
super.videoReady(file);
video_ready = true;
this.intervalId = setInterval(() => {
down_rate = (this.torrent.downloadSpeed / 1024 / 1024).toFixed(2);
up_rate = (this.torrent.uploadSpeed / 1024 / 1024).toFixed(2);
time_remaining = (this.torrent.timeRemaining / 1000).toFixed(0);
peers = this.torrent.numPeers;
}, 1000);
}
download_available(url) {
media.download_url = url;
}
download(bytes) {
let count = Math.floor(this.torrent.progress * 100);
// don't want to overload svelte with tons of updates, it kind of eats it
if(count % 2 == 0 || count % 5 == 0) {
progress = count;
peers = this.torrent.numPeers;
}
}
wire(wire) {
log.debug("wire", wire);
peers = this.torrent.numPeers;
}
noPeers(announceType) {
log.debug("announce", announceType);
peers = this.torrent.numPeers;
}
}
onDestroy(() => {
if(activated) wt.remove(media)
});
const load_media = async () => {
if(await wt.fetch_torrent_file(media)) {
await inject_remote(document, "/js/webtorrent.js", () => {
// generate a temporary target for the loader div
media.target_id = random_numbers(1)[0];
wt.load(media, new VideoEvents(media, {autoplay, controls, muted}));
activated = true;
loading_promise.resolve();
});
} else {
log.debug("Failure loading torrent file.");
}
}
onMount(async () => {
// BUG: this "guard" is here because svelte will load this component
// twice when its inside an await block. First time it loads it but
// doesn't set any properties, then the second time it sets the properties.
if(media && media.torrent_url) {
await load_media();
}
});
</script>
<style>
video {
width: 100%;
}
card {
min-width: unset;
box-shadow: unset;
border-radius: unset;
border: unset;
max-height: calc(95vh - var(--fixed-header-height));
}
card top {
max-height: calc(95vh - var(--fixed-header-height));
}
card bottom {
padding: 0px;
}
</style>
{#await loading_promise}
<Spinner color="var(--value4)" aspect_ratio="16/9" />
{:then}
<card data-testid="video-torrent-body">
<top style="--aspect-ratio: { aspect_ratio };">
<video id="append-{media.target_id}"
muted={muted}
autoplay={autoplay}
controls={ controls}
preload={ media.preload }
poster={media.poster}>
</video>
</top>
<bottom>
<ProgressMeter percent={ progress } show_percent={ false } />
</bottom>
</card>
{/await}