Skip to content

Commit

Permalink
feat(embed-process.ts): use plyr as youtube player
Browse files Browse the repository at this point in the history
  • Loading branch information
aidenlx committed Apr 14, 2021
1 parent 9da841d commit 09d1993
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 56 deletions.
127 changes: 75 additions & 52 deletions src/modules/embed-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HTMLMediaEl_TF, TimeSpan, isHTMLMediaEl_TF } from "./MFParse";
import { assertNever } from "assert-never";
import { stringify, parse } from "query-string";
import { parseLinktext } from "obsidian";
import Plyr from "plyr"

enum Host {
YouTube,
Expand Down Expand Up @@ -66,74 +67,96 @@ export function getEmbedInfo(src: URL): videoInfo | null {
}
}

export function getEmbedFrom(url:URL): HTMLIFrameElement | null {
export function getEmbedFrom(url:URL): HTMLDivElement | null {
let info = getEmbedInfo(url);
if (!info) return null;

const iframe = createEl("iframe", {
attr: {
class: "external-video",
src: info.iframe.toString(),
scrolling: "no",
border: "0",
frameborder: "no",
framespacing: "0",
allowfullscreen: false,
sandbox: "allow-forms allow-presentation allow-same-origin allow-scripts allow-modals"
},
});

const container = createDiv(undefined, (el) => el.appendChild(iframe));

switch (info.host) {
case Host.YouTube:
case Host.Bilibili:
return createEl("iframe", {
attr: {
class: "external-video",
src: info.iframe.toString(),
scrolling: "no",
border: "0",
frameborder: "no",
framespacing: "0",
allowfullscreen: false,
sandbox: "allow-forms allow-presentation allow-same-origin allow-scripts allow-modals"
},
});
case Host.YouTube: {
container.addClass("plyr__video-embed");
new Plyr(container, {
fullscreen: { enabled: false },
});
return container;
}
case Host.Bilibili: {
container.addClass("bili-embed");
return container;
}
default:
assertNever(info.host)
assertNever(info.host);
}

}

export function injectTimestamp(player: HTMLMediaElement, timeSpan: TimeSpan) {
(player as HTMLMediaEl_TF).timeSpan = timeSpan;
export interface Plyr_TF extends Plyr {
timeSpan: TimeSpan;
}

type Player_TF = HTMLMediaEl_TF | Plyr_TF;
type Player = HTMLMediaElement | Plyr;

export function injectTimestamp(player: Player, timeSpan: TimeSpan) {
(<Player_TF>player).timeSpan = timeSpan;

// inject media fragment into player's src
const { path, subpath: hash } = parseLinktext(player.src);
let hashObj = parse(hash);
hashObj.t = timeSpan.raw;
player.src = path + "#" + stringify(hashObj);
if (player instanceof HTMLMediaElement){
const { path, subpath: hash } = parseLinktext(player.src);
let hashObj = parse(hash);
hashObj.t = timeSpan.raw;
player.src = path + "#" + stringify(hashObj);
} else {
if (player.isEmbed){
// todo
} else throw new Error("Plyr for native video not implemented");

}

// inject event handler to restrict play range
player.onplaying = (e) => {
const player = e.target as HTMLMediaElement;
if (isHTMLMediaEl_TF(player)) {
const {
timeSpan: { start, end },
currentTime,
} = player;
if (currentTime > end || currentTime < start) {
player.currentTime = start;
}
} else {
console.error(player);
throw new Error("missing timeSpan in HTMLMediaEl_TF");
const onplaying = (e: Event) => {
const player = e.target as Player_TF;
const {
timeSpan: { start, end },
currentTime,
} = player;
if (currentTime > end || currentTime < start) {
player.currentTime = start;
}
};
player.ontimeupdate = (e) => {
const player = e.target as HTMLMediaElement;
if (isHTMLMediaEl_TF(player)) {
const {
timeSpan: { start, end },
currentTime,
} = player;
// check if is HTMLMediaEl_TF object
if (currentTime > end) {
if (!player.loop) {
player.pause();
} else {
player.currentTime = start;
}
const ontimeupdate = (e: Event) => {
const player = e.target as Player_TF;
const {
timeSpan: { start, end },
currentTime,
} = player;
if (currentTime > end) {
if (!player.loop) {
player.pause();
} else {
player.currentTime = start;
}
} else {
console.error(player);
throw new Error("missing timeSpan in HTMLMediaEl_TF");
}
};
if (player instanceof HTMLMediaElement) {
player.onplaying = onplaying;
player.ontimeupdate = ontimeupdate;
} else {
player.on("playing", onplaying);
player.on("timeupdate", ontimeupdate);
}
}
7 changes: 3 additions & 4 deletions src/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import {
MarkdownPostProcessorContext,
parseLinktext,
} from "obsidian";
import { parseTF, bindTimeSpan, HTMLMediaEl_TF } from "./modules/MFParse";
import { parseTF, bindTimeSpan } from "./modules/MFParse";
import { injectTimestamp, getEmbedFrom } from "./modules/embed-process";
// import Plyr from "plyr"

/**
* HTMLMediaElement with temporal fragments
Expand Down Expand Up @@ -149,7 +148,7 @@ export function processInternalEmbeds(
const { subpath: hash } = parseLinktext(srcLinktext);
const timeSpan = parseTF(hash);

const player = m.addedNodes[0] as HTMLMediaEl_TF;
const player = m.addedNodes[0] as HTMLMediaElement;
if (timeSpan !== null) {
// import timestamps to player
injectTimestamp(player, timeSpan);
Expand Down Expand Up @@ -203,7 +202,7 @@ export function processExternalEmbeds(
}
}

let newEl: HTMLMediaElement | HTMLIFrameElement | null = null;
let newEl: HTMLMediaElement | HTMLDivElement | null = null;

if (type) {
newEl = createEl(type);
Expand Down
Loading

0 comments on commit 09d1993

Please sign in to comment.