podlove-web-player-rails 0.2.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +8 -0
- data/README.md +38 -0
- data/Rakefile +6 -0
- data/lib/podlove-web-player-rails.rb +16 -0
- data/lib/podlove-web-player-rails/version.rb +9 -0
- data/lib/podlove-web-player-rails/view_helpers.rb +35 -0
- data/podlove-web-player-rails.gemspec +22 -0
- data/spec/spec_helper.rb +1 -0
- data/vendor/assets/fonts/podlovefont.eot +0 -0
- data/vendor/assets/fonts/podlovefont.otf +0 -0
- data/vendor/assets/fonts/podlovefont.pfa +829 -0
- data/vendor/assets/fonts/podlovefont.ps +1633 -0
- data/vendor/assets/fonts/podlovefont.svg +249 -0
- data/vendor/assets/fonts/podlovefont.ttf +0 -0
- data/vendor/assets/fonts/podlovefont.woff +0 -0
- data/vendor/assets/images/background.png +0 -0
- data/vendor/assets/images/bigplay.png +0 -0
- data/vendor/assets/images/bigplay.svg +1 -0
- data/vendor/assets/images/controls.png +0 -0
- data/vendor/assets/images/controls.svg +1 -0
- data/vendor/assets/images/loading.gif +0 -0
- data/vendor/assets/javascripts/podlove-web-player-rails/html5shiv.js +11 -0
- data/vendor/assets/javascripts/podlove-web-player-rails/index.js +3 -0
- data/vendor/assets/javascripts/podlove-web-player-rails/mediaelement-and-player.js +4913 -0
- data/vendor/assets/javascripts/podlove-web-player-rails/podlove-web-player.js +999 -0
- data/vendor/assets/stylesheets/podlove-web-player.css.scss +1783 -0
- metadata +111 -0
@@ -0,0 +1,999 @@
|
|
1
|
+
(function ($) {
|
2
|
+
'use strict';
|
3
|
+
var startAtTime = false,
|
4
|
+
stopAtTime = false,
|
5
|
+
// Keep all Players on site
|
6
|
+
players = [],
|
7
|
+
// Timecode as described in http://podlove.org/deep-link/
|
8
|
+
// and http://www.w3.org/TR/media-frags/#fragment-dimensions
|
9
|
+
timecodeRegExp = /(?:(\d+):)?(\d+):(\d+)(\.\d+)?([,\-](?:(\d+):)?(\d+):(\d+)(\.\d+)?)?/,
|
10
|
+
ignoreHashChange = false;
|
11
|
+
|
12
|
+
/**
|
13
|
+
* return number as string lefthand filled with zeros
|
14
|
+
* @param number number
|
15
|
+
* @param width number
|
16
|
+
* @return string
|
17
|
+
**/
|
18
|
+
var zeroFill = function (number, width) {
|
19
|
+
var s = number.toString();
|
20
|
+
while (s.length < width) {
|
21
|
+
s = "0" + s;
|
22
|
+
}
|
23
|
+
return s;
|
24
|
+
};
|
25
|
+
|
26
|
+
/**
|
27
|
+
* accepts array with start and end time in seconds
|
28
|
+
* returns timecode in deep-linking format
|
29
|
+
* @param times array
|
30
|
+
* @param forceHours bool (optional)
|
31
|
+
* @return string
|
32
|
+
**/
|
33
|
+
var generateTimecode = $.generateTimecode = function (times, leadingZeros, forceHours) {
|
34
|
+
function generatePart(time) {
|
35
|
+
var part, hours, minutes, seconds, milliseconds;
|
36
|
+
// prevent negative values from player
|
37
|
+
if (!time || time <= 0) {
|
38
|
+
return (leadingZeros || !time) ? (forceHours ? '00:00:00' : '00:00') : '--';
|
39
|
+
}
|
40
|
+
|
41
|
+
hours = Math.floor(time / 60 / 60);
|
42
|
+
minutes = Math.floor(time / 60) % 60;
|
43
|
+
seconds = Math.floor(time % 60) % 60;
|
44
|
+
milliseconds = Math.floor(time % 1 * 1000);
|
45
|
+
|
46
|
+
if (leadingZeros) {
|
47
|
+
// required (minutes : seconds)
|
48
|
+
part = zeroFill(minutes, 2) + ':' + zeroFill(seconds, 2);
|
49
|
+
hours = zeroFill(hours, 2);
|
50
|
+
hours = hours === '00' && !forceHours ? '' : hours + ':';
|
51
|
+
milliseconds = milliseconds ? '.' + zeroFill(milliseconds, 3) : '';
|
52
|
+
} else {
|
53
|
+
part = hours ? zeroFill(minutes, 2) : minutes.toString();
|
54
|
+
part += ':' + zeroFill(seconds, 2);
|
55
|
+
hours = hours ? hours + ':' : '';
|
56
|
+
milliseconds = milliseconds ? '.' + milliseconds : '';
|
57
|
+
}
|
58
|
+
|
59
|
+
return hours + part + milliseconds;
|
60
|
+
}
|
61
|
+
|
62
|
+
if (times[1] > 0 && times[1] < 9999999 && times[0] < times[1]) {
|
63
|
+
return generatePart(times[0]) + ',' + generatePart(times[1]);
|
64
|
+
}
|
65
|
+
|
66
|
+
return generatePart(times[0]);
|
67
|
+
};
|
68
|
+
|
69
|
+
/**
|
70
|
+
* parses time code into seconds
|
71
|
+
* @param string timecode
|
72
|
+
* @return number
|
73
|
+
**/
|
74
|
+
var parseTimecode = function (timecode) {
|
75
|
+
var parts, startTime = 0,
|
76
|
+
endTime = 0;
|
77
|
+
|
78
|
+
if (timecode) {
|
79
|
+
parts = timecode.match(timecodeRegExp);
|
80
|
+
|
81
|
+
if (parts && parts.length === 10) {
|
82
|
+
// hours
|
83
|
+
startTime += parts[1] ? parseInt(parts[1], 10) * 60 * 60 : 0;
|
84
|
+
// minutes
|
85
|
+
startTime += parseInt(parts[2], 10) * 60;
|
86
|
+
// seconds
|
87
|
+
startTime += parseInt(parts[3], 10);
|
88
|
+
// milliseconds
|
89
|
+
startTime += parts[4] ? parseFloat(parts[4]) : 0;
|
90
|
+
// no negative time
|
91
|
+
startTime = Math.max(startTime, 0);
|
92
|
+
|
93
|
+
// if there only a startTime but no endTime
|
94
|
+
if (parts[5] === undefined) {
|
95
|
+
return [startTime, false];
|
96
|
+
}
|
97
|
+
|
98
|
+
// hours
|
99
|
+
endTime += parts[6] ? parseInt(parts[6], 10) * 60 * 60 : 0;
|
100
|
+
// minutes
|
101
|
+
endTime += parseInt(parts[7], 10) * 60;
|
102
|
+
// seconds
|
103
|
+
endTime += parseInt(parts[8], 10);
|
104
|
+
// milliseconds
|
105
|
+
endTime += parts[9] ? parseFloat(parts[9]) : 0;
|
106
|
+
// no negative time
|
107
|
+
endTime = Math.max(endTime, 0);
|
108
|
+
|
109
|
+
return (endTime > startTime) ? [startTime, endTime] : [startTime, false];
|
110
|
+
}
|
111
|
+
}
|
112
|
+
return false;
|
113
|
+
};
|
114
|
+
|
115
|
+
var checkCurrentURL = function () {
|
116
|
+
var deepLink;
|
117
|
+
deepLink = parseTimecode(window.location.href);
|
118
|
+
if (deepLink !== false) {
|
119
|
+
startAtTime = deepLink[0];
|
120
|
+
stopAtTime = deepLink[1];
|
121
|
+
}
|
122
|
+
};
|
123
|
+
|
124
|
+
var validateURL = function (url) {
|
125
|
+
//de comment this to validate URLs, if you want use relative paths leave it so.
|
126
|
+
//var urlregex = /(^|\s)((https?:\/\/)?[\w\-]+(\.[\w\-]+)+\.?(:\d+)?(\/\S*)?)/gi;
|
127
|
+
//url = url.match(urlregex);
|
128
|
+
//return (url !== null) ? url[0] : url;
|
129
|
+
return url.trim();
|
130
|
+
};
|
131
|
+
|
132
|
+
/**
|
133
|
+
* add a string as hash in the adressbar
|
134
|
+
* @param string fragment
|
135
|
+
**/
|
136
|
+
var setFragmentURL = function (fragment) {
|
137
|
+
window.location.hash = fragment;
|
138
|
+
};
|
139
|
+
|
140
|
+
/**
|
141
|
+
* update the chapter list when the data is loaded
|
142
|
+
* @param object player
|
143
|
+
* @param object marks
|
144
|
+
**/
|
145
|
+
var updateChapterMarks = function (player, marks) {
|
146
|
+
var coverimg = marks.closest('.podlovewebplayer_wrapper').find('.coverimg');
|
147
|
+
marks.each(function () {
|
148
|
+
var deepLink, isBuffered, chapterimg = null,
|
149
|
+
mark = $(this),
|
150
|
+
startTime = mark.data('start'),
|
151
|
+
endTime = mark.data('end'),
|
152
|
+
isEnabled = mark.data('enabled'),
|
153
|
+
isActive = player.currentTime > startTime - 0.3 &&
|
154
|
+
player.currentTime <= endTime;
|
155
|
+
// prevent timing errors
|
156
|
+
if (player.buffered.length > 0) {
|
157
|
+
isBuffered = player.buffered.end(0) > startTime;
|
158
|
+
}
|
159
|
+
if (isActive) {
|
160
|
+
chapterimg = validateURL(mark.data('img'));
|
161
|
+
if ((chapterimg !== null)&&(mark.hasClass('active'))) {
|
162
|
+
if ((coverimg.attr('src') !== chapterimg)&&(chapterimg.length > 5)) {
|
163
|
+
coverimg.attr('src',chapterimg);
|
164
|
+
}
|
165
|
+
} else {
|
166
|
+
if (coverimg.attr('src') !== coverimg.data('img')) {
|
167
|
+
coverimg.attr('src', coverimg.data('img'));
|
168
|
+
}
|
169
|
+
}
|
170
|
+
mark.addClass('active').siblings().removeClass('active');
|
171
|
+
}
|
172
|
+
if (!isEnabled && isBuffered) {
|
173
|
+
deepLink = '#t=' + generateTimecode([startTime, endTime]);
|
174
|
+
$(mark).data('enabled', true).addClass('loaded').find('a[rel=player]').removeClass('disabled');
|
175
|
+
}
|
176
|
+
});
|
177
|
+
};
|
178
|
+
|
179
|
+
var checkTime = function (e) {
|
180
|
+
if (players.length > 1) {
|
181
|
+
return;
|
182
|
+
}
|
183
|
+
var player = e.data.player;
|
184
|
+
if (startAtTime !== false &&
|
185
|
+
//Kinda hackish: Make sure that the timejump is at least 1 second (fix for OGG/Firefox)
|
186
|
+
(player.lastCheck === undefined || Math.abs(startAtTime - player.lastCheck) > 1)) {
|
187
|
+
player.setCurrentTime(startAtTime);
|
188
|
+
player.lastCheck = startAtTime;
|
189
|
+
startAtTime = false;
|
190
|
+
}
|
191
|
+
if (stopAtTime !== false && player.currentTime >= stopAtTime) {
|
192
|
+
player.pause();
|
193
|
+
stopAtTime = false;
|
194
|
+
}
|
195
|
+
};
|
196
|
+
|
197
|
+
var addressCurrentTime = function (e) {
|
198
|
+
var fragment;
|
199
|
+
if (players.length === 1) {
|
200
|
+
fragment = 't=' + generateTimecode([e.data.player.currentTime]);
|
201
|
+
setFragmentURL(fragment);
|
202
|
+
}
|
203
|
+
};
|
204
|
+
|
205
|
+
/**
|
206
|
+
* Given a list of chapters, this function creates the chapter table for the player.
|
207
|
+
*/
|
208
|
+
var generateChapterTable = function (params) {
|
209
|
+
|
210
|
+
var div = $('<div class="podlovewebplayer_chapterbox showonplay"><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>'),
|
211
|
+
table = div.children('table'),
|
212
|
+
tbody = table.children('tbody');
|
213
|
+
|
214
|
+
if (params.chaptersVisible === true) {
|
215
|
+
div.addClass('active');
|
216
|
+
}
|
217
|
+
|
218
|
+
table.addClass('podlovewebplayer_chapters');
|
219
|
+
if (params.chapterlinks !== 'false') {
|
220
|
+
table.addClass('linked linked_' + params.chapterlinks);
|
221
|
+
}
|
222
|
+
|
223
|
+
//prepare row data
|
224
|
+
var tempchapters = params.chapters;
|
225
|
+
var maxchapterstart = 0;
|
226
|
+
|
227
|
+
//first round: kill empty rows and build structured object
|
228
|
+
if (typeof params.chapters === 'string') {
|
229
|
+
tempchapters = [];
|
230
|
+
$.each(params.chapters.split("\n"), function (i, chapter) {
|
231
|
+
|
232
|
+
//exit early if this line contains nothing but whitespace
|
233
|
+
if (!/\S/.test(chapter)) {
|
234
|
+
return;
|
235
|
+
}
|
236
|
+
|
237
|
+
//extract the timestamp
|
238
|
+
var line = $.trim(chapter);
|
239
|
+
var tc = parseTimecode(line.substring(0, line.indexOf(' ')));
|
240
|
+
var chaptitle = $.trim(line.substring(line.indexOf(' ')));
|
241
|
+
tempchapters.push({
|
242
|
+
start: tc[0],
|
243
|
+
code: chaptitle
|
244
|
+
});
|
245
|
+
});
|
246
|
+
} else {
|
247
|
+
// assume array of objects
|
248
|
+
$.each(tempchapters, function (key, value) {
|
249
|
+
value.code = value.title;
|
250
|
+
if (typeof value.start === 'string') {
|
251
|
+
value.start = parseTimecode(value.start)[0];
|
252
|
+
}
|
253
|
+
});
|
254
|
+
}
|
255
|
+
|
256
|
+
// order is not guaranteed: http://podlove.org/simple-chapters/
|
257
|
+
tempchapters = tempchapters.sort(function (a, b) {
|
258
|
+
return a.start - b.start;
|
259
|
+
});
|
260
|
+
|
261
|
+
//second round: collect more information
|
262
|
+
maxchapterstart = Math.max.apply(Math,
|
263
|
+
$.map(tempchapters, function (value, i) {
|
264
|
+
var next = tempchapters[i + 1];
|
265
|
+
|
266
|
+
// we use `this.end` to quickly calculate the duration in the next round
|
267
|
+
if (next) {
|
268
|
+
value.end = next.start;
|
269
|
+
}
|
270
|
+
|
271
|
+
// we need this data for proper formatting
|
272
|
+
return value.start;
|
273
|
+
}));
|
274
|
+
|
275
|
+
|
276
|
+
//this is a "template" for each chapter row
|
277
|
+
var 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>');
|
278
|
+
|
279
|
+
//third round: build actual dom table
|
280
|
+
$.each(tempchapters, function (i) {
|
281
|
+
var finalchapter = !tempchapters[i + 1],
|
282
|
+
duration = Math.round(this.end - this.start),
|
283
|
+
forceHours,
|
284
|
+
row = rowDummy.clone();
|
285
|
+
|
286
|
+
//make sure the duration for all chapters are equally formatted
|
287
|
+
if (!finalchapter) {
|
288
|
+
this.duration = generateTimecode([duration], false);
|
289
|
+
} else {
|
290
|
+
if (params.duration === 0) {
|
291
|
+
this.end = 9999999999;
|
292
|
+
this.duration = '…';
|
293
|
+
} else {
|
294
|
+
this.end = params.duration;
|
295
|
+
this.duration = generateTimecode([Math.round(this.end - this.start)], false);
|
296
|
+
}
|
297
|
+
}
|
298
|
+
|
299
|
+
|
300
|
+
if (i % 2) {
|
301
|
+
row.addClass('oddchapter');
|
302
|
+
}
|
303
|
+
|
304
|
+
//deeplink, start and end
|
305
|
+
row.attr({
|
306
|
+
'data-start': this.start,
|
307
|
+
'data-end': this.end,
|
308
|
+
'data-img': (this.image !== undefined) ? this.image : ''
|
309
|
+
});
|
310
|
+
|
311
|
+
//if there is a chapter that starts after an hour, force '00:' on all previous chapters
|
312
|
+
forceHours = (maxchapterstart >= 3600);
|
313
|
+
|
314
|
+
//insert the chapter data
|
315
|
+
row.find('.starttime > span').text(generateTimecode([Math.round(this.start)], true, forceHours));
|
316
|
+
row.find('.chaptername').html(this.code);
|
317
|
+
row.find('.timecode > span').text(this.duration);
|
318
|
+
|
319
|
+
row.appendTo(tbody);
|
320
|
+
});
|
321
|
+
return div;
|
322
|
+
};
|
323
|
+
|
324
|
+
/**
|
325
|
+
* add chapter behavior and deeplinking: skip to referenced
|
326
|
+
* time position & write current time into address
|
327
|
+
* @param player object
|
328
|
+
*/
|
329
|
+
var addBehavior = function (player, params, wrapper) {
|
330
|
+
var jqPlayer = $(player),
|
331
|
+
layoutedPlayer = jqPlayer,
|
332
|
+
canplay = false;
|
333
|
+
|
334
|
+
/**
|
335
|
+
* The `player` is an interface. It provides the play and pause functionality. The
|
336
|
+
* `layoutedPlayer` on the other hand is a DOM element. In native mode, these two
|
337
|
+
* are one and the same object. In Flash though the interface is a plain JS object.
|
338
|
+
*/
|
339
|
+
|
340
|
+
if (players.length === 1) {
|
341
|
+
// check if deeplink is set
|
342
|
+
checkCurrentURL();
|
343
|
+
}
|
344
|
+
|
345
|
+
// get things straight for flash fallback
|
346
|
+
if (player.pluginType === 'flash') {
|
347
|
+
layoutedPlayer = $('#mep_' + player.id.substring(9));
|
348
|
+
}
|
349
|
+
|
350
|
+
// cache some jQ objects
|
351
|
+
var metainfo = wrapper.find('.podlovewebplayer_meta'),
|
352
|
+
summary = wrapper.find('.summary'),
|
353
|
+
podlovewebplayer_timecontrol = wrapper.find('.podlovewebplayer_timecontrol'),
|
354
|
+
podlovewebplayer_sharebuttons = wrapper.find('.podlovewebplayer_sharebuttons'),
|
355
|
+
podlovewebplayer_downloadbuttons = wrapper.find('.podlovewebplayer_downloadbuttons'),
|
356
|
+
chapterdiv = wrapper.find('.podlovewebplayer_chapterbox'),
|
357
|
+
list = wrapper.find('table'),
|
358
|
+
marks = list.find('tr');
|
359
|
+
|
360
|
+
// fix height of summary for better toggability
|
361
|
+
summary.each(function () {
|
362
|
+
$(this).data('height', $(this).height() + 10);
|
363
|
+
if (!$(this).hasClass('active')) {
|
364
|
+
$(this).height('0px');
|
365
|
+
} else {
|
366
|
+
$(this).height($(this).find('div.summarydiv').height() + 10 + 'px');
|
367
|
+
}
|
368
|
+
});
|
369
|
+
|
370
|
+
chapterdiv.each(function () {
|
371
|
+
$(this).data('height', $(this).find('.podlovewebplayer_chapters').height());
|
372
|
+
if (!$(this).hasClass('active')) {
|
373
|
+
$(this).height('0px');
|
374
|
+
} else {
|
375
|
+
$(this).height($(this).find('.podlovewebplayer_chapters').height() + 'px');
|
376
|
+
}
|
377
|
+
});
|
378
|
+
|
379
|
+
if (metainfo.length === 1) {
|
380
|
+
|
381
|
+
metainfo.find('a.infowindow').click(function () {
|
382
|
+
summary.toggleClass('active');
|
383
|
+
if (summary.hasClass('active')) {
|
384
|
+
summary.height(summary.find('div.summarydiv').height() + 10 + 'px');
|
385
|
+
} else {
|
386
|
+
summary.height('0px');
|
387
|
+
}
|
388
|
+
return false;
|
389
|
+
});
|
390
|
+
|
391
|
+
metainfo.find('a.showcontrols').on('click', function () {
|
392
|
+
podlovewebplayer_timecontrol.toggleClass('active');
|
393
|
+
if (podlovewebplayer_sharebuttons !== undefined) {
|
394
|
+
if (podlovewebplayer_sharebuttons.hasClass('active')) {
|
395
|
+
podlovewebplayer_sharebuttons.removeClass('active');
|
396
|
+
} else if (podlovewebplayer_downloadbuttons.hasClass('active')) {
|
397
|
+
podlovewebplayer_downloadbuttons.removeClass('active');
|
398
|
+
}
|
399
|
+
}
|
400
|
+
return false;
|
401
|
+
});
|
402
|
+
|
403
|
+
metainfo.find('a.showsharebuttons').on('click', function () {
|
404
|
+
podlovewebplayer_sharebuttons.toggleClass('active');
|
405
|
+
if (podlovewebplayer_timecontrol.hasClass('active')) {
|
406
|
+
podlovewebplayer_timecontrol.removeClass('active');
|
407
|
+
} else if (podlovewebplayer_downloadbuttons.hasClass('active')) {
|
408
|
+
podlovewebplayer_downloadbuttons.removeClass('active');
|
409
|
+
}
|
410
|
+
return false;
|
411
|
+
});
|
412
|
+
|
413
|
+
metainfo.find('a.showdownloadbuttons').on('click', function () {
|
414
|
+
podlovewebplayer_downloadbuttons.toggleClass('active');
|
415
|
+
if (podlovewebplayer_timecontrol.hasClass('active')) {
|
416
|
+
podlovewebplayer_timecontrol.removeClass('active');
|
417
|
+
} else if (podlovewebplayer_sharebuttons.hasClass('active')) {
|
418
|
+
podlovewebplayer_sharebuttons.removeClass('active');
|
419
|
+
}
|
420
|
+
return false;
|
421
|
+
});
|
422
|
+
|
423
|
+
metainfo.find('.bigplay').on('click', function () {
|
424
|
+
if ($(this).hasClass('bigplay')) {
|
425
|
+
var playButton = $(this).parent().find('.bigplay');
|
426
|
+
|
427
|
+
if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
|
428
|
+
if (player.paused) {
|
429
|
+
playButton.addClass('playing');
|
430
|
+
player.play();
|
431
|
+
} else {
|
432
|
+
playButton.removeClass('playing');
|
433
|
+
player.pause();
|
434
|
+
}
|
435
|
+
} else {
|
436
|
+
if (!playButton.hasClass('playing')) {
|
437
|
+
playButton.addClass('playing');
|
438
|
+
$(this).parent().parent().find('.mejs-time-buffering').show();
|
439
|
+
}
|
440
|
+
// flash fallback needs additional pause
|
441
|
+
if (player.pluginType === 'flash') {
|
442
|
+
player.pause();
|
443
|
+
}
|
444
|
+
player.play();
|
445
|
+
}
|
446
|
+
}
|
447
|
+
return false;
|
448
|
+
});
|
449
|
+
|
450
|
+
wrapper.find('.chaptertoggle').unbind('click').click(function () {
|
451
|
+
wrapper.find('.podlovewebplayer_chapterbox').toggleClass('active');
|
452
|
+
if (wrapper.find('.podlovewebplayer_chapterbox').hasClass('active')) {
|
453
|
+
wrapper.find('.podlovewebplayer_chapterbox').height(wrapper.find('.podlovewebplayer_chapterbox').data('height') + 'px');
|
454
|
+
} else {
|
455
|
+
wrapper.find('.podlovewebplayer_chapterbox').height('0px');
|
456
|
+
}
|
457
|
+
return false;
|
458
|
+
});
|
459
|
+
|
460
|
+
wrapper.find('.prevbutton').click(function () {
|
461
|
+
if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
|
462
|
+
if (player.currentTime > chapterdiv.find('.active').data('start') + 10) {
|
463
|
+
player.setCurrentTime(chapterdiv.find('.active').data('start'));
|
464
|
+
} else {
|
465
|
+
player.setCurrentTime(chapterdiv.find('.active').prev().data('start'));
|
466
|
+
}
|
467
|
+
} else {
|
468
|
+
player.play();
|
469
|
+
}
|
470
|
+
return false;
|
471
|
+
});
|
472
|
+
|
473
|
+
wrapper.find('.nextbutton').click(function () {
|
474
|
+
if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
|
475
|
+
player.setCurrentTime(chapterdiv.find('.active').next().data('start'));
|
476
|
+
} else {
|
477
|
+
player.play();
|
478
|
+
}
|
479
|
+
return false;
|
480
|
+
});
|
481
|
+
|
482
|
+
wrapper.find('.rewindbutton').click(function () {
|
483
|
+
if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
|
484
|
+
player.setCurrentTime(player.currentTime - 30);
|
485
|
+
} else {
|
486
|
+
player.play();
|
487
|
+
}
|
488
|
+
return false;
|
489
|
+
});
|
490
|
+
|
491
|
+
wrapper.find('.forwardbutton').click(function () {
|
492
|
+
if ((typeof player.currentTime === 'number') && (player.currentTime > 0)) {
|
493
|
+
player.setCurrentTime(player.currentTime + 30);
|
494
|
+
} else {
|
495
|
+
player.play();
|
496
|
+
}
|
497
|
+
return false;
|
498
|
+
});
|
499
|
+
|
500
|
+
wrapper.find('.currentbutton').click(function () {
|
501
|
+
window.prompt('This URL directly points to this episode', $(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href'));
|
502
|
+
return false;
|
503
|
+
});
|
504
|
+
|
505
|
+
wrapper.find('.tweetbutton').click(function () {
|
506
|
+
window.open('https://twitter.com/share?text=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&url=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'tweet it', 'width=550,height=420,resizable=yes');
|
507
|
+
return false;
|
508
|
+
});
|
509
|
+
|
510
|
+
wrapper.find('.fbsharebutton').click(function () {
|
511
|
+
window.open('http://www.facebook.com/share.php?t=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&u=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'share it', 'width=550,height=340,resizable=yes');
|
512
|
+
return false;
|
513
|
+
});
|
514
|
+
|
515
|
+
wrapper.find('.gplusbutton').click(function () {
|
516
|
+
window.open('https://plus.google.com/share?title=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&url=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'plus it', 'width=550,height=420,resizable=yes');
|
517
|
+
return false;
|
518
|
+
});
|
519
|
+
|
520
|
+
wrapper.find('.adnbutton').click(function () {
|
521
|
+
window.open('https://alpha.app.net/intent/post?text=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '%20' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')), 'plus it', 'width=550,height=420,resizable=yes');
|
522
|
+
return false;
|
523
|
+
});
|
524
|
+
|
525
|
+
wrapper.find('.mailbutton').click(function () {
|
526
|
+
window.location = 'mailto:?subject=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '&body=' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').text()) + '%20%3C' + encodeURI($(this).closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href')) + '%3E';
|
527
|
+
return false;
|
528
|
+
});
|
529
|
+
|
530
|
+
wrapper.find('.downloadbutton').click(function () {
|
531
|
+
$(this).parent().find(".fileselect option:selected").each(function () {
|
532
|
+
window.location = $(this).data('dlurl');
|
533
|
+
});
|
534
|
+
return false;
|
535
|
+
});
|
536
|
+
|
537
|
+
wrapper.find('.openfilebutton').click(function () {
|
538
|
+
$(this).parent().find(".fileselect option:selected").each(function () {
|
539
|
+
window.open($(this).data('url'), 'Podlove Popup', 'width=550,height=420,resizable=yes');
|
540
|
+
});
|
541
|
+
return false;
|
542
|
+
});
|
543
|
+
|
544
|
+
wrapper.find('.fileinfobutton').click(function () {
|
545
|
+
$(this).parent().find(".fileselect option:selected").each(function () {
|
546
|
+
window.prompt('file URL:', $(this).val());
|
547
|
+
});
|
548
|
+
return false;
|
549
|
+
});
|
550
|
+
}
|
551
|
+
|
552
|
+
// chapters list
|
553
|
+
list
|
554
|
+
.show()
|
555
|
+
.delegate('.chaptertr', 'click', function (e) {
|
556
|
+
if ($(this).closest('table').hasClass('linked_all') || $(this).closest('tr').hasClass('loaded')) {
|
557
|
+
e.preventDefault();
|
558
|
+
var mark = $(this).closest('tr'),
|
559
|
+
startTime = mark.data('start');
|
560
|
+
//endTime = mark.data('end');
|
561
|
+
|
562
|
+
// If there is only one player also set deepLink
|
563
|
+
if (players.length === 1) {
|
564
|
+
// setFragmentURL('t=' + generateTimecode([startTime, endTime]));
|
565
|
+
setFragmentURL('t=' + generateTimecode([startTime]));
|
566
|
+
} else {
|
567
|
+
if (canplay) {
|
568
|
+
// Basic Chapter Mark function (without deeplinking)
|
569
|
+
player.setCurrentTime(startTime);
|
570
|
+
} else {
|
571
|
+
jqPlayer.one('canplay', function () {
|
572
|
+
player.setCurrentTime(startTime);
|
573
|
+
});
|
574
|
+
}
|
575
|
+
}
|
576
|
+
|
577
|
+
// flash fallback needs additional pause
|
578
|
+
if (player.pluginType === 'flash') {
|
579
|
+
player.pause();
|
580
|
+
}
|
581
|
+
player.play();
|
582
|
+
}
|
583
|
+
return false;
|
584
|
+
});
|
585
|
+
|
586
|
+
// wait for the player or you'll get DOM EXCEPTIONS
|
587
|
+
// And just listen once because of a special behaviour in firefox
|
588
|
+
// --> https://bugzilla.mozilla.org/show_bug.cgi?id=664842
|
589
|
+
jqPlayer.one('canplay', function () {
|
590
|
+
canplay = true;
|
591
|
+
|
592
|
+
// add duration of final chapter
|
593
|
+
if (player.duration) {
|
594
|
+
marks.find('.timecode code').eq(-1).each(function () {
|
595
|
+
var start = Math.floor($(this).closest('tr').data('start'));
|
596
|
+
var end = Math.floor(player.duration);
|
597
|
+
$(this).text(generateTimecode([end - start]));
|
598
|
+
});
|
599
|
+
}
|
600
|
+
|
601
|
+
// add Deeplink Behavior if there is only one player on the site
|
602
|
+
if (players.length === 1) {
|
603
|
+
jqPlayer.bind('play timeupdate', {
|
604
|
+
player: player
|
605
|
+
}, checkTime)
|
606
|
+
.bind('pause', {
|
607
|
+
player: player
|
608
|
+
}, addressCurrentTime);
|
609
|
+
// disabled 'cause it overrides chapter clicks
|
610
|
+
// bind seeked to addressCurrentTime
|
611
|
+
|
612
|
+
checkCurrentURL();
|
613
|
+
|
614
|
+
// handle browser history navigation
|
615
|
+
$(window).bind('hashchange onpopstate', function(e) {
|
616
|
+
if (!ignoreHashChange) {
|
617
|
+
checkCurrentURL();
|
618
|
+
}
|
619
|
+
ignoreHashChange = false;
|
620
|
+
});
|
621
|
+
}
|
622
|
+
});
|
623
|
+
|
624
|
+
// always update Chaptermarks though
|
625
|
+
jqPlayer
|
626
|
+
.on('timeupdate', function () {
|
627
|
+
updateChapterMarks(player, marks);
|
628
|
+
})
|
629
|
+
// update play/pause status
|
630
|
+
.on('play playing', function () {
|
631
|
+
if (!player.persistingTimer) {
|
632
|
+
player.persistingTimer = window.setInterval(function() {
|
633
|
+
if (players.length === 1) {
|
634
|
+
ignoreHashChange = true;
|
635
|
+
window.location.replace('#t=' + generateTimecode([player.currentTime, false]));
|
636
|
+
}
|
637
|
+
localStorage['podloveWebPlayerTime-' + params.permalink] = player.currentTime;
|
638
|
+
}, 5000);
|
639
|
+
}
|
640
|
+
list.find('.paused').removeClass('paused');
|
641
|
+
if (metainfo.length === 1) {
|
642
|
+
metainfo.find('.bigplay').addClass('playing');
|
643
|
+
}
|
644
|
+
})
|
645
|
+
.on('pause', function () {
|
646
|
+
window.clearInterval(player.persistingTimer);
|
647
|
+
player.persistingTimer = null;
|
648
|
+
|
649
|
+
if (metainfo.length === 1) {
|
650
|
+
metainfo.find('.bigplay').removeClass('playing');
|
651
|
+
}
|
652
|
+
});
|
653
|
+
};
|
654
|
+
|
655
|
+
$.fn.podlovewebplayer = function (options) {
|
656
|
+
|
657
|
+
// MEJS options default values
|
658
|
+
var mejsoptions = {
|
659
|
+
defaultVideoWidth: 480,
|
660
|
+
defaultVideoHeight: 270,
|
661
|
+
videoWidth: -1,
|
662
|
+
videoHeight: -1,
|
663
|
+
audioWidth: -1,
|
664
|
+
audioHeight: 30,
|
665
|
+
startVolume: 0.8,
|
666
|
+
loop: false,
|
667
|
+
enableAutosize: true,
|
668
|
+
features: ['playpause', 'current', 'progress', 'duration', 'tracks', 'volume', 'fullscreen'],
|
669
|
+
alwaysShowControls: false,
|
670
|
+
iPadUseNativeControls: false,
|
671
|
+
iPhoneUseNativeControls: false,
|
672
|
+
AndroidUseNativeControls: false,
|
673
|
+
alwaysShowHours: false,
|
674
|
+
showTimecodeFrameCount: false,
|
675
|
+
framesPerSecond: 25,
|
676
|
+
enableKeyboard: true,
|
677
|
+
pauseOtherPlayers: true,
|
678
|
+
duration: false,
|
679
|
+
plugins: ['flash', 'silverlight'],
|
680
|
+
pluginPath: './static/',
|
681
|
+
flashName: 'flashmediaelement.swf',
|
682
|
+
silverlightName: 'silverlightmediaelement.xap'
|
683
|
+
};
|
684
|
+
|
685
|
+
// Additional parameters default values
|
686
|
+
var params = $.extend({}, {
|
687
|
+
chapterlinks: 'all',
|
688
|
+
width: '100%',
|
689
|
+
duration: false,
|
690
|
+
chaptersVisible: false,
|
691
|
+
timecontrolsVisible: false,
|
692
|
+
sharebuttonsVisible: false,
|
693
|
+
downloadbuttonsVisible: false,
|
694
|
+
summaryVisible: false,
|
695
|
+
hidetimebutton: false,
|
696
|
+
hidedownloadbutton: false,
|
697
|
+
hidesharebutton: false,
|
698
|
+
sharewholeepisode: false,
|
699
|
+
sources: []
|
700
|
+
}, options);
|
701
|
+
|
702
|
+
// turn each player in the current set into a Podlove Web Player
|
703
|
+
return this.each(function (index, player) {
|
704
|
+
|
705
|
+
var richplayer = false,
|
706
|
+
haschapters = false,
|
707
|
+
hiddenTab = false,
|
708
|
+
i = 0;
|
709
|
+
|
710
|
+
//fine tuning params
|
711
|
+
if (params.width.toLowerCase() === 'auto') {
|
712
|
+
params.width = '100%';
|
713
|
+
} else {
|
714
|
+
params.width = params.width.replace('px', '');
|
715
|
+
}
|
716
|
+
|
717
|
+
//audio params
|
718
|
+
if (player.tagName === 'AUDIO') {
|
719
|
+
if (params.audioWidth !== undefined) {
|
720
|
+
params.width = params.audioWidth;
|
721
|
+
}
|
722
|
+
mejsoptions.audioWidth = params.width;
|
723
|
+
|
724
|
+
//kill fullscreen button
|
725
|
+
$.each(mejsoptions.features, function (i) {
|
726
|
+
if (this === 'fullscreen') {
|
727
|
+
mejsoptions.features.splice(i, 1);
|
728
|
+
}
|
729
|
+
});
|
730
|
+
|
731
|
+
//video params
|
732
|
+
} else if (player.tagName === 'VIDEO') {
|
733
|
+
|
734
|
+
if (params.height !== undefined) {
|
735
|
+
mejsoptions.videoWidth = params.width;
|
736
|
+
mejsoptions.videoHeight = params.height;
|
737
|
+
}
|
738
|
+
|
739
|
+
if ($(player).attr('width') !== undefined) {
|
740
|
+
params.width = $(player).attr('width');
|
741
|
+
}
|
742
|
+
}
|
743
|
+
|
744
|
+
//duration can be given in seconds or in NPT format
|
745
|
+
if (params.duration && params.duration !== parseInt(params.duration, 10)) {
|
746
|
+
var secArray = parseTimecode(params.duration);
|
747
|
+
params.duration = secArray[0];
|
748
|
+
}
|
749
|
+
|
750
|
+
//Overwrite MEJS default values with actual data
|
751
|
+
$.each(mejsoptions, function (key) {
|
752
|
+
if (params[key] !== undefined) {
|
753
|
+
mejsoptions[key] = params[key];
|
754
|
+
}
|
755
|
+
});
|
756
|
+
|
757
|
+
//wrapper and init stuff
|
758
|
+
if (params.width.toString().trim() === parseInt(params.width, 10).toString().trim()) {
|
759
|
+
params.width = params.width.toString().trim()+'px';
|
760
|
+
}
|
761
|
+
|
762
|
+
var orig = player;
|
763
|
+
|
764
|
+
player = $(player).clone().wrap('<div class="podlovewebplayer_wrapper" style="width: ' + params.width + '"></div>')[0];
|
765
|
+
var deepLink,
|
766
|
+
wrapper = $(player).parent();
|
767
|
+
|
768
|
+
players.push(player);
|
769
|
+
|
770
|
+
//add params from html fallback area and remove them from the DOM-tree
|
771
|
+
$(player).find('[data-pwp]').each(function () {
|
772
|
+
params[$(this).data('pwp')] = $(this).html();
|
773
|
+
$(this).remove();
|
774
|
+
});
|
775
|
+
//add params from audio and video elements
|
776
|
+
$(player).find('source').each(function () {
|
777
|
+
if (params.sources !== undefined) {
|
778
|
+
params.sources.push($(this).attr('src'));
|
779
|
+
} else {
|
780
|
+
params.sources[0] = $(this).attr('src');
|
781
|
+
}
|
782
|
+
});
|
783
|
+
|
784
|
+
//build rich player with meta data
|
785
|
+
if (params.chapters !== undefined ||
|
786
|
+
params.title !== undefined ||
|
787
|
+
params.subtitle !== undefined ||
|
788
|
+
params.summary !== undefined ||
|
789
|
+
params.poster !== undefined ||
|
790
|
+
$(player).attr('poster') !== undefined) {
|
791
|
+
|
792
|
+
//set status variable
|
793
|
+
richplayer = true;
|
794
|
+
|
795
|
+
wrapper.addClass('podlovewebplayer_' + player.tagName.toLowerCase());
|
796
|
+
|
797
|
+
if (player.tagName === "AUDIO") {
|
798
|
+
|
799
|
+
//kill play/pause button from miniplayer
|
800
|
+
$.each(mejsoptions.features, function (i) {
|
801
|
+
if (this === 'playpause') {
|
802
|
+
mejsoptions.features.splice(i, 1);
|
803
|
+
}
|
804
|
+
});
|
805
|
+
|
806
|
+
wrapper.prepend('<div class="podlovewebplayer_meta"></div>');
|
807
|
+
|
808
|
+
wrapper.find('.podlovewebplayer_meta').prepend('<a class="bigplay" title="Play Episode" href="#"></a>');
|
809
|
+
if (params.poster !== undefined) {
|
810
|
+
wrapper.find('.podlovewebplayer_meta').append(
|
811
|
+
'<div class="coverart"><img class="coverimg" src="' + params.poster + '" data-img="' + params.poster + '" alt=""></div>');
|
812
|
+
}
|
813
|
+
if ($(player).attr('poster') !== undefined) {
|
814
|
+
wrapper.find('.podlovewebplayer_meta').append(
|
815
|
+
'<div class="coverart"><img src="' + $(player).attr('poster') + '" alt=""></div>');
|
816
|
+
}
|
817
|
+
}
|
818
|
+
|
819
|
+
if (player.tagName === "VIDEO") {
|
820
|
+
wrapper.prepend('<div class="podlovewebplayer_top"></div>');
|
821
|
+
wrapper.append('<div class="podlovewebplayer_meta"></div>');
|
822
|
+
}
|
823
|
+
|
824
|
+
if (params.title !== undefined) {
|
825
|
+
if (params.permalink !== undefined) {
|
826
|
+
wrapper.find('.podlovewebplayer_meta').append(
|
827
|
+
'<h3 class="episodetitle"><a href="' + params.permalink + '">' + params.title + '</a></h3>');
|
828
|
+
} else {
|
829
|
+
wrapper.find('.podlovewebplayer_meta').append(
|
830
|
+
'<h3 class="episodetitle">' + params.title + '</h3>');
|
831
|
+
}
|
832
|
+
}
|
833
|
+
if (params.subtitle !== undefined) {
|
834
|
+
wrapper.find('.podlovewebplayer_meta').append(
|
835
|
+
'<div class="subtitle">' + params.subtitle + '</div>');
|
836
|
+
} else {
|
837
|
+
if (params.title !== undefined) {
|
838
|
+
if (params.title.length < 42) {
|
839
|
+
wrapper.addClass('podlovewebplayer_smallplayer');
|
840
|
+
}
|
841
|
+
}
|
842
|
+
wrapper.find('.podlovewebplayer_meta').append(
|
843
|
+
'<div class="subtitle"></div>');
|
844
|
+
}
|
845
|
+
|
846
|
+
//always render toggler buttons wrapper
|
847
|
+
wrapper.find('.podlovewebplayer_meta').append('<div class="togglers"></div>');
|
848
|
+
wrapper.on('playerresize', function () {
|
849
|
+
wrapper.find('.podlovewebplayer_chapterbox').data('height', wrapper.find('.podlovewebplayer_chapters').height());
|
850
|
+
if (wrapper.find('.podlovewebplayer_chapterbox').hasClass('active')) {
|
851
|
+
wrapper.find('.podlovewebplayer_chapterbox').height(wrapper.find('.podlovewebplayer_chapters').height() + 'px');
|
852
|
+
}
|
853
|
+
wrapper.find('.summary').data('height', wrapper.find('.summarydiv').height());
|
854
|
+
if (wrapper.find('.summary').hasClass('active')) {
|
855
|
+
wrapper.find('.summary').height(wrapper.find('.summarydiv').height() + 'px');
|
856
|
+
}
|
857
|
+
});
|
858
|
+
|
859
|
+
if (params.summary !== undefined) {
|
860
|
+
var summaryActive = "";
|
861
|
+
if (params.summaryVisible === true) {
|
862
|
+
summaryActive = " active";
|
863
|
+
}
|
864
|
+
wrapper.find('.togglers').append(
|
865
|
+
'<a href="#" class="infowindow infobuttons pwp-icon-info-circle" title="More information about this"></a>');
|
866
|
+
wrapper.find('.podlovewebplayer_meta').after(
|
867
|
+
'<div class="summary' + summaryActive + '"><div class="summarydiv">' + params.summary + '</div></div>');
|
868
|
+
}
|
869
|
+
if (params.chapters !== undefined) {
|
870
|
+
wrapper.find('.togglers').append(
|
871
|
+
'<a href="#" class="chaptertoggle infobuttons pwp-icon-list-bullet" title="Show/hide chapters"></a>');
|
872
|
+
}
|
873
|
+
if (params.hidetimebutton !== true) {
|
874
|
+
wrapper.find('.togglers').append('<a href="#" class="showcontrols infobuttons pwp-icon-clock" title="Show/hide time navigation controls"></a>');
|
875
|
+
}
|
876
|
+
}
|
877
|
+
|
878
|
+
var timecontrolsActive = "";
|
879
|
+
if (params.timecontrolsVisible === true) {
|
880
|
+
timecontrolsActive = " active";
|
881
|
+
}
|
882
|
+
var sharebuttonsActive = "";
|
883
|
+
if (params.sharebuttonsVisible === true) {
|
884
|
+
sharebuttonsActive = " active";
|
885
|
+
}
|
886
|
+
var downloadbuttonsActive = "";
|
887
|
+
if (params.downloadbuttonsVisible === true) {
|
888
|
+
downloadbuttonsActive = " active";
|
889
|
+
}
|
890
|
+
|
891
|
+
wrapper.append('<div class="podlovewebplayer_timecontrol podlovewebplayer_controlbox' + timecontrolsActive + '"></div>');
|
892
|
+
|
893
|
+
if (params.chapters !== undefined) {
|
894
|
+
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>');
|
895
|
+
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>');
|
896
|
+
}
|
897
|
+
wrapper.find('.podlovewebplayer_timecontrol').append(
|
898
|
+
'<a href="#" class="rewindbutton infobuttons pwp-icon-fast-bw" title="Rewind 30 seconds"></a>');
|
899
|
+
wrapper.find('.podlovewebplayer_timecontrol').append('<a href="#" class="forwardbutton infobuttons pwp-icon-fast-fw" title="Fast forward 30 seconds"></a>');
|
900
|
+
if ((wrapper.closest('.podlovewebplayer_wrapper').find('.episodetitle a').attr('href') !== undefined) && (params.hidesharebutton !== true)) {
|
901
|
+
wrapper.append('<div class="podlovewebplayer_sharebuttons podlovewebplayer_controlbox' + sharebuttonsActive + '"></div>');
|
902
|
+
wrapper.find('.togglers').append('<a href="#" class="showsharebuttons infobuttons pwp-icon-export" title="Show/hide sharing controls"></a>');
|
903
|
+
wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" class="currentbutton infobuttons pwp-icon-link" title="Get URL for this"></a>');
|
904
|
+
wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="tweetbutton infobuttons pwp-icon-twitter" title="Share this on Twitter"></a>');
|
905
|
+
wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="fbsharebutton infobuttons pwp-icon-facebook" title="Share this on Facebook"></a>');
|
906
|
+
wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="gplusbutton infobuttons pwp-icon-gplus" title="Share this on Google+"></a>');
|
907
|
+
wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="adnbutton infobuttons pwp-icon-appnet" title="Share this on App.net"></a>');
|
908
|
+
wrapper.find('.podlovewebplayer_sharebuttons').append('<a href="#" target="_blank" class="mailbutton infobuttons pwp-icon-mail" title="Share this via e-mail"></a>');
|
909
|
+
}
|
910
|
+
if (((params.downloads !== undefined) || (params.sources !== undefined)) && (params.hidedownloadbutton !== true)) {
|
911
|
+
var size, name, selectform = '<select name="downloads" class="fileselect" size="1" onchange="this.value=this.options[this.selectedIndex].value;">';
|
912
|
+
wrapper.append('<div class="podlovewebplayer_downloadbuttons podlovewebplayer_controlbox' + downloadbuttonsActive + '"></div>');
|
913
|
+
wrapper.find('.togglers').append('<a href="#" class="showdownloadbuttons infobuttons pwp-icon-download" title="Show/hide download bar"></a>');
|
914
|
+
if (params.downloads !== undefined) {
|
915
|
+
for (i = 0; i < params.downloads.length; i += 1) {
|
916
|
+
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';
|
917
|
+
selectform += '<option value="' + params.downloads[i].url + '" data-url="' + params.downloads[i].url + '" data-dlurl="' + params.downloads[i].dlurl + '">' + params.downloads[i].name + ' (<small>' + size + '</small>)</option>';
|
918
|
+
}
|
919
|
+
} else {
|
920
|
+
for (i = 0; i < params.sources.length; i += 1) {
|
921
|
+
name = params.sources[i].split('.');
|
922
|
+
name = name[name.length - 1];
|
923
|
+
selectform += '<option value="' + params.sources[i] + '" data-url="' + params.sources[i] + '" data-dlurl="' + params.sources[i] + '">' + name + '</option>';
|
924
|
+
}
|
925
|
+
}
|
926
|
+
|
927
|
+
selectform += '</select>';
|
928
|
+
wrapper.find('.podlovewebplayer_downloadbuttons').append(selectform);
|
929
|
+
if (params.downloads !== undefined) {
|
930
|
+
wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="#" class="downloadbutton infobuttons pwp-icon-download" title="Download"></a> ');
|
931
|
+
}
|
932
|
+
wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="#" class="openfilebutton infobuttons pwp-icon-link-ext" title="Open"></a> ');
|
933
|
+
wrapper.find('.podlovewebplayer_downloadbuttons').append('<a href="#" class="fileinfobutton infobuttons pwp-icon-info-circle" title="Info"></a> ');
|
934
|
+
}
|
935
|
+
|
936
|
+
//build chapter table
|
937
|
+
if (params.chapters !== undefined) {
|
938
|
+
haschapters = true;
|
939
|
+
|
940
|
+
generateChapterTable(params).appendTo(wrapper);
|
941
|
+
}
|
942
|
+
|
943
|
+
if (richplayer || haschapters) {
|
944
|
+
wrapper.append('<div class="podlovewebplayer_tableend"></div>');
|
945
|
+
}
|
946
|
+
|
947
|
+
// parse deeplink
|
948
|
+
deepLink = parseTimecode(window.location.href);
|
949
|
+
if (deepLink !== false && players.length === 1) {
|
950
|
+
if (document.hidden !== undefined) {
|
951
|
+
hiddenTab = document.hidden;
|
952
|
+
} else if (document.mozHidden !== undefined) {
|
953
|
+
hiddenTab = document.mozHidden;
|
954
|
+
} else if (document.msHidden !== undefined) {
|
955
|
+
hiddenTab = document.msHidden;
|
956
|
+
} else if (document.webkitHidden !== undefined) {
|
957
|
+
hiddenTab = document.webkitHidden;
|
958
|
+
}
|
959
|
+
|
960
|
+
if(hiddenTab === true) {
|
961
|
+
$(player).attr({
|
962
|
+
preload: 'auto'
|
963
|
+
});
|
964
|
+
} else {
|
965
|
+
$(player).attr({
|
966
|
+
preload: 'auto',
|
967
|
+
autoplay: 'autoplay'
|
968
|
+
});
|
969
|
+
}
|
970
|
+
startAtTime = deepLink[0];
|
971
|
+
stopAtTime = deepLink[1];
|
972
|
+
} else if (params && params.permalink) {
|
973
|
+
var storageKey = 'podloveWebPlayerTime-' + params.permalink;
|
974
|
+
if (localStorage[storageKey]) {
|
975
|
+
$(player).one('canplay', function() {
|
976
|
+
this.currentTime = +localStorage[storageKey];
|
977
|
+
});
|
978
|
+
}
|
979
|
+
}
|
980
|
+
|
981
|
+
$(player).on('ended', function() {
|
982
|
+
localStorage.removeItem('podloveWebPlayerTime-' + params.permalink);
|
983
|
+
});
|
984
|
+
|
985
|
+
// init MEJS to player
|
986
|
+
mejsoptions.success = function (player) {
|
987
|
+
addBehavior(player, params, wrapper);
|
988
|
+
if (deepLink !== false && players.length === 1) {
|
989
|
+
$('html, body').delay(150).animate({
|
990
|
+
scrollTop: $('.podlovewebplayer_wrapper:first').offset().top - 25
|
991
|
+
});
|
992
|
+
}
|
993
|
+
};
|
994
|
+
|
995
|
+
$(orig).replaceWith(wrapper);
|
996
|
+
$(player).mediaelementplayer(mejsoptions);
|
997
|
+
});
|
998
|
+
};
|
999
|
+
}(jQuery));
|