Skip to content

Commit

Permalink
Add support for \video with url instead of video id (#752)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvire authored Dec 5, 2024
1 parent bf8601c commit 4a80218
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 6 deletions.
22 changes: 16 additions & 6 deletions src/lib/components/ScriptureViewSofria.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ LOGGING:
updateSelections
} from '$lib/scripts/verseSelectUtil';
import { prepareAudioPhraseEndChars, parsePhrase } from '$lib/scripts/parsePhrase';
import { createVideoBlock, addVideoLinks } from '$lib/video';
import { createVideoBlock, addVideoLinks, createVideoBlockFromUrl } from '$lib/video';
import { loadDocSetIfNotLoaded } from '$lib/data/scripture';
import { seekToVerse, hasAudioPlayed } from '$lib/data/audio';
import {
Expand Down Expand Up @@ -2186,11 +2186,21 @@ LOGGING:
case 'usfm:zvideo': {
const id = element.atts['id'][0];
const video = config.videos.find((x) => x.id === id);
workspace.videoDiv = createVideoBlock(
document,
video,
workspace.currentVideoIndex++
);
if (video) {
workspace.videoDiv = createVideoBlock(
document,
video,
workspace.currentVideoIndex++
);
} else {
// Proskomma did replacement of slashes in id
const videoUrl = id.replace(/÷/g, '/');
workspace.videoDiv = createVideoBlockFromUrl(
document,
videoUrl,
config.mainFeatures
);
}
break;
}
case 'usfm:zaudioc': {
Expand Down
130 changes: 130 additions & 0 deletions src/lib/video/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ enum VideoType {
Vimeo = 'vimeo',
Jesus = 'jesus',
Gospel = 'gospel',
Daily = 'daily',
Other = 'other',
Mp4 = 'mp4',
Hls = 'hls'
Expand All @@ -23,6 +24,8 @@ export function getVideoType(url: string): VideoType {
type = VideoType.Jesus;
} else if (url.includes('dbt.io')) {
type = VideoType.Gospel;
} else if (url.includes('dai.ly')) {
type = VideoType.Daily;
} else if (url.toLowerCase().endsWith('.mp4')) {
type = VideoType.Mp4;
} else if (url.toLowerCase().endsWith('.m3u8')) {
Expand All @@ -33,6 +36,132 @@ export function getVideoType(url: string): VideoType {
return type;
}

function getYouTubeVideoId(url: string): string {
let id = '';

// Regular expression for YouTube URL pattern (e.g., youtube.com/watch?v=...)
let pattern = /https:\/\/(?:www\.)?youtube\.(?:\w+)\/watch\?v=([a-zA-Z0-9-_]+)(?:&.+)*/;
let match = url.match(pattern);

if (match) {
// If match is found, extract the video ID
id = match[1];
} else {
// Regular expression for shortened YouTube URL pattern (e.g., youtu.be/...)
pattern = /https:\/\/(?:www\.)?youtu\.be\/([a-zA-Z0-9-_]+)(?:&.+)*/;
match = url.match(pattern);

if (match) {
id = match[1];
}
}

return id;
}

export function getEmbeddedVideoUrl(
videoUrl: string,
autoplay: boolean,
features: { [key: string]: string }
) {
let returnUrl = videoUrl;
const type = getVideoType(videoUrl);

switch (type) {
case VideoType.YouTube:
// YouTube video
// Transform https://www.youtube.com/watch?v=abcdefghijk to https://www.youtube.com/embed/abcdefghijk
const videoId = getYouTubeVideoId(videoUrl);
if (videoId) {
returnUrl = 'https://www.youtube.com/embed/' + videoId;
let hasParams = false;

if (autoplay) {
returnUrl += '?audioplay=1';
hasParams = true;
}

if (features && features['video-youtube-related-same-channel']) {
// After Sept 2018, you will not be able to disable related videos.
// Instead, if the rel parameter is set to 0, related videos will come
// from the same channel as the video that was just played.
// https://developers.google.com/youtube/player_parameters
returnUrl += hasParams ? '&' : '?';
returnUrl += 'rel=0';
}
}
break;

case VideoType.Vimeo:
// Vimeo video
// Transform https://vimeo.com/12345678 to https://player.vimeo.com/video/12345678
let pattern = /https:\/\/(?:www\.)?vimeo\.(\w+)\/([0-9]+)/;
let match = returnUrl.match(pattern);

if (match) {
// Construct the Vimeo embed URL
returnUrl = `https://player.vimeo.com/video/${match[2]}`;

// Add autoplay parameter if autoplay is true
if (autoplay) {
returnUrl += '?autoplay=1';
}
}
break;

case VideoType.Daily:
pattern = /https?:\/\/dai\\.ly\/(.*)/;
match = returnUrl.match(pattern);

if (match) {
returnUrl = `https://www.dailymotion.com/embed/video/${match[1]}`;
}
break;

case VideoType.Jesus:
// Jesus Film Media
// Get the embed code from https://www.jesusfilm.org/watch, select video and click Share > Embed Code
// Example:
// https://api.arclight.org/videoPlayerUrl?refId=1_20917-jf6144-0-0&apiSessionId=5a1bda77c898d6.05342318&playerStyle=default&player=bc.vanilla5
if (!returnUrl.includes('playerStyle')) {
returnUrl = returnUrl + '&playerStyle=default&player=bc.vanilla5';
}
break;

case VideoType.Hls:
// Do nothing
break;
}

return returnUrl;
}

export function createVideoBlockFromUrl(
document: Document,
videoUrl: string,
features: { [key: string]: string }
): HTMLElement {
const url = getEmbeddedVideoUrl(videoUrl, false, features);

const videoBlockDiv = document.createElement('div');
videoBlockDiv.classList.add('video-block');
const videoContainerDiv = document.createElement('div');
videoContainerDiv.classList.add('video-container');
videoBlockDiv.appendChild(videoContainerDiv);

videoContainerDiv.classList.add('video-16-9');
const iframe = document.createElement('iframe');
iframe.setAttribute('width', '420');
iframe.setAttribute('src', url);
iframe.setAttribute('frameborder', '0');
iframe.setAttribute('webkitallowfullscreen', '');
iframe.setAttribute('mozallowfullscreen', '');
iframe.setAttribute('allowfullscreen', '');
videoContainerDiv.appendChild(iframe);

return videoBlockDiv;
}

export function createVideoBlock(document: Document, video: any, index: any): HTMLElement {
const type = getVideoType(video.onlineUrl);
const videoBlockDiv = document.createElement('div');
Expand All @@ -55,6 +184,7 @@ export function createVideoBlock(document: Document, video: any, index: any): HT
case VideoType.Vimeo:
case VideoType.Hls:
case VideoType.Gospel:
case VideoType.Daily:
case VideoType.Other:
videoContainerDiv.classList.add('video-' + type, 'video-16-9');
break;
Expand Down

0 comments on commit 4a80218

Please sign in to comment.