1 /* This widget displays annotations as a transcript */ |
1 /* This widget displays annotations as a transcript */ |
|
2 import Mustache from "mustache"; |
|
3 import jQuery from "jquery"; |
2 |
4 |
3 IriSP.Widgets.Transcript = function(player, config) { |
5 import transcriptStyles from "./Transcript.module.css"; |
4 IriSP.Widgets.Widget.call(this, player, config); |
|
5 } |
|
6 |
6 |
7 IriSP.Widgets.Transcript.prototype = new IriSP.Widgets.Widget(); |
7 const Transcript = function (ns) { |
|
8 return class extends ns.Widgets.Widget { |
|
9 constructor(player, config) { |
|
10 super(player, config); |
|
11 } |
8 |
12 |
9 IriSP.Widgets.Transcript.prototype.defaults = { |
13 static defaults = { |
10 annotation_type: "Caption", |
14 annotation_type: "Caption", |
11 use_vtt_track: false |
15 use_vtt_track: false, |
12 } |
16 }; |
13 |
17 |
14 IriSP.Widgets.Transcript.prototype.template = '<div class="Ldt-TranscriptWidget"></div>'; |
18 static template = '<div class="Ldt-TranscriptWidget"></div>'; |
15 |
19 |
16 IriSP.Widgets.Transcript.prototype.annotationTemplate = '<span data-begin="{{ begin }}" data-end="{{ end }}" data-id="{{ id }}" class="Ldt-Transcript-Annotation">{{ content }}</span> '; |
20 static annotationTemplate = |
|
21 '<span data-begin="{{ begin }}" data-end="{{ end }}" data-id="{{ id }}" class="Ldt-Transcript-Annotation">{{ content }}</span> '; |
17 |
22 |
18 IriSP.Widgets.Transcript.prototype.draw = function() { |
23 draw() { |
19 var _annotations = this.getWidgetAnnotations(); |
24 var _annotations = this.getWidgetAnnotations(); |
20 var _this = this; |
25 var _this = this; |
21 var content; |
26 var content; |
22 |
27 |
23 _this.renderTemplate(); |
28 _this.renderTemplate(); |
24 content = _this.$.find('.Ldt-TranscriptWidget'); |
29 content = _this.$.find(".Ldt-TranscriptWidget"); |
25 |
30 |
26 if (_this.use_vtt_track) { |
31 if (_this.use_vtt_track) { |
27 // Use webvtt track. It will only work with native video player. |
32 // Use webvtt track. It will only work with native video player. |
28 var widgets = _this.player.widgets.filter(function (w) { return w.type == "HtmlPlayer"; }); |
33 var widgets = _this.player.widgets.filter(function (w) { |
|
34 return w.type == "HtmlPlayer"; |
|
35 }); |
29 if (widgets) { |
36 if (widgets) { |
30 var v = widgets[0].$.find("video")[0]; |
37 var v = widgets[0].$.find("video")[0]; |
31 // FIXME: allow to specify the used track |
38 // FIXME: allow to specify the used track |
32 v.addEventListener("loadedmetadata", function () { |
39 v.addEventListener("loadedmetadata", function () { |
33 var track = v.textTracks[0]; |
40 var track = v.textTracks[0]; |
34 var cues = track.cues; |
41 var cues = track.cues; |
35 var i = 1; |
42 var i = 1; |
36 Array.prototype.forEach.apply(cues, [ function(_c) { |
43 Array.prototype.forEach.apply(cues, [ |
37 _c.id = "cue" + i; |
44 function (_c) { |
38 var _html = Mustache.to_html(_this.annotationTemplate, { |
45 _c.id = "cue" + i; |
39 id : _c.id, |
46 var _html = Mustache.render(_this.annotationTemplate, { |
40 content : _c.text, |
47 id: _c.id, |
41 begin : 1000 * _c.startTime, |
48 content: _c.text, |
42 end : 1000 * _c.endTime |
49 begin: 1000 * _c.startTime, |
43 }); |
50 end: 1000 * _c.endTime, |
44 i += 1; |
|
45 var _el = IriSP.jQuery(_html); |
|
46 content.append(_el); |
|
47 } ]); |
|
48 track.addEventListener("cuechange", function () { |
|
49 var acues = track.activeCues; |
|
50 if (acues.length > 0) { |
|
51 // Update attributes for active cues |
|
52 _this.$.find(".Ldt-Transcript-Annotation.active").removeClass("active"); |
|
53 Array.prototype.forEach.apply(acues, [ function(_c) { |
|
54 _this.$.find("#" + _c.id).addClass("active"); |
|
55 } ]); |
|
56 } |
|
57 }, false); |
|
58 content.on("click", ".Ldt-Transcript-Annotation", function () { |
|
59 _this.media.setCurrentTime(this.dataset.begin); |
|
60 }); |
51 }); |
|
52 i += 1; |
|
53 var _el = jQuery(_html); |
|
54 content.append(_el); |
|
55 }, |
|
56 ]); |
|
57 track.addEventListener( |
|
58 "cuechange", |
|
59 function () { |
|
60 var acues = track.activeCues; |
|
61 if (acues.length > 0) { |
|
62 // Update attributes for active cues |
|
63 _this.$.find(".Ldt-Transcript-Annotation.active").removeClass( |
|
64 "active" |
|
65 ); |
|
66 Array.prototype.forEach.apply(acues, [ |
|
67 function (_c) { |
|
68 _this.$.find("#" + _c.id).addClass("active"); |
|
69 }, |
|
70 ]); |
|
71 } |
|
72 }, |
|
73 false |
|
74 ); |
|
75 content.on("click", ".Ldt-Transcript-Annotation", function () { |
|
76 _this.media.setCurrentTime(this.dataset.begin); |
61 }); |
77 }); |
|
78 }); |
62 } else { |
79 } else { |
63 console.log("cannot find a video object"); |
80 console.log("cannot find a video object"); |
64 } |
81 } |
65 } else { |
82 } else { |
66 // Populate with annotation data |
83 // Populate with annotation data |
67 _annotations.forEach(function(_a) { |
84 _annotations.forEach(function (_a) { |
68 var _data = { |
85 var _data = { |
69 id : _a.id, |
86 id: _a.id, |
70 content : IriSP.textFieldHtml(_a.title), |
87 content: ns.textFieldHtml(_a.title), |
71 begin : _a.begin.toString(), |
88 begin: _a.begin.toString(), |
72 end : _a.end.toString() |
89 end: _a.end.toString(), |
73 }; |
90 }; |
74 var _html = Mustache.to_html(_this.annotationTemplate, _data); |
91 var _html = Mustache.render(_this.annotationTemplate, _data); |
75 var _el = IriSP.jQuery(_html); |
92 var _el = jQuery(_html); |
76 content.append(_el); |
93 content.append(_el); |
77 }); |
94 }); |
78 }; |
95 } |
|
96 } |
|
97 }; |
79 }; |
98 }; |
|
99 |
|
100 export { Transcript, transcriptStyles }; |