annotate johndyer-mediaelement-13fa20a/src/js/mep-feature-tracks.js @ 25:4a4bd554b4c1 tip

Closing this sub branch.
author Daniele Barchiesi <daniele.barchiesi@eecs.qmul.ac.uk>
date Mon, 25 Mar 2013 14:02:54 +0000
parents 032bc65ebafc
children
rev   line source
gyorgy@0 1 (function($) {
gyorgy@0 2
gyorgy@0 3 // add extra default options
gyorgy@0 4 $.extend(mejs.MepDefaults, {
gyorgy@0 5 // this will automatically turn on a <track>
gyorgy@0 6 startLanguage: '',
gyorgy@0 7 // a list of languages to auto-translate via Google
gyorgy@0 8 translations: [],
gyorgy@0 9 // a dropdownlist of automatic translations
gyorgy@0 10 translationSelector: false,
gyorgy@0 11 // key for tranlsations
gyorgy@0 12 googleApiKey: ''
gyorgy@0 13 });
gyorgy@0 14
gyorgy@0 15 $.extend(MediaElementPlayer.prototype, {
gyorgy@0 16
gyorgy@0 17 buildtracks: function(player, controls, layers, media) {
gyorgy@0 18 if (!player.isVideo)
gyorgy@0 19 return;
gyorgy@0 20
gyorgy@0 21 if (player.tracks.length == 0)
gyorgy@0 22 return;
gyorgy@0 23
gyorgy@0 24 var i, options = '';
gyorgy@0 25
gyorgy@0 26 player.chapters =
gyorgy@0 27 $('<div class="mejs-chapters mejs-layer"></div>')
gyorgy@0 28 .prependTo(layers).hide();
gyorgy@0 29 player.captions =
gyorgy@0 30 $('<div class="mejs-captions-layer mejs-layer"><div class="mejs-captions-position"><span class="mejs-captions-text"></span></div></div>')
gyorgy@0 31 .prependTo(layers).hide();
gyorgy@0 32 player.captionsText = player.captions.find('.mejs-captions-text');
gyorgy@0 33 player.captionsButton =
gyorgy@0 34 $('<div class="mejs-button mejs-captions-button">'+
gyorgy@0 35 '<button type="button" ></button>'+
gyorgy@0 36 '<div class="mejs-captions-selector">'+
gyorgy@0 37 '<ul>'+
gyorgy@0 38 '<li>'+
gyorgy@0 39 '<input type="radio" name="' + player.id + '_captions" id="' + player.id + '_captions_none" value="none" checked="checked" />' +
gyorgy@0 40 '<label for="' + player.id + '_captions_none">None</label>'+
gyorgy@0 41 '</li>' +
gyorgy@0 42 '</ul>'+
gyorgy@0 43 '</div>'+
gyorgy@0 44 '</div>')
gyorgy@0 45 .appendTo(controls)
gyorgy@0 46
gyorgy@0 47 // hover
gyorgy@0 48 .hover(function() {
gyorgy@0 49 $(this).find('.mejs-captions-selector').css('visibility','visible');
gyorgy@0 50 }, function() {
gyorgy@0 51 $(this).find('.mejs-captions-selector').css('visibility','hidden');
gyorgy@0 52 })
gyorgy@0 53
gyorgy@0 54 // handle clicks to the language radio buttons
gyorgy@0 55 .delegate('input[type=radio]','click',function() {
gyorgy@0 56 lang = this.value;
gyorgy@0 57
gyorgy@0 58 if (lang == 'none') {
gyorgy@0 59 player.selectedTrack = null;
gyorgy@0 60 } else {
gyorgy@0 61 for (i=0; i<player.tracks.length; i++) {
gyorgy@0 62 if (player.tracks[i].srclang == lang) {
gyorgy@0 63 player.selectedTrack = player.tracks[i];
gyorgy@0 64 player.captions.attr('lang', player.selectedTrack.srclang);
gyorgy@0 65 player.displayCaptions();
gyorgy@0 66 break;
gyorgy@0 67 }
gyorgy@0 68 }
gyorgy@0 69 }
gyorgy@0 70 });
gyorgy@0 71 //.bind('mouseenter', function() {
gyorgy@0 72 // player.captionsButton.find('.mejs-captions-selector').css('visibility','visible')
gyorgy@0 73 //});
gyorgy@0 74
gyorgy@0 75 if (!player.options.alwaysShowControls) {
gyorgy@0 76 // move with controls
gyorgy@0 77 player.container
gyorgy@0 78 .bind('mouseenter', function () {
gyorgy@0 79 // push captions above controls
gyorgy@0 80 player.container.find('.mejs-captions-position').addClass('mejs-captions-position-hover');
gyorgy@0 81
gyorgy@0 82 })
gyorgy@0 83 .bind('mouseleave', function () {
gyorgy@0 84 if (!media.paused) {
gyorgy@0 85 // move back to normal place
gyorgy@0 86 player.container.find('.mejs-captions-position').removeClass('mejs-captions-position-hover');
gyorgy@0 87 }
gyorgy@0 88 });
gyorgy@0 89 } else {
gyorgy@0 90 player.container.find('.mejs-captions-position').addClass('mejs-captions-position-hover');
gyorgy@0 91 }
gyorgy@0 92
gyorgy@0 93 player.trackToLoad = -1;
gyorgy@0 94 player.selectedTrack = null;
gyorgy@0 95 player.isLoadingTrack = false;
gyorgy@0 96
gyorgy@0 97 // add user-defined translations
gyorgy@0 98 if (player.tracks.length > 0 && player.options.translations.length > 0) {
gyorgy@0 99 for (i=0; i<player.options.translations.length; i++) {
gyorgy@0 100 player.tracks.push({
gyorgy@0 101 srclang: player.options.translations[i].toLowerCase(),
gyorgy@0 102 src: null,
gyorgy@0 103 kind: 'subtitles',
gyorgy@0 104 entries: [],
gyorgy@0 105 isLoaded: false,
gyorgy@0 106 isTranslation: true
gyorgy@0 107 });
gyorgy@0 108 }
gyorgy@0 109 }
gyorgy@0 110
gyorgy@0 111 // add to list
gyorgy@0 112 for (i=0; i<player.tracks.length; i++) {
gyorgy@0 113 if (player.tracks[i].kind == 'subtitles') {
gyorgy@0 114 player.addTrackButton(player.tracks[i].srclang, player.tracks[i].isTranslation);
gyorgy@0 115 }
gyorgy@0 116 }
gyorgy@0 117
gyorgy@0 118 player.loadNextTrack();
gyorgy@0 119
gyorgy@0 120
gyorgy@0 121 media.addEventListener('timeupdate',function(e) {
gyorgy@0 122 player.displayCaptions();
gyorgy@0 123 }, false);
gyorgy@0 124
gyorgy@0 125 media.addEventListener('loadedmetadata', function(e) {
gyorgy@0 126 player.displayChapters();
gyorgy@0 127 }, false);
gyorgy@0 128
gyorgy@0 129 player.container.hover(
gyorgy@0 130 function () {
gyorgy@0 131 // chapters
gyorgy@0 132 player.chapters.css('visibility','visible');
gyorgy@0 133 player.chapters.fadeIn(200);
gyorgy@0 134 },
gyorgy@0 135 function () {
gyorgy@0 136 if (!media.paused) {
gyorgy@0 137 player.chapters.fadeOut(200, function() {
gyorgy@0 138 $(this).css('visibility','hidden');
gyorgy@0 139 $(this).css('display','block');
gyorgy@0 140 });
gyorgy@0 141 }
gyorgy@0 142 });
gyorgy@0 143
gyorgy@0 144 // check for autoplay
gyorgy@0 145 if (player.node.getAttribute('autoplay') !== null) {
gyorgy@0 146 player.chapters.css('visibility','hidden');
gyorgy@0 147 }
gyorgy@0 148
gyorgy@0 149 // auto selector
gyorgy@0 150 if (player.options.translationSelector) {
gyorgy@0 151 for (i in mejs.language.codes) {
gyorgy@0 152 options += '<option value="' + i + '">' + mejs.language.codes[i] + '</option>';
gyorgy@0 153 }
gyorgy@0 154 player.container.find('.mejs-captions-selector ul').before($(
gyorgy@0 155 '<select class="mejs-captions-translations">' +
gyorgy@0 156 '<option value="">--Add Translation--</option>' +
gyorgy@0 157 options +
gyorgy@0 158 '</select>'
gyorgy@0 159 ));
gyorgy@0 160 // add clicks
gyorgy@0 161 player.container.find('.mejs-captions-translations').change(function() {
gyorgy@0 162 var
gyorgy@0 163 option = $(this);
gyorgy@0 164 lang = option.val();
gyorgy@0 165 // add this language to the tracks list
gyorgy@0 166 if (lang != '') {
gyorgy@0 167 player.tracks.push({
gyorgy@0 168 srclang: lang,
gyorgy@0 169 src: null,
gyorgy@0 170 entries: [],
gyorgy@0 171 isLoaded: false,
gyorgy@0 172 isTranslation: true
gyorgy@0 173 });
gyorgy@0 174
gyorgy@0 175 if (!player.isLoadingTrack) {
gyorgy@0 176 player.trackToLoad--;
gyorgy@0 177 player.addTrackButton(lang,true);
gyorgy@0 178 player.options.startLanguage = lang;
gyorgy@0 179 player.loadNextTrack();
gyorgy@0 180 }
gyorgy@0 181 }
gyorgy@0 182 });
gyorgy@0 183 }
gyorgy@0 184
gyorgy@0 185 },
gyorgy@0 186
gyorgy@0 187 loadNextTrack: function() {
gyorgy@0 188 var t = this;
gyorgy@0 189
gyorgy@0 190 t.trackToLoad++;
gyorgy@0 191 if (t.trackToLoad < t.tracks.length) {
gyorgy@0 192 t.isLoadingTrack = true;
gyorgy@0 193 t.loadTrack(t.trackToLoad);
gyorgy@0 194 } else {
gyorgy@0 195 // add done?
gyorgy@0 196 t.isLoadingTrack = false;
gyorgy@0 197 }
gyorgy@0 198 },
gyorgy@0 199
gyorgy@0 200 loadTrack: function(index){
gyorgy@0 201 var
gyorgy@0 202 t = this,
gyorgy@0 203 track = t.tracks[index],
gyorgy@0 204 after = function() {
gyorgy@0 205
gyorgy@0 206 track.isLoaded = true;
gyorgy@0 207
gyorgy@0 208 // create button
gyorgy@0 209 //t.addTrackButton(track.srclang);
gyorgy@0 210 t.enableTrackButton(track.srclang);
gyorgy@0 211
gyorgy@0 212 t.loadNextTrack();
gyorgy@0 213
gyorgy@0 214 };
gyorgy@0 215
gyorgy@0 216 if (track.isTranslation) {
gyorgy@0 217
gyorgy@0 218 // translate the first track
gyorgy@0 219 mejs.TrackFormatParser.translateTrackText(t.tracks[0].entries, t.tracks[0].srclang, track.srclang, t.options.googleApiKey, function(newOne) {
gyorgy@0 220
gyorgy@0 221 // store the new translation
gyorgy@0 222 track.entries = newOne;
gyorgy@0 223
gyorgy@0 224 after();
gyorgy@0 225 });
gyorgy@0 226
gyorgy@0 227 } else {
gyorgy@0 228 $.ajax({
gyorgy@0 229 url: track.src,
gyorgy@0 230 success: function(d) {
gyorgy@0 231
gyorgy@0 232 // parse the loaded file
gyorgy@0 233 track.entries = mejs.TrackFormatParser.parse(d);
gyorgy@0 234 after();
gyorgy@0 235
gyorgy@0 236 if (track.kind == 'chapters' && t.media.duration > 0) {
gyorgy@0 237 t.drawChapters(track);
gyorgy@0 238 }
gyorgy@0 239 },
gyorgy@0 240 error: function() {
gyorgy@0 241 t.loadNextTrack();
gyorgy@0 242 }
gyorgy@0 243 });
gyorgy@0 244 }
gyorgy@0 245 },
gyorgy@0 246
gyorgy@0 247 enableTrackButton: function(lang) {
gyorgy@0 248 var t = this;
gyorgy@0 249
gyorgy@0 250 t.captionsButton
gyorgy@0 251 .find('input[value=' + lang + ']')
gyorgy@0 252 .prop('disabled',false)
gyorgy@0 253 .siblings('label')
gyorgy@0 254 .html( mejs.language.codes[lang] || lang );
gyorgy@0 255
gyorgy@0 256 // auto select
gyorgy@0 257 if (t.options.startLanguage == lang) {
gyorgy@0 258 $('#' + t.id + '_captions_' + lang).click();
gyorgy@0 259 }
gyorgy@0 260
gyorgy@0 261 t.adjustLanguageBox();
gyorgy@0 262 },
gyorgy@0 263
gyorgy@0 264 addTrackButton: function(lang, isTranslation) {
gyorgy@0 265 var t = this,
gyorgy@0 266 l = mejs.language.codes[lang] || lang;
gyorgy@0 267
gyorgy@0 268 t.captionsButton.find('ul').append(
gyorgy@0 269 $('<li>'+
gyorgy@0 270 '<input type="radio" name="' + t.id + '_captions" id="' + t.id + '_captions_' + lang + '" value="' + lang + '" disabled="disabled" />' +
gyorgy@0 271 '<label for="' + t.id + '_captions_' + lang + '">' + l + ((isTranslation) ? ' (translating)' : ' (loading)') + '</label>'+
gyorgy@0 272 '</li>')
gyorgy@0 273 );
gyorgy@0 274
gyorgy@0 275 t.adjustLanguageBox();
gyorgy@0 276
gyorgy@0 277 // remove this from the dropdownlist (if it exists)
gyorgy@0 278 t.container.find('.mejs-captions-translations option[value=' + lang + ']').remove();
gyorgy@0 279 },
gyorgy@0 280
gyorgy@0 281 adjustLanguageBox:function() {
gyorgy@0 282 var t = this;
gyorgy@0 283 // adjust the size of the outer box
gyorgy@0 284 t.captionsButton.find('.mejs-captions-selector').height(
gyorgy@0 285 t.captionsButton.find('.mejs-captions-selector ul').outerHeight(true) +
gyorgy@0 286 t.captionsButton.find('.mejs-captions-translations').outerHeight(true)
gyorgy@0 287 );
gyorgy@0 288 },
gyorgy@0 289
gyorgy@0 290 displayCaptions: function() {
gyorgy@0 291
gyorgy@0 292 if (typeof this.tracks == 'undefined')
gyorgy@0 293 return;
gyorgy@0 294
gyorgy@0 295 var
gyorgy@0 296 t = this,
gyorgy@0 297 i,
gyorgy@0 298 track = t.selectedTrack;
gyorgy@0 299
gyorgy@0 300 if (track != null && track.isLoaded) {
gyorgy@0 301 for (i=0; i<track.entries.times.length; i++) {
gyorgy@0 302 if (t.media.currentTime >= track.entries.times[i].start && t.media.currentTime <= track.entries.times[i].stop){
gyorgy@0 303 t.captionsText.html(track.entries.text[i]);
gyorgy@0 304 t.captions.show();
gyorgy@0 305 return; // exit out if one is visible;
gyorgy@0 306 }
gyorgy@0 307 }
gyorgy@0 308 t.captions.hide();
gyorgy@0 309 } else {
gyorgy@0 310 t.captions.hide();
gyorgy@0 311 }
gyorgy@0 312 },
gyorgy@0 313
gyorgy@0 314 displayChapters: function() {
gyorgy@0 315 var
gyorgy@0 316 t = this,
gyorgy@0 317 i;
gyorgy@0 318
gyorgy@0 319 for (i=0; i<t.tracks.length; i++) {
gyorgy@0 320 if (t.tracks[i].kind == 'chapters' && t.tracks[i].isLoaded) {
gyorgy@0 321 t.drawChapters(t.tracks[i]);
gyorgy@0 322 break;
gyorgy@0 323 }
gyorgy@0 324 }
gyorgy@0 325 },
gyorgy@0 326
gyorgy@0 327 drawChapters: function(chapters) {
gyorgy@0 328 var
gyorgy@0 329 t = this,
gyorgy@0 330 i,
gyorgy@0 331 dur,
gyorgy@0 332 //width,
gyorgy@0 333 //left,
gyorgy@0 334 percent = 0,
gyorgy@0 335 usedPercent = 0;
gyorgy@0 336
gyorgy@0 337 t.chapters.empty();
gyorgy@0 338
gyorgy@0 339 for (i=0; i<chapters.entries.times.length; i++) {
gyorgy@0 340 dur = chapters.entries.times[i].stop - chapters.entries.times[i].start;
gyorgy@0 341 percent = Math.floor(dur / t.media.duration * 100);
gyorgy@0 342 if (percent + usedPercent > 100 || // too large
gyorgy@0 343 i == chapters.entries.times.length-1 && percent + usedPercent < 100) // not going to fill it in
gyorgy@0 344 {
gyorgy@0 345 percent = 100 - usedPercent;
gyorgy@0 346 }
gyorgy@0 347 //width = Math.floor(t.width * dur / t.media.duration);
gyorgy@0 348 //left = Math.floor(t.width * chapters.entries.times[i].start / t.media.duration);
gyorgy@0 349 //if (left + width > t.width) {
gyorgy@0 350 // width = t.width - left;
gyorgy@0 351 //}
gyorgy@0 352
gyorgy@0 353 t.chapters.append( $(
gyorgy@0 354 '<div class="mejs-chapter" rel="' + chapters.entries.times[i].start + '" style="left: ' + usedPercent.toString() + '%;width: ' + percent.toString() + '%;">' +
gyorgy@0 355 '<div class="mejs-chapter-block' + ((i==chapters.entries.times.length-1) ? ' mejs-chapter-block-last' : '') + '">' +
gyorgy@0 356 '<span class="ch-title">' + chapters.entries.text[i] + '</span>' +
gyorgy@0 357 '<span class="ch-time">' + mejs.Utility.secondsToTimeCode(chapters.entries.times[i].start) + '&ndash;' + mejs.Utility.secondsToTimeCode(chapters.entries.times[i].stop) + '</span>' +
gyorgy@0 358 '</div>' +
gyorgy@0 359 '</div>'));
gyorgy@0 360 usedPercent += percent;
gyorgy@0 361 }
gyorgy@0 362
gyorgy@0 363 t.chapters.find('div.mejs-chapter').click(function() {
gyorgy@0 364 t.media.setCurrentTime( parseFloat( $(this).attr('rel') ) );
gyorgy@0 365 if (t.media.paused) {
gyorgy@0 366 t.media.play();
gyorgy@0 367 }
gyorgy@0 368 });
gyorgy@0 369
gyorgy@0 370 t.chapters.show();
gyorgy@0 371 }
gyorgy@0 372 });
gyorgy@0 373
gyorgy@0 374
gyorgy@0 375
gyorgy@0 376 mejs.language = {
gyorgy@0 377 codes: {
gyorgy@0 378 af:'Afrikaans',
gyorgy@0 379 sq:'Albanian',
gyorgy@0 380 ar:'Arabic',
gyorgy@0 381 be:'Belarusian',
gyorgy@0 382 bg:'Bulgarian',
gyorgy@0 383 ca:'Catalan',
gyorgy@0 384 zh:'Chinese',
gyorgy@0 385 'zh-cn':'Chinese Simplified',
gyorgy@0 386 'zh-tw':'Chinese Traditional',
gyorgy@0 387 hr:'Croatian',
gyorgy@0 388 cs:'Czech',
gyorgy@0 389 da:'Danish',
gyorgy@0 390 nl:'Dutch',
gyorgy@0 391 en:'English',
gyorgy@0 392 et:'Estonian',
gyorgy@0 393 tl:'Filipino',
gyorgy@0 394 fi:'Finnish',
gyorgy@0 395 fr:'French',
gyorgy@0 396 gl:'Galician',
gyorgy@0 397 de:'German',
gyorgy@0 398 el:'Greek',
gyorgy@0 399 ht:'Haitian Creole',
gyorgy@0 400 iw:'Hebrew',
gyorgy@0 401 hi:'Hindi',
gyorgy@0 402 hu:'Hungarian',
gyorgy@0 403 is:'Icelandic',
gyorgy@0 404 id:'Indonesian',
gyorgy@0 405 ga:'Irish',
gyorgy@0 406 it:'Italian',
gyorgy@0 407 ja:'Japanese',
gyorgy@0 408 ko:'Korean',
gyorgy@0 409 lv:'Latvian',
gyorgy@0 410 lt:'Lithuanian',
gyorgy@0 411 mk:'Macedonian',
gyorgy@0 412 ms:'Malay',
gyorgy@0 413 mt:'Maltese',
gyorgy@0 414 no:'Norwegian',
gyorgy@0 415 fa:'Persian',
gyorgy@0 416 pl:'Polish',
gyorgy@0 417 pt:'Portuguese',
gyorgy@0 418 //'pt-pt':'Portuguese (Portugal)',
gyorgy@0 419 ro:'Romanian',
gyorgy@0 420 ru:'Russian',
gyorgy@0 421 sr:'Serbian',
gyorgy@0 422 sk:'Slovak',
gyorgy@0 423 sl:'Slovenian',
gyorgy@0 424 es:'Spanish',
gyorgy@0 425 sw:'Swahili',
gyorgy@0 426 sv:'Swedish',
gyorgy@0 427 tl:'Tagalog',
gyorgy@0 428 th:'Thai',
gyorgy@0 429 tr:'Turkish',
gyorgy@0 430 uk:'Ukrainian',
gyorgy@0 431 vi:'Vietnamese',
gyorgy@0 432 cy:'Welsh',
gyorgy@0 433 yi:'Yiddish'
gyorgy@0 434 }
gyorgy@0 435 };
gyorgy@0 436
gyorgy@0 437 /*
gyorgy@0 438 Parses WebVVT format which should be formatted as
gyorgy@0 439 ================================
gyorgy@0 440 WEBVTT
gyorgy@0 441
gyorgy@0 442 1
gyorgy@0 443 00:00:01,1 --> 00:00:05,000
gyorgy@0 444 A line of text
gyorgy@0 445
gyorgy@0 446 2
gyorgy@0 447 00:01:15,1 --> 00:02:05,000
gyorgy@0 448 A second line of text
gyorgy@0 449
gyorgy@0 450 ===============================
gyorgy@0 451
gyorgy@0 452 Adapted from: http://www.delphiki.com/html5/playr
gyorgy@0 453 */
gyorgy@0 454 mejs.TrackFormatParser = {
gyorgy@0 455 // match start "chapter-" (or anythingelse)
gyorgy@0 456 pattern_identifier: /^([a-zA-z]+-)?[0-9]+$/,
gyorgy@0 457 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 458
gyorgy@0 459 split2: function (text, regex) {
gyorgy@0 460 // normal version for compliant browsers
gyorgy@0 461 // see below for IE fix
gyorgy@0 462 return text.split(regex);
gyorgy@0 463 },
gyorgy@0 464 parse: function(trackText) {
gyorgy@0 465 var
gyorgy@0 466 i = 0,
gyorgy@0 467 lines = this.split2(trackText, /\r?\n/),
gyorgy@0 468 entries = {text:[], times:[]},
gyorgy@0 469 timecode,
gyorgy@0 470 text;
gyorgy@0 471
gyorgy@0 472 for(; i<lines.length; i++) {
gyorgy@0 473 // check for the line number
gyorgy@0 474 if (this.pattern_identifier.exec(lines[i])){
gyorgy@0 475 // skip to the next line where the start --> end time code should be
gyorgy@0 476 i++;
gyorgy@0 477 timecode = this.pattern_timecode.exec(lines[i]);
gyorgy@0 478
gyorgy@0 479 if (timecode && i<lines.length){
gyorgy@0 480 i++;
gyorgy@0 481 // grab all the (possibly multi-line) text that follows
gyorgy@0 482 text = lines[i];
gyorgy@0 483 i++;
gyorgy@0 484 while(lines[i] !== '' && i<lines.length){
gyorgy@0 485 text = text + '\n' + lines[i];
gyorgy@0 486 i++;
gyorgy@0 487 }
gyorgy@0 488
gyorgy@0 489 // Text is in a different array so I can use .join
gyorgy@0 490 entries.text.push(text);
gyorgy@0 491 entries.times.push(
gyorgy@0 492 {
gyorgy@0 493 start: mejs.Utility.timeCodeToSeconds(timecode[1]),
gyorgy@0 494 stop: mejs.Utility.timeCodeToSeconds(timecode[3]),
gyorgy@0 495 settings: timecode[5]
gyorgy@0 496 });
gyorgy@0 497 }
gyorgy@0 498 }
gyorgy@0 499 }
gyorgy@0 500
gyorgy@0 501 return entries;
gyorgy@0 502 },
gyorgy@0 503
gyorgy@0 504 translateTrackText: function(trackData, fromLang, toLang, googleApiKey, callback) {
gyorgy@0 505
gyorgy@0 506 var
gyorgy@0 507 entries = {text:[], times:[]},
gyorgy@0 508 lines,
gyorgy@0 509 i
gyorgy@0 510
gyorgy@0 511 this.translateText( trackData.text.join(' <a></a>'), fromLang, toLang, googleApiKey, function(result) {
gyorgy@0 512 // split on separators
gyorgy@0 513 lines = result.split('<a></a>');
gyorgy@0 514
gyorgy@0 515 // create new entries
gyorgy@0 516 for (i=0;i<trackData.text.length; i++) {
gyorgy@0 517 // add translated line
gyorgy@0 518 entries.text[i] = lines[i];
gyorgy@0 519 // copy existing times
gyorgy@0 520 entries.times[i] = {
gyorgy@0 521 start: trackData.times[i].start,
gyorgy@0 522 stop: trackData.times[i].stop,
gyorgy@0 523 settings: trackData.times[i].settings
gyorgy@0 524 };
gyorgy@0 525 }
gyorgy@0 526
gyorgy@0 527 callback(entries);
gyorgy@0 528 });
gyorgy@0 529 },
gyorgy@0 530
gyorgy@0 531 translateText: function(text, fromLang, toLang, googleApiKey, callback) {
gyorgy@0 532
gyorgy@0 533 var
gyorgy@0 534 separatorIndex,
gyorgy@0 535 chunks = [],
gyorgy@0 536 chunk,
gyorgy@0 537 maxlength = 1000,
gyorgy@0 538 result = '',
gyorgy@0 539 nextChunk= function() {
gyorgy@0 540 if (chunks.length > 0) {
gyorgy@0 541 chunk = chunks.shift();
gyorgy@0 542 mejs.TrackFormatParser.translateChunk(chunk, fromLang, toLang, googleApiKey, function(r) {
gyorgy@0 543 if (r != 'undefined') {
gyorgy@0 544 result += r;
gyorgy@0 545 }
gyorgy@0 546 nextChunk();
gyorgy@0 547 });
gyorgy@0 548 } else {
gyorgy@0 549 callback(result);
gyorgy@0 550 }
gyorgy@0 551 };
gyorgy@0 552
gyorgy@0 553 // split into chunks
gyorgy@0 554 while (text.length > 0) {
gyorgy@0 555 if (text.length > maxlength) {
gyorgy@0 556 separatorIndex = text.lastIndexOf('.', maxlength);
gyorgy@0 557 chunks.push(text.substring(0, separatorIndex));
gyorgy@0 558 text = text.substring(separatorIndex+1);
gyorgy@0 559 } else {
gyorgy@0 560 chunks.push(text);
gyorgy@0 561 text = '';
gyorgy@0 562 }
gyorgy@0 563 }
gyorgy@0 564
gyorgy@0 565 // start handling the chunks
gyorgy@0 566 nextChunk();
gyorgy@0 567 },
gyorgy@0 568 translateChunk: function(text, fromLang, toLang, googleApiKey, callback) {
gyorgy@0 569
gyorgy@0 570 var data = {
gyorgy@0 571 q: text,
gyorgy@0 572 langpair: fromLang + '|' + toLang,
gyorgy@0 573 v: '1.0'
gyorgy@0 574 };
gyorgy@0 575 if (googleApiKey !== '' && googleApiKey !== null) {
gyorgy@0 576 data.key = googleApiKey;
gyorgy@0 577 }
gyorgy@0 578
gyorgy@0 579 $.ajax({
gyorgy@0 580 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 581 data: data,
gyorgy@0 582 type: 'GET',
gyorgy@0 583 dataType: 'jsonp',
gyorgy@0 584 success: function(d) {
gyorgy@0 585 callback(d.responseData.translatedText);
gyorgy@0 586 },
gyorgy@0 587 error: function(e) {
gyorgy@0 588 callback(null);
gyorgy@0 589 }
gyorgy@0 590 });
gyorgy@0 591 }
gyorgy@0 592 };
gyorgy@0 593 // test for browsers with bad String.split method.
gyorgy@0 594 if ('x\n\ny'.split(/\n/gi).length != 3) {
gyorgy@0 595 // add super slow IE8 and below version
gyorgy@0 596 mejs.TrackFormatParser.split2 = function(text, regex) {
gyorgy@0 597 var
gyorgy@0 598 parts = [],
gyorgy@0 599 chunk = '',
gyorgy@0 600 i;
gyorgy@0 601
gyorgy@0 602 for (i=0; i<text.length; i++) {
gyorgy@0 603 chunk += text.substring(i,i+1);
gyorgy@0 604 if (regex.test(chunk)) {
gyorgy@0 605 parts.push(chunk.replace(regex, ''));
gyorgy@0 606 chunk = '';
gyorgy@0 607 }
gyorgy@0 608 }
gyorgy@0 609 parts.push(chunk);
gyorgy@0 610 return parts;
gyorgy@0 611 }
gyorgy@0 612 }
gyorgy@0 613
gyorgy@0 614 })(mejs.$);