podlove-web-player-rails 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NzJjNmViNjcwNjUxMGE5NDllMDE5OWRiNzEzNWNlYzhkM2I2ZDQyZQ==
5
- data.tar.gz: !binary |-
6
- Y2M5ZTA4MGNlZmNlMzFkZjM2MjNiYzQ2NjM0NWM5NzgxMDFiM2JiMA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- OTc0YzZmMDZhMWQzY2UyOWNjODE5YzljYWMwOWRkZmI3NGQzZjQyMDczOTFj
10
- YmFiNTA5NTExZTU3MGQwZDA0YTE5ZDZlOTMxMWJmZjMwZDBhODc4MTVjMWVk
11
- ZDNkMDFiNjhmOGJlNDU4NDNlZDBmYjU5NzA4Y2UyZjg3MTU5Yjc=
12
- data.tar.gz: !binary |-
13
- ODBhMjA5NzUwYjc1OWIyODkxMzQ2Y2U5M2ZjMDcwNzljZTFmZTRhMTA4MDkz
14
- ZDk5MTI4NmIxMmVjNWUxOTkwMGRmNDBkN2E0NTNmZGJmMzBkNTRkOWQ2NDg3
15
- NDI4NTJkNjgyYjk0MzdkOGYxMWFkNmRjOTExM2Y1MTRhYWJmYjQ=
2
+ SHA1:
3
+ metadata.gz: 2bfe932df08b6633da4ec741f6ddeac1ed6034b1
4
+ data.tar.gz: 586ab2ad17a7ca3ed7c842dcb6819478857e23fc
5
+ SHA512:
6
+ metadata.gz: c9eaceaf819b8f4c41aaa830d4d8ef091fb8acc416878e2362909df4b792bf857b400e8cc2d31450c2acec5418dea0ccac6d423373334672c4dc4e99136adb58
7
+ data.tar.gz: b6a295312c5826a622336d8a7113a5baece102ff958f6f503b0407c371c24c721f0e9d4cae73cbe749cc224338f64017ae3c508d3ee3a7857b5d782e85123542
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Podlove Web Player Rails
2
2
  [![Gem Version][gv img]][gv] [![Build Status][bs img]][bs] [![Code Climate][cc img]][cc] [![Dependency Status][ds img]][ds]
3
3
 
4
- Brings the [Podlove Web Player][pwp] goodness to Rails 3.
4
+ Brings the [Podlove Web Player][pwp] goodness to Rails.
5
5
 
6
6
  ## Installation ##
7
7
 
@@ -41,7 +41,7 @@ Feel free to open an issue ticket if you find something that could be improved.
41
41
  * If it's an issue pertaining the stylesheet or javascripts, please report it to the [podlove-web-player][pwpg] project.
42
42
  * If the stylesheet or javascripts are outdated, feel free to open an issue and prod me to get that thing updated. You could, of course, also fork the gem and send me an pull request with the update.
43
43
 
44
- [gv img]: https://badge.fury.io/rb/podlove-web-player-rails.png
44
+ [gv img]: https://badge.fury.io/rb/podlove-web-player-rails.png
45
45
  [gv]: https://rubygems.org/gems/podlove-web-player-rails
46
46
  [bs img]: https://travis-ci.org/coding-chimp/podlove-web-player-rails.png?branch=master
47
47
  [bs]: https://travis-ci.org/coding-chimp/podlove-web-player-rails
@@ -53,4 +53,4 @@ Feel free to open an issue ticket if you find something that could be improved.
53
53
  [pwp]: http://podlove.org/podlove-web-player/
54
54
  [pwpw]: http://wordpress.org/extend/plugins/podlove-web-player/faq/
55
55
  [doc]: http://rdoc.info/github/coding-chimp/podlove-web-player-rails/master/frames
56
- [pwpg]: https://github.com/podlove/podlove-web-player
56
+ [pwpg]: https://github.com/podlove/podlove-web-player
@@ -1,6 +1,6 @@
1
1
  module PodloveWebPlayerRails
2
2
  # version of the gem
3
- VERSION = "1.2.2"
3
+ VERSION = "1.2.3"
4
4
  # version of the podlove web player
5
- PODLOVE_WEB_PLAYER_VERSION = "2.1.0"
5
+ PODLOVE_WEB_PLAYER_VERSION = "2.0.15"
6
6
  end
@@ -17,5 +17,5 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
- gem.add_dependency "railties", "~> 3.1"
20
+ gem.add_dependency "railties", ">= 3.2"
21
21
  end
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * ===========================================
3
- * Podlove Web Player v2.1.0
3
+ * Podlove Web Player v2.0.15
4
4
  * Licensed under The BSD 2-Clause License
5
5
  * http://opensource.org/licenses/BSD-2-Clause
6
6
  * ===========================================
@@ -178,1081 +178,1026 @@ p.show(k,c);k.click(function(){typeof p.click!="undefined"&&p.click(c);c.context
178
178
  (function(f){f.extend(mejs.MepDefaults,{postrollCloseText:mejs.i18n.t("Close")});f.extend(MediaElementPlayer.prototype,{buildpostroll:function(a,b,c){var d=this.container.find('link[rel="postroll"]').attr("href");if(typeof d!=="undefined"){a.postroll=f('<div class="mejs-postroll-layer mejs-layer"><a class="mejs-postroll-close" onclick="$(this).parent().hide();return false;">'+this.options.postrollCloseText+'</a><div class="mejs-postroll-layer-content"></div></div>').prependTo(c).hide();this.media.addEventListener("ended",
179
179
  function(){f.ajax({dataType:"html",url:d,success:function(e){c.find(".mejs-postroll-layer-content").html(e)}});a.postroll.show()},false)}}})})(mejs.$);
180
180
 
181
- /*jslint browser: true, plusplus: true, white: true, unparam: true */
181
+ /*jslint browser: true, plusplus: true, unparam: true, indent: 2 */
182
182
  /*global jQuery, console */
183
-
183
+ if (typeof String.prototype.trim !== 'function') {
184
+ String.prototype.trim = function () {
185
+ "use strict";
186
+ return this.replace(/^\s+|\s+$/g, '');
187
+ };
188
+ }
184
189
  (function ($) {
185
- 'use strict';
186
- var startAtTime = false,
187
- stopAtTime = false,
188
- // Keep all Players on site
189
- players = [],
190
- // Timecode as described in http://podlove.org/deep-link/
191
- // and http://www.w3.org/TR/media-frags/#fragment-dimensions
192
- timecodeRegExp = /(?:(\d+):)?(\d+):(\d+)(\.\d+)?([,\-](?:(\d+):)?(\d+):(\d+)(\.\d+)?)?/,
193
- ignoreHashChange = false,
194
- // all used functions
195
- zeroFill, generateTimecode, parseTimecode, checkCurrentURL, validateURL, setFragmentURL, updateChapterMarks, checkTime, addressCurrentTime, generateChapterTable, addBehavior;
196
-
197
- /**
198
- * return number as string lefthand filled with zeros
199
- * @param number number
200
- * @param width number
201
- * @return string
202
- **/
203
- zeroFill = function (number, width) {
204
- var s = number.toString();
205
- while (s.length < width) {
206
- s = "0" + s;
207
- }
208
- return s;
209
- };
210
-
211
- /**
212
- * accepts array with start and end time in seconds
213
- * returns timecode in deep-linking format
214
- * @param times array
215
- * @param forceHours bool (optional)
216
- * @return string
217
- **/
218
- $.generateTimecode = function (times, leadingZeros, forceHours) {
219
- function generatePart(time) {
220
- var part, hours, minutes, seconds, milliseconds;
221
- // prevent negative values from player
222
- if (!time || time <= 0) {
223
- return (leadingZeros || !time) ? (forceHours ? '00:00:00' : '00:00') : '--';
224
- }
225
-
226
- hours = Math.floor(time / 60 / 60);
227
- minutes = Math.floor(time / 60) % 60;
228
- seconds = Math.floor(time % 60) % 60;
229
- milliseconds = Math.floor(time % 1 * 1000);
230
-
231
- if (leadingZeros) {
232
- // required (minutes : seconds)
233
- part = zeroFill(minutes, 2) + ':' + zeroFill(seconds, 2);
234
- hours = zeroFill(hours, 2);
235
- hours = hours === '00' && !forceHours ? '' : hours + ':';
236
- milliseconds = milliseconds ? '.' + zeroFill(milliseconds, 3) : '';
237
- } else {
238
- part = hours ? zeroFill(minutes, 2) : minutes.toString();
239
- part += ':' + zeroFill(seconds, 2);
240
- hours = hours ? hours + ':' : '';
241
- milliseconds = milliseconds ? '.' + milliseconds : '';
242
- }
243
-
244
- return hours + part + milliseconds;
245
- }
246
-
247
- if (times[1] > 0 && times[1] < 9999999 && times[0] < times[1]) {
248
- return generatePart(times[0]) + ',' + generatePart(times[1]);
249
- }
250
-
251
- return generatePart(times[0]);
252
- };
253
- generateTimecode = $.generateTimecode;
254
-
255
- /**
256
- * parses time code into seconds
257
- * @param string timecode
258
- * @return number
259
- **/
260
- parseTimecode = function (timecode) {
261
- var parts, startTime = 0,
262
- endTime = 0;
263
-
264
- if (timecode) {
265
- parts = timecode.match(timecodeRegExp);
266
-
267
- if (parts && parts.length === 10) {
268
- // hours
269
- startTime += parts[1] ? parseInt(parts[1], 10) * 60 * 60 : 0;
270
- // minutes
271
- startTime += parseInt(parts[2], 10) * 60;
272
- // seconds
273
- startTime += parseInt(parts[3], 10);
274
- // milliseconds
275
- startTime += parts[4] ? parseFloat(parts[4]) : 0;
276
- // no negative time
277
- startTime = Math.max(startTime, 0);
278
-
279
- // if there only a startTime but no endTime
280
- if (parts[5] === undefined) {
281
- return [startTime, false];
282
- }
283
-
284
- // hours
285
- endTime += parts[6] ? parseInt(parts[6], 10) * 60 * 60 : 0;
286
- // minutes
287
- endTime += parseInt(parts[7], 10) * 60;
288
- // seconds
289
- endTime += parseInt(parts[8], 10);
290
- // milliseconds
291
- endTime += parts[9] ? parseFloat(parts[9]) : 0;
292
- // no negative time
293
- endTime = Math.max(endTime, 0);
294
-
295
- return (endTime > startTime) ? [startTime, endTime] : [startTime, false];
296
- }
297
- }
298
- return false;
299
- };
300
-
301
- checkCurrentURL = function () {
302
- var deepLink;
303
- deepLink = parseTimecode(window.location.href);
304
- if (deepLink !== false) {
305
- startAtTime = deepLink[0];
306
- stopAtTime = deepLink[1];
307
- }
308
- };
309
-
310
- validateURL = function (url) {
311
- //de comment this to validate URLs, if you want use relative paths leave it so.
312
- //var urlregex = /(^|\s)((https?:\/\/)?[\w\-]+(\.[\w\-]+)+\.?(:\d+)?(\/\S*)?)/gi;
313
- //url = url.match(urlregex);
314
- //return (url !== null) ? url[0] : url;
315
- return url.trim();
316
- };
317
-
318
- /**
319
- * add a string as hash in the adressbar
320
- * @param string fragment
321
- **/
322
- setFragmentURL = function (fragment) {
323
- window.location.hash = fragment;
324
- };
325
-
326
- /**
327
- * update the chapter list when the data is loaded
328
- * @param object player
329
- * @param object marks
330
- **/
331
- updateChapterMarks = function (player, marks) {
332
- var coverimg = marks.closest('.podlovewebplayer_wrapper').find('.coverimg');
333
- marks.each(function () {
334
- var isBuffered, chapterimg = null,
335
- mark = $(this),
336
- startTime = mark.data('start'),
337
- endTime = mark.data('end'),
338
- isEnabled = mark.data('enabled'),
339
- isActive = player.currentTime > startTime - 0.3 &&
340
- player.currentTime <= endTime;
341
- // prevent timing errors
342
- if (player.buffered.length > 0) {
343
- isBuffered = player.buffered.end(0) > startTime;
344
- }
345
- if (isActive) {
346
- chapterimg = validateURL(mark.data('img'));
347
- if ((chapterimg !== null) && (mark.hasClass('active'))) {
348
- if ((coverimg.attr('src') !== chapterimg) && (chapterimg.length > 5)) {
349
- coverimg.attr('src', chapterimg);
350
- }
351
- } else {
352
- if (coverimg.attr('src') !== coverimg.data('img')) {
353
- coverimg.attr('src', coverimg.data('img'));
354
- }
355
- }
356
- mark.addClass('active').siblings().removeClass('active');
357
- }
358
- if (!isEnabled && isBuffered) {
359
- $(mark).data('enabled', true).addClass('loaded').find('a[rel=player]').removeClass('disabled');
360
- }
361
- });
362
- };
363
-
364
- checkTime = function (e) {
365
- if (players.length > 1) {
366
- return;
367
- }
368
- var player = e.data.player;
369
- if (startAtTime !== false &&
370
- //Kinda hackish: Make sure that the timejump is at least 1 second (fix for OGG/Firefox)
371
- (player.lastCheck === undefined || Math.abs(startAtTime - player.lastCheck) > 1)) {
372
- player.setCurrentTime(startAtTime);
373
- player.lastCheck = startAtTime;
374
- startAtTime = false;
375
- }
376
- if (stopAtTime !== false && player.currentTime >= stopAtTime) {
377
- player.pause();
378
- stopAtTime = false;
379
- }
380
- };
381
-
382
- addressCurrentTime = function (e) {
383
- var fragment;
384
- if (players.length === 1) {
385
- fragment = 't=' + generateTimecode([e.data.player.currentTime]);
386
- setFragmentURL(fragment);
387
- }
388
- };
389
-
390
- /**
391
- * Given a list of chapters, this function creates the chapter table for the player.
392
- */
393
- generateChapterTable = function (params) {
394
- var div, table, tbody, tempchapters, maxchapterstart, line, tc, chaptitle, next, chapterImages, rowDummy, i, scroll = '';
395
- if (params.chapterHeight !== "") {
396
- if (typeof parseInt(params.chapterHeight,10) === 'number') {
397
- scroll = 'style="overflow-y: auto; max-height: ' + parseInt(params.chapterHeight, 10) + 'px;"';
398
- }
399
- }
400
- div = $('<div class="podlovewebplayer_chapterbox showonplay" ' + scroll + '><table><caption>Podcast Chapters</caption><thead><tr><th scope="col">Chapter Number</th><th scope="col">Start time</th><th scope="col">Title</th><th scope="col">Duration</th></tr></thead><tbody></tbody></table></div>');
401
- table = div.children('table');
402
- tbody = table.children('tbody');
403
-
404
- if ((params.chaptersVisible === 'true') || (params.chaptersVisible === true)) {
405
- div.addClass('active');
406
- }
407
-
408
- table.addClass('podlovewebplayer_chapters');
409
- if (params.chapterlinks !== 'false') {
410
- table.addClass('linked linked_' + params.chapterlinks);
411
- }
412
-
413
- //prepare row data
414
- tempchapters = params.chapters;
415
- maxchapterstart = 0;
416
-
417
- //first round: kill empty rows and build structured object
418
- if (typeof params.chapters === 'string') {
419
- tempchapters = [];
420
- $.each(params.chapters.split("\n"), function (i, chapter) {
421
-
422
- //exit early if this line contains nothing but whitespace
423
- if (!/\S/.test(chapter)) {
424
- return;
425
- }
426
-
427
- //extract the timestamp
428
- line = $.trim(chapter);
429
- tc = parseTimecode(line.substring(0, line.indexOf(' ')));
430
- chaptitle = $.trim(line.substring(line.indexOf(' ')));
431
- tempchapters.push({
432
- start: tc[0],
433
- code: chaptitle
434
- });
435
- });
436
- } else {
437
- // assume array of objects
438
- $.each(tempchapters, function (key, value) {
439
- value.code = value.title;
440
- if (typeof value.start === 'string') {
441
- value.start = parseTimecode(value.start)[0];
442
- }
443
- });
444
- }
445
-
446
- // order is not guaranteed: http://podlove.org/simple-chapters/
447
- tempchapters = tempchapters.sort(function (a, b) {
448
- return a.start - b.start;
449
- });
450
-
451
- //second round: collect more information
452
- maxchapterstart = Math.max.apply(Math,
453
- $.map(tempchapters, function (value, i) {
454
- next = tempchapters[i + 1];
455
-
456
- // we use `this.end` to quickly calculate the duration in the next round
457
- if (next) {
458
- value.end = next.start;
459
- }
460
-
461
- // we need this data for proper formatting
462
- return value.start;
463
- }));
464
-
465
-
466
- //this is a "template" for each chapter row
467
- chapterImages = false;
468
- for (i = 0; i < tempchapters.length; i++) {
469
- if ((tempchapters[i].image !== "") && (tempchapters[i].image !== undefined)) {
470
- chapterImages = true;
471
- }
472
- }
473
- if (chapterImages) {
474
- rowDummy = $('<tr class="chaptertr" data-start="" data-end="" data-img=""><td class="starttime"><span></span></td><td class="chapterimage"></td><td class="chaptername"></td><td class="timecode">\n<span></span>\n</td>\n</tr>');
475
- } else {
476
- rowDummy = $('<tr class="chaptertr" data-start="" data-end="" data-img=""><td class="starttime"><span></span></td><td class="chaptername"></td><td class="timecode">\n<span></span>\n</td>\n</tr>');
477
- }
478
-
479
- //third round: build actual dom table
480
- $.each(tempchapters, function (i) {
481
- var finalchapter = !tempchapters[i + 1],
482
- duration = Math.round(this.end - this.start),
483
- forceHours,
484
- row = rowDummy.clone();
485
-
486
- //make sure the duration for all chapters are equally formatted
487
- if (!finalchapter) {
488
- this.duration = generateTimecode([duration], false);
489
- } else {
490
- if (params.duration === 0) {
491
- this.end = 9999999999;
492
- this.duration = '…';
493
- } else {
494
- this.end = params.duration;
495
- this.duration = generateTimecode([Math.round(this.end - this.start)], false);
496
- }
497
- }
498
-
499
-
500
- if (i % 2) {
501
- row.addClass('oddchapter');
502
- }
503
-
504
- //deeplink, start and end
505
- row.attr({
506
- 'data-start': this.start,
507
- 'data-end': this.end,
508
- 'data-img': (this.image !== undefined) ? this.image : ''
509
- });
510
-
511
- //if there is a chapter that starts after an hour, force '00:' on all previous chapters
512
- forceHours = (maxchapterstart >= 3600);
513
-
514
- //insert the chapter data
515
- row.find('.starttime > span').text(generateTimecode([Math.round(this.start)], true, forceHours));
516
- if (this.href !== undefined) {
517
- if (this.href !== "") {
518
- row.find('.chaptername').html('<span>' + this.code + '</span>' + ' <a href="' + this.href + '"></a>');
519
- }
520
- } else {
521
- row.find('.chaptername').html('<span>' + this.code + '</span>');
522
- }
523
- row.find('.timecode > span').html('<span>' + this.duration + '</span>');
524
- if (chapterImages) {
525
- if (this.image !== undefined) {
526
- if (this.image !== "") {
527
- row.find('.chapterimage').html('<img src="' + this.image + '"/>');
528
- }
529
- }
530
- }
531
-
532
- row.appendTo(tbody);
533
- });
534
- return div;
535
- };
536
-
537
- /**
538
- * add chapter behavior and deeplinking: skip to referenced
539
- * time position & write current time into address
540
- * @param player object
541
- */
542
-
543
- addBehavior = function (player, params, wrapper) {
544
- var jqPlayer = $(player),
545
- layoutedPlayer = jqPlayer,
546
- canplay = false,
547
- metainfo,
548
- summary,
549
- podlovewebplayer_timecontrol,
550
- podlovewebplayer_sharebuttons,
551
- podlovewebplayer_downloadbuttons,
552
- chapterdiv,
553
- list,
554
- marks;
555
-
556
- /**
557
- * The `player` is an interface. It provides the play and pause functionality. The
558
- * `layoutedPlayer` on the other hand is a DOM element. In native mode, these two
559
- * are one and the same object. In Flash though the interface is a plain JS object.
560
- */
561
-
562
- if (players.length === 1) {
563
- // check if deeplink is set
564
- checkCurrentURL();
565
- }
566
-
567
- // get things straight for flash fallback
568
- if (player.pluginType === 'flash') {
569
- layoutedPlayer = $('#mep_' + player.id.substring(9));
570
- console.log(layoutedPlayer);
571
- }
572
-
573
- // cache some jQ objects
574
- metainfo = wrapper.find('.podlovewebplayer_meta');
575
- summary = wrapper.find('.summary');
576
- podlovewebplayer_timecontrol = wrapper.find('.podlovewebplayer_timecontrol');
577
- podlovewebplayer_sharebuttons = wrapper.find('.podlovewebplayer_sharebuttons');
578
- podlovewebplayer_downloadbuttons = wrapper.find('.podlovewebplayer_downloadbuttons');
579
- chapterdiv = wrapper.find('.podlovewebplayer_chapterbox');
580
- list = wrapper.find('table');
581
- marks = list.find('tr');
582
-
583
- // fix height of summary for better toggability
584
- summary.each(function () {
585
- $(this).data('height', $(this).height() + 10);
586
- if (!$(this).hasClass('active')) {
587
- $(this).height('0px');
588
- } else {
589
- $(this).height($(this).find('div.summarydiv').height() + 10 + 'px');
590
- }
591
- });
592
-
593
- chapterdiv.each(function () {
594
- $(this).data('height', $(this).find('.podlovewebplayer_chapters').height());
595
- if (!$(this).hasClass('active')) {
596
- $(this).height('0px');
597
- } else {
598
- $(this).height($(this).find('.podlovewebplayer_chapters').height() + 'px');
599
- }
600
- });
601
-
602
- if (metainfo.length === 1) {
603
-
604
- metainfo.find('a.infowindow').click(function () {
605
- summary.toggleClass('active');
606
- if (summary.hasClass('active')) {
607
- summary.height(summary.find('div.summarydiv').height() + 10 + 'px');
608
- } else {
609
- summary.height('0px');
610
- }
611
- return false;
612
- });
613
-
614
- metainfo.find('a.showcontrols').on('click', function () {
615
- podlovewebplayer_timecontrol.toggleClass('active');
616
- if (podlovewebplayer_sharebuttons !== undefined) {
617
- if (podlovewebplayer_sharebuttons.hasClass('active')) {
618
- podlovewebplayer_sharebuttons.removeClass('active');
619
- } else if (podlovewebplayer_downloadbuttons.hasClass('active')) {
620
- podlovewebplayer_downloadbuttons.removeClass('active');
621
- }
622
- }
623
- return false;
624
- });
625
-
626
- metainfo.find('a.showsharebuttons').on('click', function () {
627
- podlovewebplayer_sharebuttons.toggleClass('active');
628
- if (podlovewebplayer_timecontrol.hasClass('active')) {
629
- podlovewebplayer_timecontrol.removeClass('active');
630
- } else if (podlovewebplayer_downloadbuttons.hasClass('active')) {
631
- podlovewebplayer_downloadbuttons.removeClass('active');
632
- }
633
- return false;
634
- });
635
-
636
- metainfo.find('a.showdownloadbuttons').on('click', function () {
637
- podlovewebplayer_downloadbuttons.toggleClass('active');
638
- if (podlovewebplayer_timecontrol.hasClass('active')) {
639
- podlovewebplayer_timecontrol.removeClass('active');
640
- } else if (podlovewebplayer_sharebuttons.hasClass('active')) {
641
- podlovewebplayer_sharebuttons.removeClass('active');
642
- }
643
- return false;
644
- });
645
-
646
- metainfo.find('.bigplay').on('click', function () {
647
- if ($(this).hasClass('bigplay')) {
648
- var playButton = $(this).parent().find('.bigplay');
649
-
650
- if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
651
- if (player.paused) {
652
- playButton.addClass('playing');
653
- player.play();
654
- } else {
655
- playButton.removeClass('playing');
656
- player.pause();
657
- }
658
- } else {
659
- if (!playButton.hasClass('playing')) {
660
- playButton.addClass('playing');
661
- $(this).parent().parent().find('.mejs-time-buffering').show();
662
- }
663
- // flash fallback needs additional pause
664
- if (player.pluginType === 'flash') {
665
- player.pause();
666
- }
667
- player.play();
668
- }
669
- }
670
- return false;
671
- });
672
-
673
- wrapper.find('.chaptertoggle').unbind('click').click(function () {
674
- wrapper.find('.podlovewebplayer_chapterbox').toggleClass('active');
675
- if (wrapper.find('.podlovewebplayer_chapterbox').hasClass('active')) {
676
- wrapper.find('.podlovewebplayer_chapterbox').height(parseInt(wrapper.find('.podlovewebplayer_chapterbox').data('height'), 10) + 2 + 'px');
677
- } else {
678
- wrapper.find('.podlovewebplayer_chapterbox').height('0px');
679
- }
680
- return false;
681
- });
682
-
683
- wrapper.find('.prevbutton').click(function () {
684
- if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
685
- if (player.currentTime > chapterdiv.find('.active').data('start') + 10) {
686
- player.setCurrentTime(chapterdiv.find('.active').data('start'));
687
- } else {
688
- player.setCurrentTime(chapterdiv.find('.active').prev().data('start'));
689
- }
690
- } else {
691
- player.play();
692
- }
693
- return false;
694
- });
695
-
696
- wrapper.find('.nextbutton').click(function () {
697
- if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
698
- player.setCurrentTime(chapterdiv.find('.active').next().data('start'));
699
- } else {
700
- player.play();
701
- }
702
- return false;
703
- });
704
-
705
- wrapper.find('.rewindbutton').click(function () {
706
- if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
707
- player.setCurrentTime(player.currentTime - 30);
708
- } else {
709
- player.play();
710
- }
711
- return false;
712
- });
713
-
714
- wrapper.find('.forwardbutton').click(function () {
715
- if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
716
- player.setCurrentTime(player.currentTime + 30);
717
- } else {
718
- player.play();
719
- }
720
- return false;
721
- });
722
-
723
- wrapper.find('.currentbutton').click(function () {
724
- window.prompt('This URL directly points to this episode', $(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href'));
725
- return false;
726
- });
727
-
728
- wrapper.find('.tweetbutton').click(function () {
729
- window.open('https://twitter.com/share?text=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&url=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'tweet it', 'width=550,height=420,resizable=yes');
730
- return false;
731
- });
732
-
733
- wrapper.find('.fbsharebutton').click(function () {
734
- window.open('http://www.facebook.com/share.php?t=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&u=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'share it', 'width=550,height=340,resizable=yes');
735
- return false;
736
- });
737
-
738
- wrapper.find('.gplusbutton').click(function () {
739
- window.open('https://plus.google.com/share?title=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&url=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'plus it', 'width=550,height=420,resizable=yes');
740
- return false;
741
- });
742
-
743
- wrapper.find('.adnbutton').click(function () {
744
- window.open('https://alpha.app.net/intent/post?text=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '%20' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'plus it', 'width=550,height=420,resizable=yes');
745
- return false;
746
- });
747
-
748
- wrapper.find('.mailbutton').click(function () {
749
- window.location = 'mailto:?subject=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&body=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '%20%3C' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')) + '%3E';
750
- return false;
751
- });
752
-
753
- wrapper.find('.fileselect').change(function () {
754
- var dlurl, dlname;
755
- $(this).parent().find(".fileselect option:selected").each(function () {
756
- dlurl = $(this).data('dlurl');
757
- });
758
- $(this).parent().find(".downloadbutton").each(function () {
759
- dlname = dlurl.split('/');
760
- dlname = dlname[dlname.length - 1];
761
- $(this).attr('href', dlurl);
762
- $(this).attr('download', dlname);
763
- });
764
- return false;
765
- });
766
-
767
- wrapper.find('.openfilebutton').click(function () {
768
- $(this).parent().find(".fileselect option:selected").each(function () {
769
- window.open($(this).data('url'), 'Podlove Popup', 'width=550,height=420,resizable=yes');
770
- });
771
- return false;
772
- });
773
-
774
- wrapper.find('.fileinfobutton').click(function () {
775
- $(this).parent().find(".fileselect option:selected").each(function () {
776
- window.prompt('file URL:', $(this).val());
777
- });
778
- return false;
779
- });
780
- }
781
-
782
- // chapters list
783
- list
784
- .show()
785
- .delegate('.chaptertr', 'click', function (e) {
786
- if ($(this).closest('table').hasClass('linked_all') || $(this).closest('tr').hasClass('loaded')) {
787
- e.preventDefault();
788
- var mark = $(this).closest('tr'),
789
- startTime = mark.data('start');
790
- //endTime = mark.data('end');
791
-
792
- // If there is only one player also set deepLink
793
- if (players.length === 1) {
794
- // setFragmentURL('t=' + generateTimecode([startTime, endTime]));
795
- setFragmentURL('t=' + generateTimecode([startTime]));
796
- } else {
797
- if (canplay) {
798
- // Basic Chapter Mark function (without deeplinking)
799
- player.setCurrentTime(startTime);
800
- } else {
801
- jqPlayer.one('canplay', function () {
802
- player.setCurrentTime(startTime);
803
- });
804
- }
805
- }
806
-
807
- // flash fallback needs additional pause
808
- if (player.pluginType === 'flash') {
809
- player.pause();
810
- }
811
- player.play();
812
- }
813
- return false;
814
- });
815
- list
816
- .show()
817
- .delegate('.chaptertr a', 'click', function (e) {
818
- if ($(this).closest('table').hasClass('linked_all') || $(this).closest('td').hasClass('loaded')) {
819
- e.preventDefault();
820
- window.open($(this)[0].href, '_blank');
821
- }
822
- return false;
823
- });
824
-
825
- // wait for the player or you'll get DOM EXCEPTIONS
826
- // And just listen once because of a special behaviour in firefox
827
- // --> https://bugzilla.mozilla.org/show_bug.cgi?id=664842
828
- jqPlayer.one('canplay', function () {
829
- canplay = true;
830
-
831
- // add duration of final chapter
832
- if (player.duration) {
833
- marks.find('.timecode code').eq(-1).each(function () {
834
- var start, end;
835
- start = Math.floor($(this).closest('tr').data('start'));
836
- end = Math.floor(player.duration);
837
- $(this).text(generateTimecode([end - start]));
838
- });
839
- }
840
-
841
- // add Deeplink Behavior if there is only one player on the site
842
- if (players.length === 1) {
843
- jqPlayer.bind('play timeupdate', {
844
- player: player
845
- }, checkTime)
846
- .bind('pause', {
847
- player: player
848
- }, addressCurrentTime);
849
- // disabled 'cause it overrides chapter clicks
850
- // bind seeked to addressCurrentTime
851
-
852
- checkCurrentURL();
853
-
854
- // handle browser history navigation
855
- jQuery(window).bind('hashchange onpopstate', function (e) {
856
- if (!ignoreHashChange) {
857
- checkCurrentURL();
858
- }
859
- ignoreHashChange = false;
860
- });
861
- }
862
- });
863
-
864
- // always update Chaptermarks though
865
- jqPlayer
866
- .on('timeupdate', function () {
867
- updateChapterMarks(player, marks);
868
- })
869
- // update play/pause status
870
- .on('play playing', function () {
871
- if (!player.persistingTimer) {
872
- player.persistingTimer = window.setInterval(function () {
873
- if (players.length === 1) {
874
- ignoreHashChange = true;
875
- window.location.replace('#t=' + generateTimecode([player.currentTime, false]));
876
- }
877
- localStorage['podloveWebPlayerTime-' + params.permalink] = player.currentTime;
878
- }, 5000);
879
- }
880
- list.find('.paused').removeClass('paused');
881
- if (metainfo.length === 1) {
882
- metainfo.find('.bigplay').addClass('playing');
883
- }
884
- })
885
- .on('pause', function () {
886
- window.clearInterval(player.persistingTimer);
887
- player.persistingTimer = null;
888
-
889
- if (metainfo.length === 1) {
890
- metainfo.find('.bigplay').removeClass('playing');
891
- }
892
- });
893
- };
894
-
895
- $.fn.podlovewebplayer = function (options) {
896
-
897
- // MEJS options default values
898
- var mejsoptions = {
899
- defaultVideoWidth: 480,
900
- defaultVideoHeight: 270,
901
- videoWidth: -1,
902
- videoHeight: -1,
903
- audioWidth: -1,
904
- audioHeight: 30,
905
- startVolume: 0.8,
906
- loop: false,
907
- enableAutosize: true,
908
- features: ['playpause', 'current', 'progress', 'duration', 'tracks', 'volume', 'fullscreen'],
909
- alwaysShowControls: false,
910
- iPadUseNativeControls: false,
911
- iPhoneUseNativeControls: false,
912
- AndroidUseNativeControls: false,
913
- alwaysShowHours: false,
914
- showTimecodeFrameCount: false,
915
- framesPerSecond: 25,
916
- enableKeyboard: true,
917
- pauseOtherPlayers: true,
918
- duration: false,
919
- plugins: ['flash', 'silverlight'],
920
- pluginPath: './static/',
921
- flashName: 'flashmediaelement.swf',
922
- silverlightName: 'silverlightmediaelement.xap'
923
- },
924
-
925
- // Additional parameters default values
926
- params = $.extend({}, {
927
- chapterlinks: 'all',
928
- width: '100%',
929
- duration: false,
930
- chaptersVisible: false,
931
- timecontrolsVisible: false,
932
- sharebuttonsVisible: false,
933
- downloadbuttonsVisible: false,
934
- summaryVisible: false,
935
- hidetimebutton: false,
936
- hidedownloadbutton: false,
937
- hidesharebutton: false,
938
- sharewholeepisode: false,
939
- sources: []
940
- }, options);
941
-
942
- // turn each player in the current set into a Podlove Web Player
943
- return this.each(function (index, player) {
944
-
945
- var richplayer = false,
946
- haschapters = false,
947
- hiddenTab = false,
948
- i = 0,
949
- secArray,
950
- orig,
951
- deepLink,
952
- wrapper,
953
- summaryActive,
954
- timecontrolsActive,
955
- sharebuttonsActive,
956
- downloadbuttonsActive,
957
- size,
958
- name,
959
- downloadname,
960
- selectform,
961
- storageKey;
962
-
963
- //fine tuning params
964
- if (params.width.toLowerCase() === 'auto') {
965
- params.width = '100%';
966
- } else {
967
- params.width = params.width.replace('px', '');
968
- }
969
-
970
- //audio params
971
- if (player.tagName === 'AUDIO') {
972
- if (params.audioWidth !== undefined) {
973
- params.width = params.audioWidth;
974
- }
975
- mejsoptions.audioWidth = params.width;
976
-
977
- //kill fullscreen button
978
- $.each(mejsoptions.features, function (i) {
979
- if (this === 'fullscreen') {
980
- mejsoptions.features.splice(i, 1);
981
- }
982
- });
983
-
984
- //video params
985
- } else if (player.tagName === 'VIDEO') {
986
-
987
- if (params.height !== undefined) {
988
- mejsoptions.videoWidth = params.width;
989
- mejsoptions.videoHeight = params.height;
990
- }
991
-
992
- if ($(player).attr('width') !== undefined) {
993
- params.width = $(player).attr('width');
994
- }
995
- }
996
-
997
- //duration can be given in seconds or in NPT format
998
- if (params.duration && params.duration !== parseInt(params.duration, 10)) {
999
- secArray = parseTimecode(params.duration);
1000
- params.duration = secArray[0];
1001
- }
1002
-
1003
- //Overwrite MEJS default values with actual data
1004
- $.each(mejsoptions, function (key) {
1005
- if (params[key] !== undefined) {
1006
- mejsoptions[key] = params[key];
1007
- }
1008
- });
1009
-
1010
- //wrapper and init stuff
1011
- if (params.width.toString().trim() === parseInt(params.width, 10).toString().trim()) {
1012
- params.width = params.width.toString().trim() + 'px';
1013
- }
1014
-
1015
- orig = player;
1016
-
1017
- player = $(player).clone().wrap('<div class="podlovewebplayer_wrapper" style="width: ' + params.width + '"></div>')[0];
1018
- wrapper = $(player).parent();
1019
-
1020
- players.push(player);
1021
-
1022
- //add params from html fallback area and remove them from the DOM-tree
1023
- $(player).find('[data-pwp]').each(function () {
1024
- params[$(this).data('pwp')] = $(this).html();
1025
- $(this).remove();
1026
- });
1027
- //add params from audio and video elements
1028
- $(player).find('source').each(function () {
1029
- if (params.sources !== undefined) {
1030
- params.sources.push($(this).attr('src'));
1031
- } else {
1032
- params.sources[0] = $(this).attr('src');
1033
- }
1034
- });
1035
-
1036
- //build rich player with meta data
1037
- if (params.chapters !== undefined ||
1038
- params.title !== undefined ||
1039
- params.subtitle !== undefined ||
1040
- params.summary !== undefined ||
1041
- params.poster !== undefined ||
1042
- $(player).attr('poster') !== undefined) {
1043
-
1044
- //set status variable
1045
- richplayer = true;
1046
-
1047
- wrapper.addClass('podlovewebplayer_' + player.tagName.toLowerCase());
1048
-
1049
- if (player.tagName === "AUDIO") {
1050
-
1051
- //kill play/pause button from miniplayer
1052
- $.each(mejsoptions.features, function (i) {
1053
- if (this === 'playpause') {
1054
- mejsoptions.features.splice(i, 1);
1055
- }
1056
- });
1057
-
1058
- wrapper.prepend('<div class="podlovewebplayer_meta"></div>');
1059
-
1060
- wrapper.find('.podlovewebplayer_meta').prepend('<a class="bigplay" title="Play Episode" href="#"></a>');
1061
- if (params.poster !== undefined) {
1062
- wrapper.find('.podlovewebplayer_meta').append(
1063
- '<div class="coverart"><img class="coverimg" src="' + params.poster + '" data-img="' + params.poster + '" alt=""></div>');
1064
- }
1065
- if ($(player).attr('poster') !== undefined) {
1066
- wrapper.find('.podlovewebplayer_meta').append(
1067
- '<div class="coverart"><img src="' + $(player).attr('poster') + '" alt=""></div>');
1068
- }
1069
- }
1070
-
1071
- if (player.tagName === "VIDEO") {
1072
- wrapper.prepend('<div class="podlovewebplayer_top"></div>');
1073
- wrapper.append('<div class="podlovewebplayer_meta"></div>');
1074
- }
1075
-
1076
- if (params.title !== undefined) {
1077
- if (params.permalink !== undefined) {
1078
- wrapper.find('.podlovewebplayer_meta').append(
1079
- '<h3 class="episodetitle"><a href="' + params.permalink + '">' + params.title + '</a></h3>');
1080
- } else {
1081
- wrapper.find('.podlovewebplayer_meta').append(
1082
- '<h3 class="episodetitle">' + params.title + '</h3>');
1083
- }
1084
- }
1085
- if (params.subtitle !== undefined) {
1086
- wrapper.find('.podlovewebplayer_meta').append(
1087
- '<div class="subtitle">' + params.subtitle + '</div>');
1088
- } else {
1089
- if (params.title !== undefined) {
1090
- if ((params.title.length < 42) && (params.poster === undefined)) {
1091
- wrapper.addClass('podlovewebplayer_smallplayer');
1092
- }
1093
- }
1094
- wrapper.find('.podlovewebplayer_meta').append(
1095
- '<div class="subtitle"></div>');
1096
- }
1097
-
1098
- //always render toggler buttons wrapper
1099
- wrapper.find('.podlovewebplayer_meta').append('<div class="togglers"></div>');
1100
- wrapper.on('playerresize', function () {
1101
- wrapper.find('.podlovewebplayer_chapterbox').data('height', wrapper.find('.podlovewebplayer_chapters').height());
1102
- if (wrapper.find('.podlovewebplayer_chapterbox').hasClass('active')) {
1103
- wrapper.find('.podlovewebplayer_chapterbox').height(parseInt(wrapper.find('.podlovewebplayer_chapterbox').data('height'), 10) + 2 + 'px');
1104
- }
1105
- wrapper.find('.summary').data('height', wrapper.find('.summarydiv').height());
1106
- if (wrapper.find('.summary').hasClass('active')) {
1107
- wrapper.find('.summary').height(wrapper.find('.summarydiv').height() + 'px');
1108
- }
1109
- });
1110
-
1111
- if (params.summary !== undefined) {
1112
- summaryActive = "";
1113
- if (params.summaryVisible === true) {
1114
- summaryActive = " active";
1115
- }
1116
- wrapper.find('.togglers').append(
1117
- '<a href="#" class="infowindow infobuttons pwp-icon-info-circle" title="More information about this"></a>');
1118
- wrapper.find('.podlovewebplayer_meta').after(
1119
- '<div class="summary' + summaryActive + '"><div class="summarydiv">' + params.summary + '</div></div>');
1120
- }
1121
- if (params.chapters !== undefined) {
1122
- if (((params.chapters.length > 10) && (typeof params.chapters === 'string')) || ((params.chapters.length > 1) && (typeof params.chapters === 'object'))) {
1123
- wrapper.find('.togglers').append(
1124
- '<a href="#" class="chaptertoggle infobuttons pwp-icon-list-bullet" title="Show/hide chapters"></a>');
1125
- }
1126
- }
1127
- if (params.hidetimebutton !== true) {
1128
- wrapper.find('.togglers').append('<a href="#" class="showcontrols infobuttons pwp-icon-clock" title="Show/hide time navigation controls"></a>');
1129
- }
1130
- }
1131
-
1132
- timecontrolsActive = "";
1133
- if (params.timecontrolsVisible === true) {
1134
- timecontrolsActive = " active";
1135
- }
1136
- sharebuttonsActive = "";
1137
- if (params.sharebuttonsVisible === true) {
1138
- sharebuttonsActive = " active";
1139
- }
1140
- downloadbuttonsActive = "";
1141
- if (params.downloadbuttonsVisible === true) {
1142
- downloadbuttonsActive = " active";
1143
- }
1144
-
1145
- wrapper.append('<div class="podlovewebplayer_timecontrol podlovewebplayer_controlbox' + timecontrolsActive + '"></div>');
1146
-
1147
- if (params.chapters !== undefined) {
1148
- if (params.chapters.length > 10) {
1149
- wrapper.find('.podlovewebplayer_timecontrol').append('<a href="#" class="prevbutton infobuttons pwp-icon-to-start" title="Jump backward to previous chapter"></a><a href="#" class="nextbutton infobuttons pwp-icon-to-end" title="next chapter"></a>');
1150
- wrapper.find('.controlbox').append('<a href="#" class="prevbutton infobuttons pwp-icon-step-backward" title="previous chapter"></a><a href="#" class="nextbutton infobuttons pwp-icon-to-end" title="Jump to next chapter"></a>');
1151
- }
1152
- }
1153
- wrapper.find('.podlovewebplayer_timecontrol').append(
1154
- '<a href="#" class="rewindbutton infobuttons pwp-icon-fast-bw" title="Rewind 30 seconds"></a>');
1155
- wrapper.find('.podlovewebplayer_timecontrol').append('<a href="#" class="forwardbutton infobuttons pwp-icon-fast-fw" title="Fast forward 30 seconds"></a>');
1156
- if ((wrapper.closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href') !== undefined) && (params.hidesharebutton !== true)) {
1157
- wrapper.append('<div class="podlovewebplayer_sharebuttons podlovewebplayer_controlbox' + sharebuttonsActive + '"></div>');
1158
- wrapper.find('.togglers').append('<a href="#" class="showsharebuttons infobuttons pwp-icon-export" title="Show/hide sharing controls"></a>');
1159
- wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" class="currentbutton infobuttons pwp-icon-link" title="Get URL for this"></a>');
1160
- wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="tweetbutton infobuttons pwp-icon-twitter" title="Share this on Twitter"></a>');
1161
- wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="fbsharebutton infobuttons pwp-icon-facebook" title="Share this on Facebook"></a>');
1162
- wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="gplusbutton infobuttons pwp-icon-gplus" title="Share this on Google+"></a>');
1163
- wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="adnbutton infobuttons pwp-icon-appnet" title="Share this on App.net"></a>');
1164
- wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="mailbutton infobuttons pwp-icon-mail" title="Share this via e-mail"></a>');
1165
- }
1166
- if (((params.downloads !== undefined) || (params.sources !== undefined)) && (params.hidedownloadbutton !== true)) {
1167
- selectform = '<select name="downloads" class="fileselect" size="1" onchange="this.value=this.options[this.selectedIndex].value;">';
1168
- wrapper.append('<div class="podlovewebplayer_downloadbuttons podlovewebplayer_controlbox' + downloadbuttonsActive + '"></div>');
1169
- wrapper.find('.togglers').append('<a href="#" class="showdownloadbuttons infobuttons pwp-icon-download" title="Show/hide download bar"></a>');
1170
- if (params.downloads !== undefined) {
1171
- for (i = 0; i < params.downloads.length; i += 1) {
1172
- size = (parseInt(params.downloads[i].size, 10) < 1048704) ? Math.round(parseInt(params.downloads[i].size, 10) / 100) / 10 + 'kB' : Math.round(parseInt(params.downloads[i].size, 10) / 1000 / 100) / 10 + 'MB';
1173
- selectform += '<option value="' + params.downloads[i].url + '" data-url="' + params.downloads[i].url + '" data-dlurl="' + params.downloads[i].dlurl + '">' + params.downloads[i].name + ' (' + size + ')</option>';
1174
- }
1175
- } else {
1176
- for (i = 0; i < params.sources.length; i += 1) {
1177
- name = params.sources[i].split('.');
1178
- name = name[name.length - 1];
1179
- selectform += '<option value="' + params.sources[i] + '" data-url="' + params.sources[i] + '" data-dlurl="' + params.sources[i] + '">' + name + '</option>';
1180
- }
1181
- }
1182
-
1183
- selectform += '</select>';
1184
- wrapper.find('.podlovewebplayer_downloadbuttons').append(selectform);
1185
- if (params.downloads !== undefined) {
1186
- downloadname = params.downloads[0].url.split('/');
1187
- downloadname = downloadname[downloadname.length - 1];
1188
- wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="' + params.downloads[0].url + '" download="' + downloadname + '" class="downloadbutton infobuttons pwp-icon-download" title="Download"></a> ');
1189
- }
1190
- wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="#" class="openfilebutton infobuttons pwp-icon-link-ext" title="Open"></a> ');
1191
- wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="#" class="fileinfobutton infobuttons pwp-icon-info-circle" title="Info"></a> ');
1192
- }
1193
-
1194
- //build chapter table
1195
- if (params.chapters !== undefined) {
1196
- if (((params.chapters.length > 10) && (typeof params.chapters === 'string')) || ((params.chapters.length > 1) && (typeof params.chapters === 'object'))) {
1197
- haschapters = true;
1198
- generateChapterTable(params).appendTo(wrapper);
1199
- }
1200
- }
1201
-
1202
- if (richplayer || haschapters) {
1203
- wrapper.append('<div class="podlovewebplayer_tableend"></div>');
1204
- }
1205
-
1206
- // parse deeplink
1207
- deepLink = parseTimecode(window.location.href);
1208
- if (deepLink !== false && players.length === 1) {
1209
- if (document.hidden !== undefined) {
1210
- hiddenTab = document.hidden;
1211
- } else if (document.mozHidden !== undefined) {
1212
- hiddenTab = document.mozHidden;
1213
- } else if (document.msHidden !== undefined) {
1214
- hiddenTab = document.msHidden;
1215
- } else if (document.webkitHidden !== undefined) {
1216
- hiddenTab = document.webkitHidden;
1217
- }
1218
-
1219
- if (hiddenTab === true) {
1220
- $(player).attr({
1221
- preload: 'auto'
1222
- });
1223
- } else {
1224
- $(player).attr({
1225
- preload: 'auto',
1226
- autoplay: 'autoplay'
1227
- });
1228
- }
1229
- startAtTime = deepLink[0];
1230
- stopAtTime = deepLink[1];
1231
- } else if (params && params.permalink) {
1232
- storageKey = 'podloveWebPlayerTime-' + params.permalink;
1233
- if (localStorage[storageKey]) {
1234
- $(player).one('canplay', function () {
1235
- this.currentTime = +localStorage[storageKey];
1236
- });
1237
- }
1238
- }
1239
-
1240
- $(player).on('ended', function () {
1241
- localStorage.removeItem('podloveWebPlayerTime-' + params.permalink);
1242
- });
1243
-
1244
- // init MEJS to player
1245
- mejsoptions.success = function (player) {
1246
- addBehavior(player, params, wrapper);
1247
- if (deepLink !== false && players.length === 1) {
1248
- $('html, body').delay(150).animate({
1249
- scrollTop: $('.podlovewebplayer_wrapper:first').offset().top - 25
1250
- });
1251
- }
1252
- };
1253
-
1254
- $(orig).replaceWith(wrapper);
1255
- $(player).mediaelementplayer(mejsoptions);
1256
- });
1257
- };
1258
- }(jQuery));
190
+ 'use strict';
191
+ var startAtTime = false,
192
+ stopAtTime = false,
193
+ // Keep all Players on site
194
+ players = [],
195
+ // Timecode as described in http://podlove.org/deep-link/
196
+ // and http://www.w3.org/TR/media-frags/#fragment-dimensions
197
+ timecodeRegExp = /(?:(\d+):)?(\d+):(\d+)(\.\d+)?([,\-](?:(\d+):)?(\d+):(\d+)(\.\d+)?)?/,
198
+ ignoreHashChange = false,
199
+ // all used functions
200
+ zeroFill,
201
+ generateTimecode,
202
+ parseTimecode,
203
+ checkCurrentURL,
204
+ validateURL,
205
+ setFragmentURL,
206
+ updateChapterMarks,
207
+ checkTime,
208
+ addressCurrentTime,
209
+ generateChapterTable,
210
+ addBehavior,
211
+ handleCookies;
212
+
213
+ /**
214
+ * return number as string lefthand filled with zeros
215
+ * @param number number
216
+ * @param width number
217
+ * @return string
218
+ **/
219
+ zeroFill = function (number, width) {
220
+ var s = number.toString();
221
+ while (s.length < width) {
222
+ s = "0" + s;
223
+ }
224
+ return s;
225
+ };
226
+ /**
227
+ * accepts array with start and end time in seconds
228
+ * returns timecode in deep-linking format
229
+ * @param times array
230
+ * @param forceHours bool (optional)
231
+ * @return string
232
+ **/
233
+ $.generateTimecode = function (times, leadingZeros, forceHours) {
234
+ function generatePart(time) {
235
+ var part,
236
+ hours,
237
+ minutes,
238
+ seconds,
239
+ milliseconds;
240
+
241
+ // prevent negative values from player
242
+ if (!time || time <= 0) {
243
+ return (leadingZeros || !time) ? (forceHours ? '00:00:00' : '00:00') : '--';
244
+ }
245
+ hours = Math.floor(time / 60 / 60);
246
+ minutes = Math.floor(time / 60) % 60;
247
+ seconds = Math.floor(time % 60) % 60;
248
+ milliseconds = Math.floor(time % 1 * 1000);
249
+ if (leadingZeros) {
250
+ // required (minutes : seconds)
251
+ part = zeroFill(minutes, 2) + ':' + zeroFill(seconds, 2);
252
+ hours = zeroFill(hours, 2);
253
+ hours = hours === '00' && !forceHours ? '' : hours + ':';
254
+ milliseconds = milliseconds ? '.' + zeroFill(milliseconds, 3) : '';
255
+ } else {
256
+ part = hours ? zeroFill(minutes, 2) : minutes.toString();
257
+ part += ':' + zeroFill(seconds, 2);
258
+ hours = hours ? hours + ':' : '';
259
+ milliseconds = milliseconds ? '.' + milliseconds : '';
260
+ }
261
+ return hours + part + milliseconds;
262
+ }
263
+ if (times[1] > 0 && times[1] < 9999999 && times[0] < times[1]) {
264
+ return generatePart(times[0]) + ',' + generatePart(times[1]);
265
+ }
266
+ return generatePart(times[0]);
267
+ };
268
+ generateTimecode = $.generateTimecode;
269
+ /**
270
+ * parses time code into seconds
271
+ * @param string timecode
272
+ * @return number
273
+ **/
274
+ parseTimecode = function (timecode) {
275
+ var parts, startTime = 0,
276
+ endTime = 0;
277
+ if (timecode) {
278
+ parts = timecode.match(timecodeRegExp);
279
+ if (parts && parts.length === 10) {
280
+ // hours
281
+ startTime += parts[1] ? parseInt(parts[1], 10) * 60 * 60 : 0;
282
+ // minutes
283
+ startTime += parseInt(parts[2], 10) * 60;
284
+ // seconds
285
+ startTime += parseInt(parts[3], 10);
286
+ // milliseconds
287
+ startTime += parts[4] ? parseFloat(parts[4]) : 0;
288
+ // no negative time
289
+ startTime = Math.max(startTime, 0);
290
+ // if there only a startTime but no endTime
291
+ if (parts[5] === undefined) {
292
+ return [startTime, false];
293
+ }
294
+ // hours
295
+ endTime += parts[6] ? parseInt(parts[6], 10) * 60 * 60 : 0;
296
+ // minutes
297
+ endTime += parseInt(parts[7], 10) * 60;
298
+ // seconds
299
+ endTime += parseInt(parts[8], 10);
300
+ // milliseconds
301
+ endTime += parts[9] ? parseFloat(parts[9]) : 0;
302
+ // no negative time
303
+ endTime = Math.max(endTime, 0);
304
+ return (endTime > startTime) ? [startTime, endTime] : [startTime, false];
305
+ }
306
+ }
307
+ return false;
308
+ };
309
+ checkCurrentURL = function () {
310
+ var deepLink;
311
+ deepLink = parseTimecode(window.location.href);
312
+ if (deepLink !== false) {
313
+ startAtTime = deepLink[0];
314
+ stopAtTime = deepLink[1];
315
+ }
316
+ };
317
+ validateURL = function (url) {
318
+ //de comment this to validate URLs, if you want use relative paths leave it so.
319
+ //var urlregex = /(^|\s)((https?:\/\/)?[\w\-]+(\.[\w\-]+)+\.?(:\d+)?(\/\S*)?)/gi;
320
+ //url = url.match(urlregex);
321
+ //return (url !== null) ? url[0] : url;
322
+ return url.trim();
323
+ };
324
+ /**
325
+ * add a string as hash in the adressbar
326
+ * @param string fragment
327
+ **/
328
+ setFragmentURL = function (fragment) {
329
+ window.location.hash = fragment;
330
+ };
331
+ /**
332
+ * handle Cookies
333
+ **/
334
+ handleCookies = {
335
+ getItem: function (sKey) {
336
+ if (!sKey || !this.hasItem(sKey)) {
337
+ return null;
338
+ }
339
+ return window.unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + window.escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
340
+ },
341
+ setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
342
+ if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/.test(sKey)) {
343
+ return;
344
+ }
345
+ var sExpires = "";
346
+ if (vEnd) {
347
+ switch (typeof vEnd) {
348
+ case "number":
349
+ sExpires = "; max-age=" + vEnd;
350
+ break;
351
+ case "string":
352
+ sExpires = "; expires=" + vEnd;
353
+ break;
354
+ case "object":
355
+ if (vEnd.hasOwnProperty("toGMTString")) {
356
+ sExpires = "; expires=" + vEnd.toGMTString();
357
+ }
358
+ break;
359
+ }
360
+ }
361
+ document.cookie = window.escape(sKey) + "=" + window.escape(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
362
+ },
363
+ removeItem: function (sKey) {
364
+ if (!sKey || !this.hasItem(sKey)) {
365
+ return;
366
+ }
367
+ var oExpDate = new Date();
368
+ oExpDate.setDate(oExpDate.getDate() - 1);
369
+ document.cookie = window.escape(sKey) + "=; expires=" + oExpDate.toGMTString() + "; path=/";
370
+ },
371
+ hasItem: function (sKey) {
372
+ return (new RegExp("(?:^|;\\s*)" + window.escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
373
+ }
374
+ };
375
+ /**
376
+ * update the chapter list when the data is loaded
377
+ * @param object player
378
+ * @param object marks
379
+ **/
380
+ updateChapterMarks = function (player, marks) {
381
+ var coverimg = marks.closest('.podlovewebplayer_wrapper').find('.coverimg');
382
+ marks.each(function () {
383
+ var isBuffered, chapterimg = null,
384
+ mark = $(this),
385
+ startTime = mark.data('start'),
386
+ endTime = mark.data('end'),
387
+ isEnabled = mark.data('enabled'),
388
+ isActive = player.currentTime > startTime - 0.3 && player.currentTime <= endTime;
389
+ // prevent timing errors
390
+ if (player.buffered.length > 0) {
391
+ isBuffered = player.buffered.end(0) > startTime;
392
+ }
393
+ if (isActive) {
394
+ chapterimg = validateURL(mark.data('img'));
395
+ if ((chapterimg !== null) && (mark.hasClass('active'))) {
396
+ if ((coverimg.attr('src') !== chapterimg) && (chapterimg.length > 5)) {
397
+ coverimg.attr('src', chapterimg);
398
+ }
399
+ } else {
400
+ if (coverimg.attr('src') !== coverimg.data('img')) {
401
+ coverimg.attr('src', coverimg.data('img'));
402
+ }
403
+ }
404
+ mark.addClass('active').siblings().removeClass('active');
405
+ }
406
+ if (!isEnabled && isBuffered) {
407
+ $(mark).data('enabled', true).addClass('loaded').find('a[rel=player]').removeClass('disabled');
408
+ }
409
+ });
410
+ };
411
+ checkTime = function (e) {
412
+ if (players.length > 1) {
413
+ return;
414
+ }
415
+ var player = e.data.player;
416
+ //Kinda hackish: Make sure that the timejump is at least 1 second (fix for OGG/Firefox)
417
+ if (startAtTime !== false && (player.lastCheck === undefined || Math.abs(startAtTime - player.lastCheck) > 1)) {
418
+ player.setCurrentTime(startAtTime);
419
+ player.lastCheck = startAtTime;
420
+ startAtTime = false;
421
+ }
422
+ if (stopAtTime !== false && player.currentTime >= stopAtTime) {
423
+ player.pause();
424
+ stopAtTime = false;
425
+ }
426
+ };
427
+ addressCurrentTime = function (e) {
428
+ var fragment;
429
+ if (players.length === 1) {
430
+ fragment = 't=' + generateTimecode([e.data.player.currentTime]);
431
+ setFragmentURL(fragment);
432
+ }
433
+ };
434
+ /**
435
+ * Given a list of chapters, this function creates the chapter table for the player.
436
+ */
437
+ generateChapterTable = function (params) {
438
+ var div, table, tbody, tempchapters, maxchapterstart, line, tc, chaptitle, next, chapterImages, rowDummy, i, scroll = '';
439
+ if (params.chapterHeight !== "") {
440
+ if (typeof parseInt(params.chapterHeight, 10) === 'number') {
441
+ scroll = 'style="overflow-y: auto; max-height: ' + parseInt(params.chapterHeight, 10) + 'px;"';
442
+ }
443
+ }
444
+ div = $('<div class="podlovewebplayer_chapterbox showonplay" ' + scroll + '><table><caption>Podcast Chapters</caption><thead><tr><th scope="col">Chapter Number</th><th scope="col">Start time</th><th scope="col">Title</th><th scope="col">Duration</th></tr></thead><tbody></tbody></table></div>');
445
+ table = div.children('table');
446
+ tbody = table.children('tbody');
447
+ if ((params.chaptersVisible === 'true') || (params.chaptersVisible === true)) {
448
+ div.addClass('active');
449
+ }
450
+ table.addClass('podlovewebplayer_chapters');
451
+ if (params.chapterlinks !== 'false') {
452
+ table.addClass('linked linked_' + params.chapterlinks);
453
+ }
454
+ //prepare row data
455
+ tempchapters = params.chapters;
456
+ maxchapterstart = 0;
457
+ //first round: kill empty rows and build structured object
458
+ if (typeof params.chapters === 'string') {
459
+ tempchapters = [];
460
+ $.each(params.chapters.split("\n"), function (i, chapter) {
461
+ //exit early if this line contains nothing but whitespace
462
+ if (!/\S/.test(chapter)) {
463
+ return;
464
+ }
465
+ //extract the timestamp
466
+ line = $.trim(chapter);
467
+ tc = parseTimecode(line.substring(0, line.indexOf(' ')));
468
+ chaptitle = $.trim(line.substring(line.indexOf(' ')));
469
+ tempchapters.push({
470
+ start: tc[0],
471
+ code: chaptitle
472
+ });
473
+ });
474
+ } else {
475
+ // assume array of objects
476
+ $.each(tempchapters, function (key, value) {
477
+ value.code = value.title;
478
+ if (typeof value.start === 'string') {
479
+ value.start = parseTimecode(value.start)[0];
480
+ }
481
+ });
482
+ }
483
+ // order is not guaranteed: http://podlove.org/simple-chapters/
484
+ tempchapters = tempchapters.sort(function (a, b) {
485
+ return a.start - b.start;
486
+ });
487
+ //second round: collect more information
488
+ maxchapterstart = Math.max.apply(Math,
489
+ $.map(tempchapters, function (value, i) {
490
+ next = tempchapters[i + 1];
491
+ // we use `this.end` to quickly calculate the duration in the next round
492
+ if (next) {
493
+ value.end = next.start;
494
+ }
495
+ // we need this data for proper formatting
496
+ return value.start;
497
+ }));
498
+ //this is a "template" for each chapter row
499
+ chapterImages = false;
500
+ for (i = 0; i < tempchapters.length; i++) {
501
+ if ((tempchapters[i].image !== "") && (tempchapters[i].image !== undefined)) {
502
+ chapterImages = true;
503
+ }
504
+ }
505
+ if (chapterImages) {
506
+ rowDummy = $('<tr class="chaptertr" data-start="" data-end="" data-img=""><td class="starttime"><span></span></td><td class="chapterimage"></td><td class="chaptername"></td><td class="timecode">\n<span></span>\n</td>\n</tr>');
507
+ } else {
508
+ rowDummy = $('<tr class="chaptertr" data-start="" data-end="" data-img=""><td class="starttime"><span></span></td><td class="chaptername"></td><td class="timecode">\n<span></span>\n</td>\n</tr>');
509
+ }
510
+ //third round: build actual dom table
511
+ $.each(tempchapters, function (i) {
512
+ var finalchapter = !tempchapters[i + 1],
513
+ duration = Math.round(this.end - this.start),
514
+ forceHours,
515
+ row = rowDummy.clone();
516
+ //make sure the duration for all chapters are equally formatted
517
+ if (!finalchapter) {
518
+ this.duration = generateTimecode([duration], false);
519
+ } else {
520
+ if (params.duration === 0) {
521
+ this.end = 9999999999;
522
+ this.duration = '…';
523
+ } else {
524
+ this.end = params.duration;
525
+ this.duration = generateTimecode([Math.round(this.end - this.start)], false);
526
+ }
527
+ }
528
+ if (i % 2) {
529
+ row.addClass('oddchapter');
530
+ }
531
+ //deeplink, start and end
532
+ row.attr({
533
+ 'data-start': this.start,
534
+ 'data-end': this.end,
535
+ 'data-img': (this.image !== undefined) ? this.image : ''
536
+ });
537
+ //if there is a chapter that starts after an hour, force '00:' on all previous chapters
538
+ forceHours = (maxchapterstart >= 3600);
539
+ //insert the chapter data
540
+ row.find('.starttime > span').text(generateTimecode([Math.round(this.start)], true, forceHours));
541
+ if (this.href !== undefined) {
542
+ if (this.href !== "") {
543
+ row.find('.chaptername').html('<span>' + this.code + '</span>' + ' <a href="' + this.href + '"></a>');
544
+ } else {
545
+ row.find('.chaptername').html('<span>' + this.code + '</span>');
546
+ }
547
+ } else {
548
+ row.find('.chaptername').html('<span>' + this.code + '</span>');
549
+ }
550
+ row.find('.timecode > span').html('<span>' + this.duration + '</span>');
551
+ if (chapterImages) {
552
+ if (this.image !== undefined) {
553
+ if (this.image !== "") {
554
+ row.find('.chapterimage').html('<img src="' + this.image + '"/>');
555
+ }
556
+ }
557
+ }
558
+ row.appendTo(tbody);
559
+ });
560
+ return div;
561
+ };
562
+ /**
563
+ * add chapter behavior and deeplinking: skip to referenced
564
+ * time position & write current time into address
565
+ * @param player object
566
+ */
567
+ addBehavior = function (player, params, wrapper) {
568
+ var jqPlayer = $(player),
569
+ layoutedPlayer = jqPlayer,
570
+ canplay = false,
571
+ metainfo,
572
+ summary,
573
+ podlovewebplayer_timecontrol,
574
+ podlovewebplayer_sharebuttons,
575
+ podlovewebplayer_downloadbuttons,
576
+ chapterdiv,
577
+ list,
578
+ marks;
579
+ // expose the player interface
580
+ wrapper.data('podlovewebplayer', {
581
+ player: jqPlayer
582
+ });
583
+ // This might be a fix to some Firefox AAC issues.
584
+ jqPlayer.on('error', function () {
585
+ if ($(this).attr('src')) {
586
+ $(this).removeAttr('src');
587
+ } else {
588
+ $(this).children().first().remove();
589
+ }
590
+ });
591
+ /**
592
+ * The `player` is an interface. It provides the play and pause functionality. The
593
+ * `layoutedPlayer` on the other hand is a DOM element. In native mode, these two
594
+ * are one and the same object. In Flash though the interface is a plain JS object.
595
+ */
596
+ if (players.length === 1) {
597
+ // check if deeplink is set
598
+ checkCurrentURL();
599
+ }
600
+ // get things straight for flash fallback
601
+ if (player.pluginType === 'flash') {
602
+ layoutedPlayer = $('#mep_' + player.id.substring(9));
603
+ console.log(layoutedPlayer);
604
+ }
605
+ // cache some jQ objects
606
+ metainfo = wrapper.find('.podlovewebplayer_meta');
607
+ summary = wrapper.find('.summary');
608
+ podlovewebplayer_timecontrol = wrapper.find('.podlovewebplayer_timecontrol');
609
+ podlovewebplayer_sharebuttons = wrapper.find('.podlovewebplayer_sharebuttons');
610
+ podlovewebplayer_downloadbuttons = wrapper.find('.podlovewebplayer_downloadbuttons');
611
+ chapterdiv = wrapper.find('.podlovewebplayer_chapterbox');
612
+ list = wrapper.find('table');
613
+ marks = list.find('tr');
614
+ // fix height of summary for better toggability
615
+ summary.each(function () {
616
+ $(this).data('height', $(this).height() + 10);
617
+ if (!$(this).hasClass('active')) {
618
+ $(this).height('0px');
619
+ } else {
620
+ $(this).height($(this).find('div.summarydiv').height() + 10 + 'px');
621
+ }
622
+ });
623
+ chapterdiv.each(function () {
624
+ $(this).data('height', $(this).find('.podlovewebplayer_chapters').height());
625
+ if (!$(this).hasClass('active')) {
626
+ $(this).height('0px');
627
+ } else {
628
+ $(this).height($(this).find('.podlovewebplayer_chapters').height() + 'px');
629
+ }
630
+ });
631
+ if (metainfo.length === 1) {
632
+ metainfo.find('a.infowindow').click(function () {
633
+ summary.toggleClass('active');
634
+ if (summary.hasClass('active')) {
635
+ summary.height(summary.find('div.summarydiv').height() + 10 + 60 + 'px');
636
+ } else {
637
+ summary.css('height', '0px');
638
+ }
639
+ return false;
640
+ });
641
+ metainfo.find('a.showcontrols').on('click', function () {
642
+ podlovewebplayer_timecontrol.toggleClass('active');
643
+ if (podlovewebplayer_sharebuttons !== undefined) {
644
+ if (podlovewebplayer_sharebuttons.hasClass('active')) {
645
+ podlovewebplayer_sharebuttons.removeClass('active');
646
+ } else if (podlovewebplayer_downloadbuttons.hasClass('active')) {
647
+ podlovewebplayer_downloadbuttons.removeClass('active');
648
+ }
649
+ }
650
+ return false;
651
+ });
652
+ metainfo.find('a.showsharebuttons').on('click', function () {
653
+ podlovewebplayer_sharebuttons.toggleClass('active');
654
+ if (podlovewebplayer_timecontrol.hasClass('active')) {
655
+ podlovewebplayer_timecontrol.removeClass('active');
656
+ } else if (podlovewebplayer_downloadbuttons.hasClass('active')) {
657
+ podlovewebplayer_downloadbuttons.removeClass('active');
658
+ }
659
+ return false;
660
+ });
661
+ metainfo.find('a.showdownloadbuttons').on('click', function () {
662
+ podlovewebplayer_downloadbuttons.toggleClass('active');
663
+ if (podlovewebplayer_timecontrol.hasClass('active')) {
664
+ podlovewebplayer_timecontrol.removeClass('active');
665
+ } else if (podlovewebplayer_sharebuttons.hasClass('active')) {
666
+ podlovewebplayer_sharebuttons.removeClass('active');
667
+ }
668
+ return false;
669
+ });
670
+ metainfo.find('.bigplay').on('click', function () {
671
+ if ($(this).hasClass('bigplay')) {
672
+ var playButton = $(this).parent().find('.bigplay');
673
+ if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
674
+ if (player.paused) {
675
+ playButton.addClass('playing');
676
+ player.play();
677
+ } else {
678
+ playButton.removeClass('playing');
679
+ player.pause();
680
+ }
681
+ } else {
682
+ if (!playButton.hasClass('playing')) {
683
+ playButton.addClass('playing');
684
+ $(this).parent().parent().find('.mejs-time-buffering').show();
685
+ }
686
+ // flash fallback needs additional pause
687
+ if (player.pluginType === 'flash') {
688
+ player.pause();
689
+ }
690
+ player.play();
691
+ }
692
+ }
693
+ return false;
694
+ });
695
+ wrapper.find('.chaptertoggle').unbind('click').click(function () {
696
+ wrapper.find('.podlovewebplayer_chapterbox').toggleClass('active');
697
+ if (wrapper.find('.podlovewebplayer_chapterbox').hasClass('active')) {
698
+ wrapper.find('.podlovewebplayer_chapterbox').height(parseInt(wrapper.find('.podlovewebplayer_chapterbox').data('height'), 10) + 2 + 'px');
699
+ } else {
700
+ wrapper.find('.podlovewebplayer_chapterbox').height('0px');
701
+ }
702
+ return false;
703
+ });
704
+ wrapper.find('.prevbutton').click(function () {
705
+ if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
706
+ if (player.currentTime > chapterdiv.find('.active').data('start') + 10) {
707
+ player.setCurrentTime(chapterdiv.find('.active').data('start'));
708
+ } else {
709
+ player.setCurrentTime(chapterdiv.find('.active').prev().data('start'));
710
+ }
711
+ } else {
712
+ player.play();
713
+ }
714
+ return false;
715
+ });
716
+ wrapper.find('.nextbutton').click(function () {
717
+ if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
718
+ player.setCurrentTime(chapterdiv.find('.active').next().data('start'));
719
+ } else {
720
+ player.play();
721
+ }
722
+ return false;
723
+ });
724
+ wrapper.find('.rewindbutton').click(function () {
725
+ if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
726
+ player.setCurrentTime(player.currentTime - 30);
727
+ } else {
728
+ player.play();
729
+ }
730
+ return false;
731
+ });
732
+ wrapper.find('.forwardbutton').click(function () {
733
+ if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
734
+ player.setCurrentTime(player.currentTime + 30);
735
+ } else {
736
+ player.play();
737
+ }
738
+ return false;
739
+ });
740
+ wrapper.find('.currentbutton').click(function () {
741
+ window.prompt('This URL directly points to this episode', $(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href'));
742
+ return false;
743
+ });
744
+ wrapper.find('.tweetbutton').click(function () {
745
+ window.open('https://twitter.com/share?text=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&url=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'tweet it', 'width=550,height=420,resizable=yes');
746
+ return false;
747
+ });
748
+ wrapper.find('.fbsharebutton').click(function () {
749
+ window.open('http://www.facebook.com/share.php?t=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&u=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'share it', 'width=550,height=340,resizable=yes');
750
+ return false;
751
+ });
752
+ wrapper.find('.gplusbutton').click(function () {
753
+ window.open('https://plus.google.com/share?title=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&url=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'plus it', 'width=550,height=420,resizable=yes');
754
+ return false;
755
+ });
756
+ wrapper.find('.adnbutton').click(function () {
757
+ window.open('https://alpha.app.net/intent/post?text=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '%20' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'plus it', 'width=550,height=420,resizable=yes');
758
+ return false;
759
+ });
760
+ wrapper.find('.mailbutton').click(function () {
761
+ window.location = 'mailto:?subject=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&body=' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '%20%3C' + encodeURIComponent($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')) + '%3E';
762
+ return false;
763
+ });
764
+ wrapper.find('.fileselect').change(function () {
765
+ var dlurl, dlname;
766
+ $(this).parent().find(".fileselect option:selected").each(function () {
767
+ dlurl = $(this).data('dlurl');
768
+ });
769
+ $(this).parent().find(".downloadbutton").each(function () {
770
+ dlname = dlurl.split('/');
771
+ dlname = dlname[dlname.length - 1];
772
+ $(this).attr('href', dlurl);
773
+ $(this).attr('download', dlname);
774
+ });
775
+ return false;
776
+ });
777
+ wrapper.find('.openfilebutton').click(function () {
778
+ $(this).parent().find(".fileselect option:selected").each(function () {
779
+ window.open($(this).data('url'), 'Podlove Popup', 'width=550,height=420,resizable=yes');
780
+ });
781
+ return false;
782
+ });
783
+ wrapper.find('.fileinfobutton').click(function () {
784
+ $(this).parent().find(".fileselect option:selected").each(function () {
785
+ window.prompt('file URL:', $(this).val());
786
+ });
787
+ return false;
788
+ });
789
+ }
790
+ // chapters list
791
+ list
792
+ .show()
793
+ .delegate('.chaptertr', 'click', function (e) {
794
+ if ($(this).closest('table').hasClass('linked_all') || $(this).closest('tr').hasClass('loaded')) {
795
+ e.preventDefault();
796
+ var mark = $(this).closest('tr'),
797
+ startTime = mark.data('start');
798
+ //endTime = mark.data('end');
799
+ // If there is only one player also set deepLink
800
+ if (players.length === 1) {
801
+ // setFragmentURL('t=' + generateTimecode([startTime, endTime]));
802
+ setFragmentURL('t=' + generateTimecode([startTime]));
803
+ } else {
804
+ if (canplay) {
805
+ // Basic Chapter Mark function (without deeplinking)
806
+ player.setCurrentTime(startTime);
807
+ } else {
808
+ jqPlayer.one('canplay', function () {
809
+ player.setCurrentTime(startTime);
810
+ });
811
+ }
812
+ }
813
+ // flash fallback needs additional pause
814
+ if (player.pluginType === 'flash') {
815
+ player.pause();
816
+ }
817
+ player.play();
818
+ }
819
+ return false;
820
+ });
821
+ list
822
+ .show()
823
+ .delegate('.chaptertr a', 'click', function (e) {
824
+ if ($(this).closest('table').hasClass('linked_all') || $(this).closest('td').hasClass('loaded')) {
825
+ e.preventDefault();
826
+ window.open($(this)[0].href, '_blank');
827
+ }
828
+ return false;
829
+ });
830
+ // wait for the player or you'll get DOM EXCEPTIONS
831
+ // And just listen once because of a special behaviour in firefox
832
+ // --> https://bugzilla.mozilla.org/show_bug.cgi?id=664842
833
+ jqPlayer.one('canplay', function () {
834
+ canplay = true;
835
+ // add duration of final chapter
836
+ if (player.duration) {
837
+ marks.find('.timecode code').eq(-1).each(function () {
838
+ var start, end;
839
+ start = Math.floor($(this).closest('tr').data('start'));
840
+ end = Math.floor(player.duration);
841
+ $(this).text(generateTimecode([end - start]));
842
+ });
843
+ }
844
+ // add Deeplink Behavior if there is only one player on the site
845
+ if (players.length === 1) {
846
+ jqPlayer.bind('play timeupdate', {
847
+ player: player
848
+ }, checkTime)
849
+ .bind('pause', {
850
+ player: player
851
+ }, addressCurrentTime);
852
+ // disabled 'cause it overrides chapter clicks
853
+ // bind seeked to addressCurrentTime
854
+ checkCurrentURL();
855
+ // handle browser history navigation
856
+ jQuery(window).bind('hashchange onpopstate', function (e) {
857
+ if (!ignoreHashChange) {
858
+ checkCurrentURL();
859
+ }
860
+ ignoreHashChange = false;
861
+ });
862
+ }
863
+ });
864
+ // always update Chaptermarks though
865
+ jqPlayer
866
+ .on('timeupdate', function () {
867
+ updateChapterMarks(player, marks);
868
+ })
869
+ // update play/pause status
870
+ .on('play playing', function () {
871
+ if (!player.persistingTimer) {
872
+ player.persistingTimer = window.setInterval(function () {
873
+ if (players.length === 1) {
874
+ ignoreHashChange = true;
875
+ window.location.replace('#t=' + generateTimecode([player.currentTime, false]));
876
+ }
877
+ handleCookies.setItem('podloveWebPlayerTime-' + params.permalink, player.currentTime);
878
+ }, 5000);
879
+ }
880
+ list.find('.paused').removeClass('paused');
881
+ if (metainfo.length === 1) {
882
+ metainfo.find('.bigplay').addClass('playing');
883
+ }
884
+ })
885
+ .on('pause', function () {
886
+ window.clearInterval(player.persistingTimer);
887
+ player.persistingTimer = null;
888
+ if (metainfo.length === 1) {
889
+ metainfo.find('.bigplay').removeClass('playing');
890
+ }
891
+ });
892
+ };
893
+ $.fn.podlovewebplayer = function (options) {
894
+ // MEJS options default values
895
+ var mejsoptions = {
896
+ defaultVideoWidth: 480,
897
+ defaultVideoHeight: 270,
898
+ videoWidth: -1,
899
+ videoHeight: -1,
900
+ audioWidth: -1,
901
+ audioHeight: 30,
902
+ startVolume: 0.8,
903
+ loop: false,
904
+ enableAutosize: true,
905
+ features: ['playpause', 'current', 'progress', 'duration', 'tracks', 'volume', 'fullscreen'],
906
+ alwaysShowControls: false,
907
+ iPadUseNativeControls: false,
908
+ iPhoneUseNativeControls: false,
909
+ AndroidUseNativeControls: false,
910
+ alwaysShowHours: false,
911
+ showTimecodeFrameCount: false,
912
+ framesPerSecond: 25,
913
+ enableKeyboard: true,
914
+ pauseOtherPlayers: true,
915
+ duration: false,
916
+ plugins: ['flash', 'silverlight'],
917
+ pluginPath: './static/',
918
+ flashName: 'flashmediaelement.swf',
919
+ silverlightName: 'silverlightmediaelement.xap'
920
+ },
921
+ // Additional parameters default values
922
+ params = $.extend({}, {
923
+ chapterlinks: 'all',
924
+ width: '100%',
925
+ duration: false,
926
+ chaptersVisible: false,
927
+ timecontrolsVisible: false,
928
+ sharebuttonsVisible: false,
929
+ downloadbuttonsVisible: false,
930
+ summaryVisible: false,
931
+ hidetimebutton: false,
932
+ hidedownloadbutton: false,
933
+ hidesharebutton: false,
934
+ sharewholeepisode: false,
935
+ sources: []
936
+ }, options);
937
+ // turn each player in the current set into a Podlove Web Player
938
+ return this.each(function (index, player) {
939
+ var richplayer = false,
940
+ haschapters = false,
941
+ hiddenTab = false,
942
+ i = 0,
943
+ secArray,
944
+ orig,
945
+ deepLink,
946
+ wrapper,
947
+ summaryActive,
948
+ timecontrolsActive,
949
+ sharebuttonsActive,
950
+ downloadbuttonsActive,
951
+ size,
952
+ name,
953
+ downloadname,
954
+ selectform,
955
+ storageKey;
956
+ //fine tuning params
957
+ if (params.width.toLowerCase() === 'auto') {
958
+ params.width = '100%';
959
+ } else {
960
+ params.width = params.width.replace('px', '');
961
+ }
962
+ //audio params
963
+ if (player.tagName === 'AUDIO') {
964
+ if (params.audioWidth !== undefined) {
965
+ params.width = params.audioWidth;
966
+ }
967
+ mejsoptions.audioWidth = params.width;
968
+ //kill fullscreen button
969
+ $.each(mejsoptions.features, function (i) {
970
+ if (this === 'fullscreen') {
971
+ mejsoptions.features.splice(i, 1);
972
+ }
973
+ });
974
+ //video params
975
+ } else if (player.tagName === 'VIDEO') {
976
+ if (params.height !== undefined) {
977
+ mejsoptions.videoWidth = params.width;
978
+ mejsoptions.videoHeight = params.height;
979
+ }
980
+ if ($(player).attr('width') !== undefined) {
981
+ params.width = $(player).attr('width');
982
+ }
983
+ }
984
+ //duration can be given in seconds or in NPT format
985
+ if (params.duration && params.duration !== parseInt(params.duration, 10)) {
986
+ secArray = parseTimecode(params.duration);
987
+ params.duration = secArray[0];
988
+ }
989
+ //Overwrite MEJS default values with actual data
990
+ $.each(mejsoptions, function (key) {
991
+ if (params[key] !== undefined) {
992
+ mejsoptions[key] = params[key];
993
+ }
994
+ });
995
+ //wrapper and init stuff
996
+ if (params.width.toString().trim() === parseInt(params.width, 10).toString().trim()) {
997
+ params.width = params.width.toString().trim() + 'px';
998
+ }
999
+ orig = player;
1000
+ player = $(player).clone().wrap('<div class="podlovewebplayer_wrapper" style="width: ' + params.width + '"></div>')[0];
1001
+ wrapper = $(player).parent();
1002
+ players.push(player);
1003
+ //add params from html fallback area and remove them from the DOM-tree
1004
+ $(player).find('[data-pwp]').each(function () {
1005
+ params[$(this).data('pwp')] = $(this).html();
1006
+ $(this).remove();
1007
+ });
1008
+ //add params from audio and video elements
1009
+ $(player).find('source').each(function () {
1010
+ if (params.sources !== undefined) {
1011
+ params.sources.push($(this).attr('src'));
1012
+ } else {
1013
+ params.sources[0] = $(this).attr('src');
1014
+ }
1015
+ });
1016
+ //build rich player with meta data
1017
+ if (params.chapters !== undefined || params.title !== undefined || params.subtitle !== undefined || params.summary !== undefined || params.poster !== undefined || $(player).attr('poster') !== undefined) {
1018
+ //set status variable
1019
+ richplayer = true;
1020
+ wrapper.addClass('podlovewebplayer_' + player.tagName.toLowerCase());
1021
+ if (player.tagName === "AUDIO") {
1022
+ //kill play/pause button from miniplayer
1023
+ $.each(mejsoptions.features, function (i) {
1024
+ if (this === 'playpause') {
1025
+ mejsoptions.features.splice(i, 1);
1026
+ }
1027
+ });
1028
+ wrapper.prepend('<div class="podlovewebplayer_meta"></div>');
1029
+ wrapper.find('.podlovewebplayer_meta').prepend('<a class="bigplay" title="Play Episode" href="#"></a>');
1030
+ if (params.poster !== undefined) {
1031
+ wrapper.find('.podlovewebplayer_meta').append('<div class="coverart"><img class="coverimg" src="' + params.poster + '" data-img="' + params.poster + '" alt=""></div>');
1032
+ }
1033
+ if ($(player).attr('poster') !== undefined) {
1034
+ wrapper.find('.podlovewebplayer_meta').append('<div class="coverart"><img src="' + $(player).attr('poster') + '" alt=""></div>');
1035
+ }
1036
+ }
1037
+ if (player.tagName === "VIDEO") {
1038
+ wrapper.prepend('<div class="podlovewebplayer_top"></div>');
1039
+ wrapper.append('<div class="podlovewebplayer_meta"></div>');
1040
+ }
1041
+ if (params.title !== undefined) {
1042
+ if (params.permalink !== undefined) {
1043
+ wrapper.find('.podlovewebplayer_meta').append('<h3 class="episodetitle"><a href="' + params.permalink + '">' + params.title + '</a></h3>');
1044
+ } else {
1045
+ wrapper.find('.podlovewebplayer_meta').append('<h3 class="episodetitle">' + params.title + '</h3>');
1046
+ }
1047
+ }
1048
+ if (params.subtitle !== undefined) {
1049
+ wrapper.find('.podlovewebplayer_meta').append('<div class="subtitle">' + params.subtitle + '</div>');
1050
+ } else {
1051
+ if (params.title !== undefined) {
1052
+ if ((params.title.length < 42) && (params.poster === undefined)) {
1053
+ wrapper.addClass('podlovewebplayer_smallplayer');
1054
+ }
1055
+ }
1056
+ wrapper.find('.podlovewebplayer_meta').append('<div class="subtitle"></div>');
1057
+ }
1058
+ //always render toggler buttons wrapper
1059
+ wrapper.find('.podlovewebplayer_meta').append('<div class="togglers"></div>');
1060
+ wrapper.on('playerresize', function () {
1061
+ wrapper.find('.podlovewebplayer_chapterbox').data('height', wrapper.find('.podlovewebplayer_chapters').height());
1062
+ if (wrapper.find('.podlovewebplayer_chapterbox').hasClass('active')) {
1063
+ wrapper.find('.podlovewebplayer_chapterbox').height(parseInt(wrapper.find('.podlovewebplayer_chapterbox').data('height'), 10) + 2 + 'px');
1064
+ }
1065
+ wrapper.find('.summary').data('height', wrapper.find('.summarydiv').height());
1066
+ if (wrapper.find('.summary').hasClass('active')) {
1067
+ wrapper.find('.summary').height(wrapper.find('.summarydiv').height() + 'px');
1068
+ }
1069
+ });
1070
+ if (params.summary !== undefined) {
1071
+ summaryActive = "";
1072
+ if (params.summaryVisible === true) {
1073
+ summaryActive = " active";
1074
+ }
1075
+ wrapper.find('.togglers').append('<a href="#" class="infowindow infobuttons pwp-icon-info-circle" title="More information about this"></a>');
1076
+ wrapper.find('.podlovewebplayer_meta').after('<div class="summary' + summaryActive + '"><div class="summarydiv">' + params.summary + '</div></div>');
1077
+ }
1078
+ if (params.chapters !== undefined) {
1079
+ if (((params.chapters.length > 10) && (typeof params.chapters === 'string')) || ((params.chapters.length > 1) && (typeof params.chapters === 'object'))) {
1080
+ wrapper.find('.togglers').append('<a href="#" class="chaptertoggle infobuttons pwp-icon-list-bullet" title="Show/hide chapters"></a>');
1081
+ }
1082
+ }
1083
+ if (params.hidetimebutton !== true) {
1084
+ wrapper.find('.togglers').append('<a href="#" class="showcontrols infobuttons pwp-icon-clock" title="Show/hide time navigation controls"></a>');
1085
+ }
1086
+ }
1087
+ timecontrolsActive = "";
1088
+ if (params.timecontrolsVisible === true) {
1089
+ timecontrolsActive = " active";
1090
+ }
1091
+ sharebuttonsActive = "";
1092
+ if (params.sharebuttonsVisible === true) {
1093
+ sharebuttonsActive = " active";
1094
+ }
1095
+ downloadbuttonsActive = "";
1096
+ if (params.downloadbuttonsVisible === true) {
1097
+ downloadbuttonsActive = " active";
1098
+ }
1099
+ wrapper.append('<div class="podlovewebplayer_timecontrol podlovewebplayer_controlbox' + timecontrolsActive + '"></div>');
1100
+ if (params.chapters !== undefined) {
1101
+ if (params.chapters.length > 10) {
1102
+ wrapper.find('.podlovewebplayer_timecontrol').append('<a href="#" class="prevbutton infobuttons pwp-icon-to-start" title="Jump backward to previous chapter"></a><a href="#" class="nextbutton infobuttons pwp-icon-to-end" title="next chapter"></a>');
1103
+ wrapper.find('.controlbox').append('<a href="#" class="prevbutton infobuttons pwp-icon-step-backward" title="previous chapter"></a><a href="#" class="nextbutton infobuttons pwp-icon-to-end" title="Jump to next chapter"></a>');
1104
+ }
1105
+ }
1106
+ wrapper.find('.podlovewebplayer_timecontrol').append('<a href="#" class="rewindbutton infobuttons pwp-icon-fast-bw" title="Rewind 30 seconds"></a>');
1107
+ wrapper.find('.podlovewebplayer_timecontrol').append('<a href="#" class="forwardbutton infobuttons pwp-icon-fast-fw" title="Fast forward 30 seconds"></a>');
1108
+
1109
+ if ((wrapper.closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href') !== undefined) && (params.hidesharebutton !== true)) {
1110
+ wrapper.append('<div class="podlovewebplayer_sharebuttons podlovewebplayer_controlbox' + sharebuttonsActive + '"></div>');
1111
+ wrapper.find('.togglers').append('<a href="#" class="showsharebuttons infobuttons pwp-icon-export" title="Show/hide sharing controls"></a>');
1112
+ wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" class="currentbutton infobuttons pwp-icon-link" title="Get URL for this"></a>');
1113
+ wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="tweetbutton infobuttons pwp-icon-twitter" title="Share this on Twitter"></a>');
1114
+ wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="fbsharebutton infobuttons pwp-icon-facebook" title="Share this on Facebook"></a>');
1115
+ wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="gplusbutton infobuttons pwp-icon-gplus" title="Share this on Google+"></a>');
1116
+ wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="adnbutton infobuttons pwp-icon-appnet" title="Share this on App.net"></a>');
1117
+ wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="mailbutton infobuttons pwp-icon-mail" title="Share this via e-mail"></a>');
1118
+ }
1119
+ if (((params.downloads !== undefined) || (params.sources !== undefined)) && (params.hidedownloadbutton !== true)) {
1120
+ selectform = '<select name="downloads" class="fileselect" size="1" onchange="this.value=this.options[this.selectedIndex].value;">';
1121
+ wrapper.append('<div class="podlovewebplayer_downloadbuttons podlovewebplayer_controlbox' + downloadbuttonsActive + '"></div>');
1122
+ wrapper.find('.togglers').append('<a href="#" class="showdownloadbuttons infobuttons pwp-icon-download" title="Show/hide download bar"></a>');
1123
+ if (params.downloads !== undefined) {
1124
+ for (i = 0; i < params.downloads.length; i += 1) {
1125
+ size = (parseInt(params.downloads[i].size, 10) < 1048704) ? Math.round(parseInt(params.downloads[i].size, 10) / 100) / 10 + 'kB' : Math.round(parseInt(params.downloads[i].size, 10) / 1000 / 100) / 10 + 'MB';
1126
+ selectform += '<option value="' + params.downloads[i].url + '" data-url="' + params.downloads[i].url + '" data-dlurl="' + params.downloads[i].dlurl + '">' + params.downloads[i].name + ' (' + size + ')</option>';
1127
+ }
1128
+ } else {
1129
+ for (i = 0; i < params.sources.length; i += 1) {
1130
+ name = params.sources[i].split('.');
1131
+ name = name[name.length - 1];
1132
+ selectform += '<option value="' + params.sources[i] + '" data-url="' + params.sources[i] + '" data-dlurl="' + params.sources[i] + '">' + name + '</option>';
1133
+ }
1134
+ }
1135
+ selectform += '</select>';
1136
+ wrapper.find('.podlovewebplayer_downloadbuttons').append(selectform);
1137
+ if (params.downloads !== undefined && params.downloads.length > 0) {
1138
+ downloadname = params.downloads[0].url.split('/');
1139
+ downloadname = downloadname[downloadname.length - 1];
1140
+ wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="' + params.downloads[0].url + '" download="' + downloadname + '" class="downloadbutton infobuttons pwp-icon-download" title="Download"></a> ');
1141
+ }
1142
+ wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="#" class="openfilebutton infobuttons pwp-icon-link-ext" title="Open"></a> ');
1143
+ wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="#" class="fileinfobutton infobuttons pwp-icon-info-circle" title="Info"></a> ');
1144
+ }
1145
+ //build chapter table
1146
+ if (params.chapters !== undefined) {
1147
+ if (((params.chapters.length > 10) && (typeof params.chapters === 'string')) || ((params.chapters.length > 1) && (typeof params.chapters === 'object'))) {
1148
+ haschapters = true;
1149
+ generateChapterTable(params).appendTo(wrapper);
1150
+ }
1151
+ }
1152
+ if (richplayer || haschapters) {
1153
+ wrapper.append('<div class="podlovewebplayer_tableend"></div>');
1154
+ }
1155
+ // parse deeplink
1156
+ deepLink = parseTimecode(window.location.href);
1157
+ if (deepLink !== false && players.length === 1) {
1158
+ if (document.hidden !== undefined) {
1159
+ hiddenTab = document.hidden;
1160
+ } else if (document.mozHidden !== undefined) {
1161
+ hiddenTab = document.mozHidden;
1162
+ } else if (document.msHidden !== undefined) {
1163
+ hiddenTab = document.msHidden;
1164
+ } else if (document.webkitHidden !== undefined) {
1165
+ hiddenTab = document.webkitHidden;
1166
+ }
1167
+ if (hiddenTab === true) {
1168
+ $(player).attr({
1169
+ preload: 'auto'
1170
+ });
1171
+ } else {
1172
+ $(player).attr({
1173
+ preload: 'auto',
1174
+ autoplay: 'autoplay'
1175
+ });
1176
+ }
1177
+ startAtTime = deepLink[0];
1178
+ stopAtTime = deepLink[1];
1179
+ } else if (params && params.permalink) {
1180
+ storageKey = 'podloveWebPlayerTime-' + params.permalink;
1181
+ if (handleCookies.getItem(storageKey)) {
1182
+ $(player).one('canplay', function () {
1183
+ this.currentTime = handleCookies.getItem(storageKey);
1184
+ });
1185
+ }
1186
+ }
1187
+ $(player).on('ended', function () {
1188
+ handleCookies.setItem('podloveWebPlayerTime-' + params.permalink, '', new Date(2000, 1, 1));
1189
+ });
1190
+ // init MEJS to player
1191
+ mejsoptions.success = function (player) {
1192
+ addBehavior(player, params, wrapper);
1193
+ if (deepLink !== false && players.length === 1) {
1194
+ $('html, body').delay(150).animate({
1195
+ scrollTop: $('.podlovewebplayer_wrapper:first').offset().top - 25
1196
+ });
1197
+ }
1198
+ };
1199
+ $(orig).replaceWith(wrapper);
1200
+ $(player).mediaelementplayer(mejsoptions);
1201
+ });
1202
+ };
1203
+ }(jQuery));