Skip to content

Commit

Permalink
Code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
aidenlx committed Apr 5, 2021
1 parent c5c202b commit 83666ef
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 141 deletions.
10 changes: 10 additions & 0 deletions src/MFDefs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* See also: https://www.w3.org/TR/media-frags/#valid-uri
*/
export default {
tFrag: /(?<start>[\w:\.]*?)(?:,(?<end>[\w:\.]+?))?$/,

npt_sec: /^\d+(?:\.\d+)?$/,
npt_mmss: /^(?<mm>[0-5]\d):(?<ss>[0-5]\d(?:\.\d+)?)$/,
npt_hhmmss: /^(?<hh>\d+):(?<mm>[0-5]\d):(?<ss>[0-5]\d(?:\.\d+)?)$/,
};
105 changes: 105 additions & 0 deletions src/MFParse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { parseUrl, parse, ParsedQuery } from "query-string";
import MFDefs from "./MFDefs";

export function parseHash(url: string): ParsedQuery | null {
const hash = parseUrl(url, { parseFragmentIdentifier: true }).fragmentIdentifier;
if (hash) {
return parse(hash);
} else {
return null;
}
}
export function parseTF(hash: string | undefined): TimeSpan | null {
if (hash) {
const params = parse(hash);
const paramT = params.t;
let match;
if (paramT && typeof paramT === "string" && (match = MFDefs.tFrag.exec(paramT)) !== null) {
if (!match.groups)
throw new Error("tFragRegex match error");
const { start, end } = match.groups;
const timeSpan = getTimeSpan(start, end);
if (timeSpan)
return { ...timeSpan, raw: paramT };
else
return null;
}
}
return null;
}
export function bindTimeSpan(timeSpan: TimeSpan, player: HTMLMediaElement) {
if (timeSpan.end !== Infinity) {
player.ontimeupdate = function (e) {
const p = this as HTMLMediaElement;
if (p.currentTime >= timeSpan.end) {
p.pause();
p.ontimeupdate = null;
}
};
}
player.currentTime = timeSpan.start;
if (player.paused)
player.play();
}
interface TimeSpan {
end: number;
start: number;
/**
* raw value of key "t" in #t={value}
*/
raw: string;
}
function getTimeSpan(
start: string | undefined,
end: string | undefined
): Omit<TimeSpan, "raw"> | null {
// start may be an empty string
const startRaw = start ? start : null;
const endRaw = end ?? null;

let startTime, endTime;
if (startRaw && endRaw) {
startTime = convertTime(startRaw);
endTime = convertTime(endRaw);
} else if (startRaw) {
startTime = convertTime(startRaw);
endTime = Infinity;
} else if (endRaw) {
startTime = 0;
endTime = convertTime(endRaw);
} else {
throw new Error("Missing startTime and endTime");
}

if (startTime === null || endTime === null) {
return null;
} else {
return { start: startTime, end: endTime };
}
}
function convertTime(input: string): number | null {
const npttimedef = /^(?:npt:)?([\d\.:]+)$/;
if (npttimedef.test(input)) {
const rawTime = (input.match(npttimedef) as RegExpMatchArray)[1];

let match;

if ((match = MFDefs.npt_sec.exec(rawTime)) !== null) {
return +match[0];
} else if ((match = MFDefs.npt_mmss.exec(rawTime)) !== null) {
if (!match.groups)
throw new Error("npt_mmss match error");
const { mm, ss } = match.groups;
return +mm * 60 + +ss;
} else if ((match = MFDefs.npt_hhmmss.exec(rawTime)) !== null) {
if (!match.groups)
throw new Error("npt_hhmmss match error");
const { hh, mm, ss } = match.groups;
return +hh * 60 + +mm * 60 + +ss;
} else
return null;
} else {
console.error("fail to parse npt: " + input);
return null;
}
}
166 changes: 25 additions & 141 deletions src/processor.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import MediaExtended from "main";
import { FileView, MarkdownPostProcessorContext, WorkspaceLeaf } from "obsidian";
import { parseUrl, parse, ParsedQuery } from "query-string";
import { parseUrl } from "query-string";
import { parseTF, bindTimeSpan, parseHash } from "./MFParse";
// import Plyr from "plyr"

const parseOpt = {parseFragmentIdentifier: true};

/**
* See also: https://www.w3.org/TR/media-frags/#valid-uri
*/
const tFragRegex = /(?<start>[\w:\.]*?)(?:,(?<end>[\w:\.]+?))?$/;

/**
* HTMLMediaElement with temporal fragments
*/
Expand All @@ -18,136 +12,6 @@ interface HME_TF extends HTMLMediaElement{
end:number;
}

function onplaying(this: any, event: Event) {
const player = this as HME_TF;
const { start,end, currentTime } = player;
// check if is HME_TF object
if (start||end){
if (currentTime>end||currentTime<start){
player.currentTime=start;
}
}
}

function ontimeupdate(this: any, event: Event) {
const player = this as HME_TF;
const { start,end, currentTime } = player;
// check if is HME_TF object
if ((start || end) && currentTime > end) {
if (!player.loop){
player.pause();
} else {
player.currentTime = start;
}
}
}

function parseHash(url: string): ParsedQuery|null{
const hash = parseUrl(url,parseOpt).fragmentIdentifier
if(hash){
return parse(hash);
} else {
return null;
}
}

function parseTF(hash: string | undefined): TimeSpan | null {
if (hash) {
const params = parse(hash);
const paramT = params.t;
let match;
if (paramT && typeof paramT === "string" && (match = tFragRegex.exec(paramT))!==null) {
if (!match.groups) throw new Error("tFragRegex match error");
const { start, end } = match.groups;
const timeSpan = getTimeSpan(start, end);
if (timeSpan) return { ...timeSpan, raw: paramT };
else return null;
}
}
return null;
}

function bindTimeSpan(timeSpan: TimeSpan, player: HTMLMediaElement) {
if (timeSpan.end !== Infinity) {
player.ontimeupdate = function (e) {
const p = this as HTMLMediaElement;
if (p.currentTime >= timeSpan.end) {
p.pause();
p.ontimeupdate = null;
}
};
}
player.currentTime = timeSpan.start;
if (player.paused)
player.play();
}

interface TimeSpan {
end: number;
start: number;
/**
* raw value of key "t" in #t={value}
*/
raw: string;
}

function getTimeSpan(
start: string | undefined,
end: string | undefined
): Omit<TimeSpan,"raw"> | null {
// start may be an empty string
const startRaw = start ? start : null;
const endRaw = end ?? null;

let startTime, endTime;
if (startRaw && endRaw) {
startTime = convertTime(startRaw);
endTime = convertTime(endRaw);
} else if (startRaw) {
startTime = convertTime(startRaw);
endTime = Infinity;
} else if (endRaw) {
startTime = 0;
endTime = convertTime(endRaw);
} else {
throw new Error("Missing startTime and endTime");
}

if (startTime===null || endTime ===null) {
return null
} else {
return { start: startTime, end: endTime };
}
}

function convertTime(input: string): number | null {
const npttimedef = /^(?:npt:)?([\d\.:]+)$/;
if (npttimedef.test(input)) {
const rawTime = (input.match(npttimedef) as RegExpMatchArray)[1];

const npt_sec = /^\d+(?:\.\d+)?$/;
const npt_mmss = /^(?<mm>[0-5]\d):(?<ss>[0-5]\d(?:\.\d+)?)$/;
const npt_hhmmss = /^(?<hh>\d+):(?<mm>[0-5]\d):(?<ss>[0-5]\d(?:\.\d+)?)$/;

let match;

if ((match = npt_sec.exec(rawTime)) !== null) {
return +match[0];
} else if ((match = npt_mmss.exec(rawTime)) !== null) {
if (!match.groups) throw new Error("npt_mmss match error");
const { mm, ss } = match.groups;
return +mm * 60 + +ss;
} else if ((match = npt_hhmmss.exec(rawTime)) !== null) {
if (!match.groups) throw new Error("npt_hhmmss match error");
const { hh, mm, ss } = match.groups;
return +hh * 60 + +mm * 60 + +ss;
} else return null;
} else {
console.error("fail to parse npt: " + input);
return null;
}
}

export function processInternalLinks(this: MediaExtended, el:HTMLElement, ctx:MarkdownPostProcessorContext) {

const plugin = this;
Expand Down Expand Up @@ -267,7 +131,7 @@ export function processInternalEmbeds(/* this: MediaExtended, */el:HTMLElement,
console.error(m.target)
throw new TypeError("src not found on container <span>")
}
const hash = parseUrl(url,parseOpt).fragmentIdentifier
const hash = parseUrl(url,{parseFragmentIdentifier: true}).fragmentIdentifier
const timeSpan = parseTF(hash);
const player = m.addedNodes[0] as HME_TF;
if (timeSpan!==null) {
Expand All @@ -282,8 +146,28 @@ export function processInternalEmbeds(/* this: MediaExtended, */el:HTMLElement,
if (parseHash(url)?.loop===null){
player.loop=true;
}
player.onplaying = onplaying;
player.ontimeupdate = ontimeupdate;
player.onplaying = e => {
const player = e.target as HME_TF;
const { start,end, currentTime } = player;
// check if is HME_TF object
if (start||end){
if (currentTime>end||currentTime<start){
player.currentTime=start;
}
}
};
player.ontimeupdate = e => {
const player = e.target as HME_TF;
const { start,end, currentTime } = player;
// check if is HME_TF object
if ((start || end) && currentTime > end) {
if (!player.loop){
player.pause();
} else {
player.currentTime = start;
}
}
};
}
};

Expand Down

0 comments on commit 83666ef

Please sign in to comment.