Skip to content

Commit a42d710

Browse files
authored
Merge pull request #91 from DANS-KNAW-jp/11041-video-subtitles
Add subtitles to video previews
2 parents dcd795d + 6870e09 commit a42d710

File tree

1 file changed

+107
-1
lines changed

1 file changed

+107
-1
lines changed

previewers/betatest/js/video.js

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,111 @@ function translateBaseHtmlPage() {
99

1010
function writeContent(fileUrl, file, title, authors) {
1111
addStandardPreviewHeader(file, title, authors);
12-
$(".preview").append($("<video/>").prop("controls",true).append($('<source/>').attr("src",fileUrl)));
12+
13+
const queryParams = new URLSearchParams(window.location.search.substring(1));
14+
const id = queryParams.get("datasetid");
15+
const siteUrl = queryParams.get("siteUrl");
16+
if (!siteUrl || !id) {
17+
// fallback to simple video element in case of signed URLs
18+
$(".preview").append($("<video/>") .prop("controls", true) .append($('<source/>').attr("src", fileUrl)))
19+
return;
20+
}
21+
const versionUrl = `${siteUrl}/api/datasets/${id}/versions/`
22+
+ queryParams.get("datasetversion");
23+
const videoId =queryParams.get("fileid") * 1; // converted to number
24+
const userLanguages = [...navigator.languages];
25+
const locale = queryParams.get("locale");
26+
if (locale && !userLanguages.includes(locale)) {
27+
userLanguages.unshift(locale); // add as first element
28+
}
29+
30+
$.ajax({
31+
type: 'GET',
32+
dataType: 'json',
33+
crosssite: true,
34+
url: versionUrl,
35+
success: function(data, status) {
36+
appendVideoElements(fileUrl, videoId, data.data.files, siteUrl, userLanguages);
37+
},
38+
error: function(request, status, error) {
39+
// fallback to simple video element
40+
$(".preview").append($("<video/>") .prop("controls", true) .append($('<source/>').attr("src", fileUrl)))
41+
}
42+
});
43+
}
44+
45+
function appendVideoElements(fileUrl, videoId, files, siteUrl, userLanguages) {
46+
47+
const baseName = files // the video file name without extension
48+
.find(item => item.dataFile.id === videoId)
49+
.label.replace(/\.[a-z0-9]+$/i,'');
50+
51+
// find labels like "baseName.en.vtt", "baseName.de-CH.vtt" or "baseName.vtt"
52+
const regex = new RegExp(`${baseName}(\\.([-a-z]+))?\\.vtt$`, 'i')
53+
54+
// create a map of URLs with their (optional) language
55+
let trackUrlWithoutLang = null;
56+
const subtitles = files
57+
.filter(item => regex.test(item.label))
58+
.reduce((map, item) => {
59+
const lang = item.label.match(regex)[2];
60+
const url = `${siteUrl}/api/access/datafile/${item.dataFile.id}?gbrecs=true`
61+
map.set(url, lang);
62+
if (!lang) {
63+
trackUrlWithoutLang = url;
64+
}
65+
return map;
66+
}, new Map());
67+
68+
// sort subtitles by language value, 'de-CH' before 'de'
69+
const sortedSubtitles = new Map([...subtitles.entries()].sort((a, b) => {
70+
if (!a[1]) return 1;
71+
if (!b[1]) return -1;
72+
if (a[1].startsWith(b[1])) return -1;
73+
if (b[1].startsWith(a[1])) return 1;
74+
return a[1].localeCompare(b[1]);
75+
}));
76+
77+
// determine default track
78+
let defaultTrackUrl = null;
79+
loop: for (const lang of userLanguages) {
80+
for (const [url, trackLang] of sortedSubtitles) {
81+
if (trackLang) {
82+
if (trackLang === lang || trackLang.startsWith(lang.replace(/-.*/, ''))) {
83+
defaultTrackUrl = url;
84+
break loop;
85+
}
86+
}
87+
}
88+
}
89+
if (!defaultTrackUrl) {
90+
defaultTrackUrl = trackUrlWithoutLang;
91+
}
92+
if (!defaultTrackUrl && subtitles) {
93+
defaultTrackUrl = subtitles.keys().next().value;
94+
}
95+
96+
const videoElement = $("<video/>")
97+
.prop("controls", true)
98+
.append($('<source/>').attr("src", fileUrl));
99+
100+
sortedSubtitles.forEach((trackLang, url) => {
101+
const trackElement = $('<track/>')
102+
.attr("kind", "subtitles")
103+
.attr("src", url);
104+
if (trackLang) {
105+
trackElement
106+
.attr("label", trackLang)
107+
.attr("srclang", trackLang);
108+
} else {
109+
trackElement.attr("label", "???");
110+
}
111+
console.log("url: ", url, "defaultTrackUrl: ", defaultTrackUrl);
112+
if (url === defaultTrackUrl) {
113+
trackElement.attr("default", true);
114+
}
115+
videoElement.append(trackElement);
116+
});
117+
118+
$(".preview").append(videoElement);
13119
}

0 commit comments

Comments
 (0)