Skip to content

Instantly share code, notes, and snippets.

@moritzebeling
Last active December 31, 2021 17:14
Show Gist options
  • Save moritzebeling/c8f1d2ed03553c0f542116bdc933c27e to your computer and use it in GitHub Desktop.
Save moritzebeling/c8f1d2ed03553c0f542116bdc933c27e to your computer and use it in GitHub Desktop.
Vimeo Svelte Player
export function renderTime(sec) {
let min = Math.floor(sec / 60);
sec = Math.floor(sec - min * 60);
sec = "00" + sec;
return `${min}:${sec.slice(-2)}`;
}
export function renderPercent(fl) {
return Math.round(fl * 100);
}
export function errorHandler(err) {
console.error(err);
}
<script context="module">
const allPlayers = new Set();
</script>
<script>
import Player from "@vimeo/player";
import Progress from "./Progress.svelte";
import { onDestroy } from "svelte";
import { renderTime, renderPercent, errorHandler } from "./helpers.js";
/* parameters */
export let id;
export let controls = false;
export let audio = false;
export let progress = false;
export let options = {};
/* vimeo options https://www.npmjs.com/package/@vimeo/player#embed-options */
const vimeoOptions = {
id: id,
width: 640,
background: true,
muted: true,
autoplay: true,
...options
};
/* status */
let player;
let message = "Loading...";
let isLoaded = false;
let isMuted = options.muted || true;
let isPlaying = options.autoplay || true;
let videoTime = 0;
let videoProgress = 0;
let videoDuration = 0;
/* mount & destroy */
function init(element) {
player = new Player(element, vimeoOptions);
/* events https://www.npmjs.com/package/@vimeo/player#events */
player.on("loaded", () => {
isLoaded = true;
});
player.on("playing", () => {
isPlaying = true;
});
player.on("pause", () => {
isPlaying = false;
});
if (progress) {
player.on("timeupdate", data => {
videoProgress = data.percent;
videoTime = data.seconds;
videoDuration = data.duration;
});
}
player.on("volumechange", ({volume}) => {
player.getMuted().then(function(muted) {
isMuted = muted;
}).catch(errorHandler);
console.log('volumechange', isMuted);
});
allPlayers.add(player);
}
onDestroy(() => {
player.pause();
let empty = function() {};
player.off("loaded", empty);
player.off("playing", empty);
player.off("pause", empty);
player.off("timeupdate", empty);
allPlayers.delete(player);
player.destroy();
player = undefined;
});
/* controls https://www.npmjs.com/package/@vimeo/player#methods */
function mute(){
player.setMuted(true);
}
function unMute(){
allPlayers.forEach(pl => {
if (pl !== player) pl.setMuted(true);
});
player.setMuted(false);
}
function play() {
player
.play()
.then(function() {
console.log("Play");
})
.catch(function(error) {
switch (error.name) {
case "PasswordError":
console.warn("Video is password protected");
break;
case "PrivacyError":
console.warn("Video is private");
break;
default:
errorHandler(error);
break;
}
});
}
function pause() {
player.pause();
}
function seek(event) {
let percent = event.detail;
let seekto = percent * videoDuration;
player
.setCurrentTime(seekto)
.then(function(seconds) {
videoTime = seconds;
videoProgress = percent;
})
.catch(function(error) {
switch (error.name) {
case "RangeError":
console.error("Seek value was out of bounds");
break;
default:
errorHandler(error);
break;
}
});
}
</script>
<div use:init></div>
{#if isLoaded}
{#if controls}
<div>
{#if isPlaying}
<button on:click={pause}>Pause</button>
{:else}
<button on:click={play}>Play</button>
{/if}
</div>
{/if}
{#if audio}
<div>
{#if isMuted}
<button on:click={unMute}>Unmute</button>
{:else}
<button on:click={mute}>Mute</button>
{/if}
</div>
{/if}
{#if progress}
<div>
{renderTime(videoTime)} / {renderTime(videoDuration)} ({renderPercent(videoProgress)}%)
</div>
<div>
<Progress {videoProgress} on:seek={seek} />
</div>
{/if}
{:else}
<div>{message}</div>
{/if}
<script>
import { createEventDispatcher } from "svelte";
export let videoProgress;
const dispatch = createEventDispatcher();
let barWidth;
function seek(event) {
let seekto = event.offsetX / barWidth;
console.log(seekto);
dispatch("seek", seekto);
}
</script>
<div class="bar" on:click={seek} bind:offsetWidth={barWidth}>
<div class="progress" style="width:{videoProgress*100}%;"></div>
</div>
<style>
.bar {
background-color: #eee;
cursor: pointer;
}
.progress {
height: 1rem;
background-color: #000;
transition: width 200ms ease;
}
</style>
@moritzebeling
Copy link
Author

moritzebeling commented Dec 31, 2021

NPM Vimeo
https://www.npmjs.com/package/@vimeo/player

Codesandbox Example
https://codesandbox.io/s/gracious-parm-l92qs?file=/Player.svelte

Usage

<script>
  import Player from './Player.svelte';
</script>

<Player id="{'59777392'}" audio={true} controls={true} progress={true} options={{}} />

Aim

  • Videos should be autoplayed, muted and without controls (background mode)
  • Videos should have option to play or pause them
  • Videos should have option to seek a playback position
  • Videos should have option to unmute them, but must mute all other unmuted videos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment