diff --git a/src/app/vendor/videojsplugins.js b/src/app/vendor/videojsplugins.js
index 65a353ab59..26cdde6e5e 100644
--- a/src/app/vendor/videojsplugins.js
+++ b/src/app/vendor/videojsplugins.js
@@ -4,8 +4,6 @@ var Button = videojs.getComponent('Button');
var MenuButton = videojs.getComponent('MenuButton');
var SubtitlesButton = videojs.getComponent('SubtitlesButton');
var MenuItem = videojs.getComponent('MenuItem');
-var srt2vtt = require('srt-to-vtt');
-var fs = require('fs');
// var BiggerSubtitleButton = videojs.extend(Button, {
// /** @constructor */
@@ -82,94 +80,128 @@ class CustomTrackMenuItem extends MenuItem {
options = options || {};
options.label = i18n.__('Custom...');
super(player, options);
-
- // let that = this;
- // this.fileInput_ = $('');
- // $(this.el()).append(this.fileInput_);
- // this.fileInput_.on('change', function () {
- // that.player_.play();
- // if (this.value === '') {
- // return;
- // }
- // that.loadSubtitle(this.value);
- // this.value = null; //reset
- // });
}
/**
* Seek with the button's configured offset
*/
handleClick() {
- console.log('click!');
this.player_.pause();
- // this.fileInput_.trigger('click'); // redirect to fileInput click
var input = document.createElement('input');
input.type = 'file';
input.accept = '.vtt, .srt, .ssa, .ass, .txt';
input.onchange = e => {
- var file = e.target.files[0];
- console.log(file);
- this.loadSubtitle(file);
+ let file = e.target.files[0];
+ if (file.type === 'text/vtt') {
+ this.loadSubtitle(file);
+ return;
+ }
+ this.convert2vtt(file).then((file) => {
+ this.loadSubtitle(file);
+ });
};
input.click();
- // const now = this.player_.currentTime();
- //
- // if (this.options_.direction === 'forward') {
- // this.player_.currentTime(now + this.options_.seconds);
- // } else if (this.options_.direction === 'back') {
- // this.player_.currentTime(now - this.options_.seconds);
- // }
+ }
+
+ // TODO: find some npm module, which works with strings
+ srt2webvtt(data) {
+ // remove dos newlines
+ var srt = data.replace(/\r+/g, '');
+ // trim white space start and end
+ srt = srt.replace(/^\s+|\s+$/g, '');
+
+ // get cues
+ var cuelist = srt.split('\n\n');
+ var result = '';
+
+ if (cuelist.length > 0) {
+ result += 'WEBVTT\n\n';
+ for (var i = 0; i < cuelist.length; i=i+1) {
+ result += this.convertSrtCue(cuelist[i]);
+ }
+ }
+
+ return result;
+ }
+
+ convertSrtCue(caption) {
+ // remove all html tags for security reasons
+ //srt = srt.replace(/<[a-zA-Z\/][^>]*>/g, '');
+
+ var cue = '';
+ var s = caption.split(/\n/);
+
+ // concatenate muilt-line string separated in array into one
+ while (s.length > 3) {
+ for (var i = 3; i < s.length; i++) {
+ s[2] += '\n' + s[i];
+ }
+ s.splice(3, s.length - 3);
+ }
+
+ var line = 0;
+
+ // detect identifier
+ if (!s[0].match(/\d+:\d+:\d+/) && s[1].match(/\d+:\d+:\d+/)) {
+ cue += s[0].match(/\w+/) + '\n';
+ line += 1;
+ }
+
+ // get time strings
+ if (s[line].match(/\d+:\d+:\d+/)) {
+ // convert time string
+ var m = s[1].match(/(\d+):(\d+):(\d+)(?:,(\d+))?\s*--?>\s*(\d+):(\d+):(\d+)(?:,(\d+))?/);
+ if (m) {
+ cue += m[1]+':'+m[2]+':'+m[3]+'.'+m[4]+' --> '
+ +m[5]+':'+m[6]+':'+m[7]+'.'+m[8]+'\n';
+ line += 1;
+ } else {
+ // Unrecognized timestring
+ return '';
+ }
+ } else {
+ // file format error or comment lines
+ return '';
+ }
+
+ // get cue text
+ if (s[line]) {
+ cue += s[line] + '\n\n';
+ }
+
+ return cue;
+ }
+
+ async convert2vtt(file) {
+ let text = await file.text();
+
+ let vtt = this.srt2webvtt(text);
+ return new File(
+ [vtt],
+ '/temp.vtt',
+ {type: 'text/vtt'}
+ );
}
loadSubtitle(file) {
- //clean tracks
- var tracks = this.player_.textTracks() || [];
- for (var i = 0; i < tracks.length; ++i) {
- if (tracks[i].id_.indexOf('vjs_subtitles_00') !== -1) {
- $(tracks[i].el()).remove();
- tracks.splice(i, 1);
- break;
+ // on call removeRemoteTextTrack this.player_ set to null (???)
+ let tracks = videojs('video_player').remoteTextTracks() || [];
+ for (let i = tracks.length - 1; i >= 0; --i) {
+ if (tracks[i].language === '00') {
+ videojs('video_player').removeRemoteTextTrack(tracks[i]);
}
}
- window['x'] = file;
-
- file.text().then((x) => fs.writeFileSync(App.settings.tmpLocation + '/temp.srt', x)).then((stream) => {
- fs.createReadStream(App.settings.tmpLocation + '/temp.srt')
- .pipe(srt2vtt())
- .pipe(fs.createWriteStream(App.settings.tmpLocation + '/temp.vtt'));
- }).then(() => {
- let file = new Blob(new Uint8Array(fs.readFileSync(App.settings.tmpLocation + '/temp.vtt')), {type: 'text/vtt'});
- console.log(file);
- const track = this.player_.addRemoteTextTrack({
- kind: 'subtitles',
- language: '01',
- label: 'str2vtt',
- mode: 'showing',
- src: URL.createObjectURL(file)
- }, false);
- console.log(track);
- });
- //return;
-
- //file.stream().pipe(srt2vtt()).toBlob()
-
- const track = this.player_.addRemoteTextTrack({
+ const track = videojs('video_player').addRemoteTextTrack({
kind: 'subtitles',
language: '00',
label: 'original',
mode: 'showing',
src: URL.createObjectURL(file)
}, false);
- // const track = this.player_.addTextTrack('subtitles', 'Loaded', App.Settings.language, {
- // src: filePath
- // });
- console.log(track);
- //App.vent.trigger('customSubtitles:added', filePath);
- //vjs.TextTrackMenuItem.prototype.onClick.call(this); // redirect to TextTrackMenuItem.onClick
}
}
@@ -242,90 +274,3 @@ class CustomButton extends MenuButton {
}
videojs.registerComponent('customButton', CustomButton);
-
-// // Custom Subtitles Button/Menu
-// videojs.registerPlugin('customSubtitles', function () {
-//
-// // Find subtitlesButton
-// var subtitlesButton;
-// this.controlBar.children().forEach(function (el) {
-// if (el.name() === 'subtitlesButton') {
-// subtitlesButton = el;
-// }
-// });
-//
-// var CustomTrackMenuItem = vjs.TextTrackMenuItem.extend({
-//
-// /*@ Constructor */
-// init: function (player, options) {
-// options = options || {};
-// // fake 'empty' track
-// options['track'] = {
-// kind: function () {
-// return 'subtitles';
-// },
-// player: player,
-// label: function () {
-// return i18n.__('Custom...');
-// },
-// dflt: function () {
-// return false;
-// },
-// mode: function () {
-// return false;
-// }
-// };
-//
-// this.fileInput_ = $('');
-// $(this.el()).append(this.fileInput_);
-//
-// var that = this;
-//
-// App.vent.on('videojs:drop_sub', function () {
-// var subname = Settings.droppedSub;
-// var subpath = path.join(App.settings.tmpLocation, subname);
-// win.info('Subtitles dropped:', subname);
-// that.loadSubtitle(subpath);
-// });
-//
-// this.fileInput_.on('change', function () {
-// that.player_.play();
-// if (this.value === '') {
-// return;
-// }
-// that.loadSubtitle(this.value);
-// this.value = null; //reset
-// });
-//
-// vjs.TextTrackMenuItem.call(this, player, options);
-// }
-// });
-//
-// CustomTrackMenuItem.prototype.onClick = function () {
-// this.player_.pause();
-// this.fileInput_.trigger('click'); // redirect to fileInput click
-// };
-//
-// CustomTrackMenuItem.prototype.loadSubtitle = function (filePath) {
-//
-// //clean tracks
-// var tracks = this.player_.textTracks() || [];
-// for (var i = 0; i < tracks.length; ++i) {
-// if (tracks[i].id_.indexOf('vjs_subtitles_00') !== -1) {
-// $(tracks[i].el()).remove();
-// tracks.splice(i, 1);
-// break;
-// }
-// }
-//
-// this.track = this.player_.addTextTrack('subtitles', i18n.__('Custom...'), '00', {
-// src: filePath
-// });
-// App.vent.trigger('customSubtitles:added', filePath);
-// vjs.TextTrackMenuItem.prototype.onClick.call(this); // redirect to TextTrackMenuItem.onClick
-// };
-//
-// subtitlesButton.menu.addItem(new CustomTrackMenuItem(this));
-// subtitlesButton.show(); // Always show subtitles button
-//
-// });