Skip to content

Commit

Permalink
Support local files
Browse files Browse the repository at this point in the history
  • Loading branch information
ed-asriyan committed Feb 19, 2024
1 parent 726b2b4 commit 639ab0a
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 20 deletions.
3 changes: 2 additions & 1 deletion src/local-room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class LocalRoom implements Writable<RemoteRoomRaw> {
if (!newTime || Math.abs(newRemoteRoom.time - newTime) > maximumDelta) {
newTime = newRemoteRoom.time;
}
set({ url: newRemoteRoom.url, paused: newRemoteRoom.paused, time: newTime });
set({ ...newRemoteRoom, time: newTime });
});
});
}
Expand All @@ -34,6 +34,7 @@ export class LocalRoom implements Writable<RemoteRoomRaw> {
const remoteValue = getStore(this.remoteRoom);

if (
remoteValue.isLocalMode !== newValue.isLocalMode ||
remoteValue.paused !== newValue.paused ||
remoteValue.url !== newValue.url ||
Math.abs(getStore(this.remoteRoom).time - val.time) > syncInterval
Expand Down
2 changes: 2 additions & 0 deletions src/remote-room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface RemoteRoomRaw {
url: string;
time: number;
paused: boolean;
isLocalMode: boolean;
}

export class RemoteRoom implements Writable<RemoteRoomRaw> {
Expand All @@ -31,6 +32,7 @@ export class RemoteRoom implements Writable<RemoteRoomRaw> {
url: '',
paused: true,
time: 0,
isLocalMode: false,
};
}
this.store.set(initRoom);
Expand Down
42 changes: 38 additions & 4 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { v4 as uuidv4 } from 'uuid';
import VideoView from './video-view.svelte';
import Loader from './loader.svelte';
import VideoSelector from './video-selector.svelte';
import { RemoteRoom } from '../remote-room';
import { LocalRoom } from '../local-room';
Expand All @@ -21,6 +22,9 @@
let isLoading = true;
$: remoteRoom.load().finally(() => isLoading = false);
$: localRoom = new LocalRoom(remoteRoom);
let blobUrl: string;
$: playUrl = $localRoom?.isLocalMode ? blobUrl : $localRoom?.url;
const copyToClipboard = function (text: string) {
const input = document.createElement('input');
Expand All @@ -29,13 +33,16 @@
input.select();
document.execCommand('copy');
document.body.removeChild(input);
}
};
const copyUrl = function () {
copyToClipboard($page.url.href);
};
$: isUrlValid = (() => {
if ($localRoom?.isLocalMode) {
return blobUrl;
}
try {
const url = new URL($localRoom.url);
return url.protocol === "http:" || url.protocol === "https:";
Expand All @@ -61,6 +68,21 @@
{:else}
<div class="uk-container uk-container-small">
<h3>1. Select a video</h3>
<ul class="uk-subnav uk-subnav-pill " uk-switcher>
<li class:uk-active={!$localRoom.isLocalMode}>
<a on:click={() => $localRoom.isLocalMode = false}>Online link</a>
</li>
<li class:uk-active={$localRoom.isLocalMode}>
<a on:click={() => $localRoom.isLocalMode = true}>Local file</a>
</li>
</ul>

{#if $localRoom.isLocalMode}
<div class="uk-margin">
You all downloaded a movie already!? Well done! Everyone should select the same video file, please.
</div>
<VideoSelector bind:videoUri={blobUrl}/>
{:else}
<div class="uk-margin">
Insert a link to YouTube, Vimeo, HLS playlist, video or audio file. The input is synchronized with everyone in the room.
</div>
Expand All @@ -69,7 +91,9 @@
class="uk-input"
class:uk-form-danger={$localRoom.url && !isUrlValid}
placeholder="Video URL"
disabled={$localRoom.isLocalMode}
/>
{/if}
</div>
{/if}
</div>
Expand All @@ -91,9 +115,15 @@
<div class="uk-margin">
Playback, time, and video scrolling are synchronized with everyone who has the page open.
</div>
{#if isUrlValid}
<VideoView bind:paused={$localRoom.paused} bind:time={$localRoom.time} bind:url={$localRoom.url}/>
{/if}
<div class="uk-text-center">
{#if isUrlValid}
<VideoView bind:paused={$localRoom.paused} bind:time={$localRoom.time} url={playUrl}/>
{:else}
<div class="stub uk-text-small">
Video player will appear here when you insert a link or select a video
</div>
{/if}
</div>
</div>
</div>
{/if}
Expand All @@ -106,4 +136,8 @@
.window-height {
min-height: 100vh;
}
.stub {
margin-top: 15rem;
}
</style>
31 changes: 31 additions & 0 deletions src/routes/video-selector.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script lang="ts">
export let videoUri: string;
let fileName: string;
let input: HTMLInputElement;
const loadSource = async function (file: any): Promise<void> {
console.log(file);
videoUri = window.URL.createObjectURL(file) as string;
fileName = file.name;
};
</script>

<input bind:this={input} type="file" on:change={e => loadSource(e.target.files[0])}/>
<button on:click={() => input.click()} class="uk-button uk-button-default">
{#if fileName}
Click to select another video
{:else}
Click to select video file
{/if}
</button>
{#if fileName}
<span class="uk-margin-left">{fileName}</span>
{/if}

<style lang="scss">
input {
display: none;
}
</style>
52 changes: 37 additions & 15 deletions src/routes/video-view.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
$: isMounted && (player.currentTime = time);
$: isMounted && (player.paused = paused);
$: isBlob = url.startsWith('blob:');
const onLoaded = function (this: HTMLVideoElement) {
this.currentTime = time;
};
onMount(() => {
player.subscribe(options => {
paused = options.paused;
Expand All @@ -33,18 +39,34 @@
});
</script>

<media-player
bind:this={player}
src={url}
autoplay
playsInline
preload="metadata"
crossOrigin
muted
>
<media-provider>
</media-provider>
<!-- Layouts -->
<media-audio-layout />
<media-video-layout />
</media-player>
{#if isBlob}
<video
src={url}
autoplay
playsInline
preload="metadata"
crossOrigin="anonymous"
bind:paused={paused}
bind:currentTime={time}
on:loadeddata={onLoaded}
muted
controls
>
</video>
{/if}
<media-player
class:uk-invisible={isBlob}
bind:this={player}
src={url}
autoplay
playsInline
preload="metadata"
crossOrigin
muted
>
<media-provider>
</media-provider>
<!-- Layouts -->
<media-audio-layout />
<media-video-layout />
</media-player>

0 comments on commit 639ab0a

Please sign in to comment.