gyorgy@0: (function($) { gyorgy@0: gyorgy@0: // add extra default options gyorgy@0: $.extend(mejs.MepDefaults, { gyorgy@0: // this will automatically turn on a gyorgy@0: startLanguage: '', gyorgy@0: // a list of languages to auto-translate via Google gyorgy@0: translations: [], gyorgy@0: // a dropdownlist of automatic translations gyorgy@0: translationSelector: false, gyorgy@0: // key for tranlsations gyorgy@0: googleApiKey: '' gyorgy@0: }); gyorgy@0: gyorgy@0: $.extend(MediaElementPlayer.prototype, { gyorgy@0: gyorgy@0: buildtracks: function(player, controls, layers, media) { gyorgy@0: if (!player.isVideo) gyorgy@0: return; gyorgy@0: gyorgy@0: if (player.tracks.length == 0) gyorgy@0: return; gyorgy@0: gyorgy@0: var i, options = ''; gyorgy@0: gyorgy@0: player.chapters = gyorgy@0: $('
') gyorgy@0: .prependTo(layers).hide(); gyorgy@0: player.captions = gyorgy@0: $('
') gyorgy@0: .prependTo(layers).hide(); gyorgy@0: player.captionsText = player.captions.find('.mejs-captions-text'); gyorgy@0: player.captionsButton = gyorgy@0: $('
'+ gyorgy@0: ''+ gyorgy@0: '
'+ gyorgy@0: ''+ gyorgy@0: '
'+ gyorgy@0: '
') gyorgy@0: .appendTo(controls) gyorgy@0: gyorgy@0: // hover gyorgy@0: .hover(function() { gyorgy@0: $(this).find('.mejs-captions-selector').css('visibility','visible'); gyorgy@0: }, function() { gyorgy@0: $(this).find('.mejs-captions-selector').css('visibility','hidden'); gyorgy@0: }) gyorgy@0: gyorgy@0: // handle clicks to the language radio buttons gyorgy@0: .delegate('input[type=radio]','click',function() { gyorgy@0: lang = this.value; gyorgy@0: gyorgy@0: if (lang == 'none') { gyorgy@0: player.selectedTrack = null; gyorgy@0: } else { gyorgy@0: for (i=0; i 0 && player.options.translations.length > 0) { gyorgy@0: for (i=0; i' + mejs.language.codes[i] + ''; gyorgy@0: } gyorgy@0: player.container.find('.mejs-captions-selector ul').before($( gyorgy@0: '' gyorgy@0: )); gyorgy@0: // add clicks gyorgy@0: player.container.find('.mejs-captions-translations').change(function() { gyorgy@0: var gyorgy@0: option = $(this); gyorgy@0: lang = option.val(); gyorgy@0: // add this language to the tracks list gyorgy@0: if (lang != '') { gyorgy@0: player.tracks.push({ gyorgy@0: srclang: lang, gyorgy@0: src: null, gyorgy@0: entries: [], gyorgy@0: isLoaded: false, gyorgy@0: isTranslation: true gyorgy@0: }); gyorgy@0: gyorgy@0: if (!player.isLoadingTrack) { gyorgy@0: player.trackToLoad--; gyorgy@0: player.addTrackButton(lang,true); gyorgy@0: player.options.startLanguage = lang; gyorgy@0: player.loadNextTrack(); gyorgy@0: } gyorgy@0: } gyorgy@0: }); gyorgy@0: } gyorgy@0: gyorgy@0: }, gyorgy@0: gyorgy@0: loadNextTrack: function() { gyorgy@0: var t = this; gyorgy@0: gyorgy@0: t.trackToLoad++; gyorgy@0: if (t.trackToLoad < t.tracks.length) { gyorgy@0: t.isLoadingTrack = true; gyorgy@0: t.loadTrack(t.trackToLoad); gyorgy@0: } else { gyorgy@0: // add done? gyorgy@0: t.isLoadingTrack = false; gyorgy@0: } gyorgy@0: }, gyorgy@0: gyorgy@0: loadTrack: function(index){ gyorgy@0: var gyorgy@0: t = this, gyorgy@0: track = t.tracks[index], gyorgy@0: after = function() { gyorgy@0: gyorgy@0: track.isLoaded = true; gyorgy@0: gyorgy@0: // create button gyorgy@0: //t.addTrackButton(track.srclang); gyorgy@0: t.enableTrackButton(track.srclang); gyorgy@0: gyorgy@0: t.loadNextTrack(); gyorgy@0: gyorgy@0: }; gyorgy@0: gyorgy@0: if (track.isTranslation) { gyorgy@0: gyorgy@0: // translate the first track gyorgy@0: mejs.TrackFormatParser.translateTrackText(t.tracks[0].entries, t.tracks[0].srclang, track.srclang, t.options.googleApiKey, function(newOne) { gyorgy@0: gyorgy@0: // store the new translation gyorgy@0: track.entries = newOne; gyorgy@0: gyorgy@0: after(); gyorgy@0: }); gyorgy@0: gyorgy@0: } else { gyorgy@0: $.ajax({ gyorgy@0: url: track.src, gyorgy@0: success: function(d) { gyorgy@0: gyorgy@0: // parse the loaded file gyorgy@0: track.entries = mejs.TrackFormatParser.parse(d); gyorgy@0: after(); gyorgy@0: gyorgy@0: if (track.kind == 'chapters' && t.media.duration > 0) { gyorgy@0: t.drawChapters(track); gyorgy@0: } gyorgy@0: }, gyorgy@0: error: function() { gyorgy@0: t.loadNextTrack(); gyorgy@0: } gyorgy@0: }); gyorgy@0: } gyorgy@0: }, gyorgy@0: gyorgy@0: enableTrackButton: function(lang) { gyorgy@0: var t = this; gyorgy@0: gyorgy@0: t.captionsButton gyorgy@0: .find('input[value=' + lang + ']') gyorgy@0: .prop('disabled',false) gyorgy@0: .siblings('label') gyorgy@0: .html( mejs.language.codes[lang] || lang ); gyorgy@0: gyorgy@0: // auto select gyorgy@0: if (t.options.startLanguage == lang) { gyorgy@0: $('#' + t.id + '_captions_' + lang).click(); gyorgy@0: } gyorgy@0: gyorgy@0: t.adjustLanguageBox(); gyorgy@0: }, gyorgy@0: gyorgy@0: addTrackButton: function(lang, isTranslation) { gyorgy@0: var t = this, gyorgy@0: l = mejs.language.codes[lang] || lang; gyorgy@0: gyorgy@0: t.captionsButton.find('ul').append( gyorgy@0: $('
  • '+ gyorgy@0: '' + gyorgy@0: ''+ gyorgy@0: '
  • ') gyorgy@0: ); gyorgy@0: gyorgy@0: t.adjustLanguageBox(); gyorgy@0: gyorgy@0: // remove this from the dropdownlist (if it exists) gyorgy@0: t.container.find('.mejs-captions-translations option[value=' + lang + ']').remove(); gyorgy@0: }, gyorgy@0: gyorgy@0: adjustLanguageBox:function() { gyorgy@0: var t = this; gyorgy@0: // adjust the size of the outer box gyorgy@0: t.captionsButton.find('.mejs-captions-selector').height( gyorgy@0: t.captionsButton.find('.mejs-captions-selector ul').outerHeight(true) + gyorgy@0: t.captionsButton.find('.mejs-captions-translations').outerHeight(true) gyorgy@0: ); gyorgy@0: }, gyorgy@0: gyorgy@0: displayCaptions: function() { gyorgy@0: gyorgy@0: if (typeof this.tracks == 'undefined') gyorgy@0: return; gyorgy@0: gyorgy@0: var gyorgy@0: t = this, gyorgy@0: i, gyorgy@0: track = t.selectedTrack; gyorgy@0: gyorgy@0: if (track != null && track.isLoaded) { gyorgy@0: for (i=0; i= track.entries.times[i].start && t.media.currentTime <= track.entries.times[i].stop){ gyorgy@0: t.captionsText.html(track.entries.text[i]); gyorgy@0: t.captions.show(); gyorgy@0: return; // exit out if one is visible; gyorgy@0: } gyorgy@0: } gyorgy@0: t.captions.hide(); gyorgy@0: } else { gyorgy@0: t.captions.hide(); gyorgy@0: } gyorgy@0: }, gyorgy@0: gyorgy@0: displayChapters: function() { gyorgy@0: var gyorgy@0: t = this, gyorgy@0: i; gyorgy@0: gyorgy@0: for (i=0; i 100 || // too large gyorgy@0: i == chapters.entries.times.length-1 && percent + usedPercent < 100) // not going to fill it in gyorgy@0: { gyorgy@0: percent = 100 - usedPercent; gyorgy@0: } gyorgy@0: //width = Math.floor(t.width * dur / t.media.duration); gyorgy@0: //left = Math.floor(t.width * chapters.entries.times[i].start / t.media.duration); gyorgy@0: //if (left + width > t.width) { gyorgy@0: // width = t.width - left; gyorgy@0: //} gyorgy@0: gyorgy@0: t.chapters.append( $( gyorgy@0: '
    ' + gyorgy@0: '
    ' + gyorgy@0: '' + chapters.entries.text[i] + '' + gyorgy@0: '' + mejs.Utility.secondsToTimeCode(chapters.entries.times[i].start) + '–' + mejs.Utility.secondsToTimeCode(chapters.entries.times[i].stop) + '' + gyorgy@0: '
    ' + gyorgy@0: '
    ')); gyorgy@0: usedPercent += percent; gyorgy@0: } gyorgy@0: gyorgy@0: t.chapters.find('div.mejs-chapter').click(function() { gyorgy@0: t.media.setCurrentTime( parseFloat( $(this).attr('rel') ) ); gyorgy@0: if (t.media.paused) { gyorgy@0: t.media.play(); gyorgy@0: } gyorgy@0: }); gyorgy@0: gyorgy@0: t.chapters.show(); gyorgy@0: } gyorgy@0: }); gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: mejs.language = { gyorgy@0: codes: { gyorgy@0: af:'Afrikaans', gyorgy@0: sq:'Albanian', gyorgy@0: ar:'Arabic', gyorgy@0: be:'Belarusian', gyorgy@0: bg:'Bulgarian', gyorgy@0: ca:'Catalan', gyorgy@0: zh:'Chinese', gyorgy@0: 'zh-cn':'Chinese Simplified', gyorgy@0: 'zh-tw':'Chinese Traditional', gyorgy@0: hr:'Croatian', gyorgy@0: cs:'Czech', gyorgy@0: da:'Danish', gyorgy@0: nl:'Dutch', gyorgy@0: en:'English', gyorgy@0: et:'Estonian', gyorgy@0: tl:'Filipino', gyorgy@0: fi:'Finnish', gyorgy@0: fr:'French', gyorgy@0: gl:'Galician', gyorgy@0: de:'German', gyorgy@0: el:'Greek', gyorgy@0: ht:'Haitian Creole', gyorgy@0: iw:'Hebrew', gyorgy@0: hi:'Hindi', gyorgy@0: hu:'Hungarian', gyorgy@0: is:'Icelandic', gyorgy@0: id:'Indonesian', gyorgy@0: ga:'Irish', gyorgy@0: it:'Italian', gyorgy@0: ja:'Japanese', gyorgy@0: ko:'Korean', gyorgy@0: lv:'Latvian', gyorgy@0: lt:'Lithuanian', gyorgy@0: mk:'Macedonian', gyorgy@0: ms:'Malay', gyorgy@0: mt:'Maltese', gyorgy@0: no:'Norwegian', gyorgy@0: fa:'Persian', gyorgy@0: pl:'Polish', gyorgy@0: pt:'Portuguese', gyorgy@0: //'pt-pt':'Portuguese (Portugal)', gyorgy@0: ro:'Romanian', gyorgy@0: ru:'Russian', gyorgy@0: sr:'Serbian', gyorgy@0: sk:'Slovak', gyorgy@0: sl:'Slovenian', gyorgy@0: es:'Spanish', gyorgy@0: sw:'Swahili', gyorgy@0: sv:'Swedish', gyorgy@0: tl:'Tagalog', gyorgy@0: th:'Thai', gyorgy@0: tr:'Turkish', gyorgy@0: uk:'Ukrainian', gyorgy@0: vi:'Vietnamese', gyorgy@0: cy:'Welsh', gyorgy@0: yi:'Yiddish' gyorgy@0: } gyorgy@0: }; gyorgy@0: gyorgy@0: /* gyorgy@0: Parses WebVVT format which should be formatted as gyorgy@0: ================================ gyorgy@0: WEBVTT gyorgy@0: gyorgy@0: 1 gyorgy@0: 00:00:01,1 --> 00:00:05,000 gyorgy@0: A line of text gyorgy@0: gyorgy@0: 2 gyorgy@0: 00:01:15,1 --> 00:02:05,000 gyorgy@0: A second line of text gyorgy@0: gyorgy@0: =============================== gyorgy@0: gyorgy@0: Adapted from: http://www.delphiki.com/html5/playr gyorgy@0: */ gyorgy@0: mejs.TrackFormatParser = { gyorgy@0: // match start "chapter-" (or anythingelse) gyorgy@0: pattern_identifier: /^([a-zA-z]+-)?[0-9]+$/, gyorgy@0: pattern_timecode: /^([0-9]{2}:[0-9]{2}:[0-9]{2}([,.][0-9]{1,3})?) --\> ([0-9]{2}:[0-9]{2}:[0-9]{2}([,.][0-9]{3})?)(.*)$/, gyorgy@0: gyorgy@0: split2: function (text, regex) { gyorgy@0: // normal version for compliant browsers gyorgy@0: // see below for IE fix gyorgy@0: return text.split(regex); gyorgy@0: }, gyorgy@0: parse: function(trackText) { gyorgy@0: var gyorgy@0: i = 0, gyorgy@0: lines = this.split2(trackText, /\r?\n/), gyorgy@0: entries = {text:[], times:[]}, gyorgy@0: timecode, gyorgy@0: text; gyorgy@0: gyorgy@0: for(; i end time code should be gyorgy@0: i++; gyorgy@0: timecode = this.pattern_timecode.exec(lines[i]); gyorgy@0: gyorgy@0: if (timecode && i'), fromLang, toLang, googleApiKey, function(result) { gyorgy@0: // split on separators gyorgy@0: lines = result.split(''); gyorgy@0: gyorgy@0: // create new entries gyorgy@0: for (i=0;i 0) { gyorgy@0: chunk = chunks.shift(); gyorgy@0: mejs.TrackFormatParser.translateChunk(chunk, fromLang, toLang, googleApiKey, function(r) { gyorgy@0: if (r != 'undefined') { gyorgy@0: result += r; gyorgy@0: } gyorgy@0: nextChunk(); gyorgy@0: }); gyorgy@0: } else { gyorgy@0: callback(result); gyorgy@0: } gyorgy@0: }; gyorgy@0: gyorgy@0: // split into chunks gyorgy@0: while (text.length > 0) { gyorgy@0: if (text.length > maxlength) { gyorgy@0: separatorIndex = text.lastIndexOf('.', maxlength); gyorgy@0: chunks.push(text.substring(0, separatorIndex)); gyorgy@0: text = text.substring(separatorIndex+1); gyorgy@0: } else { gyorgy@0: chunks.push(text); gyorgy@0: text = ''; gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: // start handling the chunks gyorgy@0: nextChunk(); gyorgy@0: }, gyorgy@0: translateChunk: function(text, fromLang, toLang, googleApiKey, callback) { gyorgy@0: gyorgy@0: var data = { gyorgy@0: q: text, gyorgy@0: langpair: fromLang + '|' + toLang, gyorgy@0: v: '1.0' gyorgy@0: }; gyorgy@0: if (googleApiKey !== '' && googleApiKey !== null) { gyorgy@0: data.key = googleApiKey; gyorgy@0: } gyorgy@0: gyorgy@0: $.ajax({ gyorgy@0: url: 'https://ajax.googleapis.com/ajax/services/language/translate', // 'https://www.google.com/uds/Gtranslate', //'https://ajax.googleapis.com/ajax/services/language/translate', // gyorgy@0: data: data, gyorgy@0: type: 'GET', gyorgy@0: dataType: 'jsonp', gyorgy@0: success: function(d) { gyorgy@0: callback(d.responseData.translatedText); gyorgy@0: }, gyorgy@0: error: function(e) { gyorgy@0: callback(null); gyorgy@0: } gyorgy@0: }); gyorgy@0: } gyorgy@0: }; gyorgy@0: // test for browsers with bad String.split method. gyorgy@0: if ('x\n\ny'.split(/\n/gi).length != 3) { gyorgy@0: // add super slow IE8 and below version gyorgy@0: mejs.TrackFormatParser.split2 = function(text, regex) { gyorgy@0: var gyorgy@0: parts = [], gyorgy@0: chunk = '', gyorgy@0: i; gyorgy@0: gyorgy@0: for (i=0; i