Skip to content

Commit 43848d1

Browse files
committed
Add support for YouTube captions
1 parent aa9149c commit 43848d1

17 files changed

Lines changed: 3815 additions & 251 deletions

Gruntfile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ module.exports = function(grunt) {
3535
'scripts/search.js',
3636
'scripts/event.js',
3737
'scripts/dragdrop.js',
38-
'scripts/sign.js'
38+
'scripts/sign.js',
39+
'scripts/langs.js'
3940
],
4041
dest: 'build/<%= pkg.name %>.js'
4142
},

build/ableplayer.dist.js

Lines changed: 1259 additions & 79 deletions
Large diffs are not rendered by default.

build/ableplayer.js

Lines changed: 1260 additions & 80 deletions
Large diffs are not rendered by default.

build/ableplayer.min.css

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/ableplayer.min.js

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ableplayer",
3-
"version": "2.1.4",
3+
"version": "2.1.5",
44
"repository": {
55
"type": "git",
66
"url": "https://github.com/ableplayer/ableplayer.git"

scripts/ableplayer-base.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
1818
// YouTube Player API for iframe Embeds
1919
https://developers.google.com/youtube/iframe_api_reference
20+
// YouTube Player Parameters
21+
https://developers.google.com/youtube/player_parameters?playerVersion=HTML5
2022
*/
2123

2224
/*jslint node: true, browser: true, white: true, indent: 2, unparam: true, plusplus: true */

scripts/buildplayer.js

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
(function ($) {
2+
23
AblePlayer.prototype.injectPlayerCode = function() {
34
// create and inject surrounding HTML structure
45
// If IOS:
@@ -27,8 +28,11 @@
2728
this.injectOffscreenHeading();
2829

2930
// youtube adds its own big play button
30-
if (this.mediaType === 'video' && this.player !== 'youtube') {
31-
this.injectBigPlayButton();
31+
// if (this.mediaType === 'video' && this.player !== 'youtube') {
32+
if (this.mediaType === 'video') {
33+
if (this.player !== 'youtube') {
34+
this.injectBigPlayButton();
35+
}
3236

3337
// add container that captions or description will be appended to
3438
// Note: new Jquery object must be assigned _after_ wrap, hence the temp vidcapContainer variable
@@ -37,7 +41,7 @@
3741
});
3842
this.$vidcapContainer = this.$mediaContainer.wrap(vidcapContainer).parent();
3943
}
40-
44+
4145
this.injectPlayerControlArea();
4246
this.injectTextDescriptionArea();
4347

@@ -390,11 +394,23 @@
390394
radioName, radioId, trackButton, trackLabel;
391395

392396
popups = [];
393-
if (this.captions.length > 0) {
394-
popups.push('captions');
397+
398+
if (typeof this.ytCaptions !== 'undefined') {
399+
// special call to this function for setting up a YouTube caption popup
400+
if (this.ytCaptions.length) {
401+
popups.push('ytCaptions');
402+
}
403+
else {
404+
return false;
405+
}
395406
}
396-
if (this.chapters.length > 0) {
397-
popups.push('chapters');
407+
else {
408+
if (this.captions.length > 0) {
409+
popups.push('captions');
410+
}
411+
if (this.chapters.length > 0) {
412+
popups.push('chapters');
413+
}
398414
}
399415
if (popups.length > 0) {
400416
thisObj = this;
@@ -409,6 +425,10 @@
409425
this.chaptersPopup = this.createPopup('chapters');
410426
tracks = this.chapters;
411427
}
428+
else if (popup == 'ytCaptions') {
429+
this.captionsPopup = this.createPopup('captions');
430+
tracks = this.ytCaptions;
431+
}
412432
var trackList = $('<ul></ul>');
413433
radioName = this.mediaId + '-' + popup + '-choice';
414434
for (j in tracks) {
@@ -431,11 +451,9 @@
431451
if (track.language !== 'undefined') {
432452
trackButton.attr('lang',track.language);
433453
}
434-
if (popup == 'captions') {
454+
if (popup == 'captions' || popup == 'ytCaptions') {
435455
trackLabel.text(track.label || track.language);
436456
trackButton.click(this.getCaptionClickFunction(track));
437-
//trackButton.click(this.handleCaptionRadioSelect(track));
438-
// trackButton.keypress(function() { alert('hey!');});
439457
}
440458
else if (popup == 'chapters') {
441459
trackLabel.text(this.flattenCueForCaption(track) + ' - ' + this.formatSecondsAsColonTime(track.start));
@@ -452,7 +470,7 @@
452470
trackItem.append(trackButton,trackLabel);
453471
trackList.append(trackItem);
454472
}
455-
if (popup == 'captions') {
473+
if (popup == 'captions' || popup == 'ytCaptions') {
456474
// add a captions off button
457475
radioId = this.mediaId + '-captions-off';
458476
trackItem = $('<li></li>');
@@ -473,7 +491,7 @@
473491
// check the first button
474492
trackList.find('input').first().attr('checked','checked');
475493
}
476-
if (popup == 'captions') {
494+
if (popup == 'captions' || popup == 'ytCaptions') {
477495
this.captionsPopup.append(trackList);
478496
}
479497
else if (popup == 'chapters') {
@@ -626,10 +644,12 @@
626644
}
627645
else if (this.controls[i] === 'captions') {
628646
if (this.captions.length > 1) {
647+
console.log('There is more than one caption');
629648
// caption button launches a Captions popup menu
630649
label = this.tt.captions;
631650
}
632651
else {
652+
console.log('There is only one caption');
633653
// there is only one caption track
634654
// therefore caption button is a toggle
635655
if (this.captionsOn) {
@@ -777,6 +797,7 @@
777797
};
778798

779799
AblePlayer.prototype.addControls = function() {
800+
780801
// determine which controls to show based on several factors:
781802
// mediaType (audio vs video)
782803
// availability of tracks (e.g., for closed captions & audio description)
@@ -798,7 +819,7 @@
798819
var controlLayout = this.calculateControlLayout();
799820

800821
var sectionByOrder = {0: 'ul', 1:'ur', 2:'bl', 3:'br'};
801-
822+
802823
// add an empty div to serve as a tooltip
803824
tooltipId = this.mediaId + '-tooltip';
804825
tooltipDiv = $('<div>',{
@@ -1142,7 +1163,6 @@
11421163
this.media.load();
11431164
}
11441165
else if (this.player === 'jw') {
1145-
console.log('this.jwPlayer.load');
11461166
this.jwPlayer.load({file: jwSource});
11471167
}
11481168
else if (this.player === 'youtube') {
@@ -1153,6 +1173,9 @@ console.log('this.jwPlayer.load');
11531173
};
11541174

11551175
AblePlayer.prototype.getButtonTitle = function(control) {
1176+
1177+
var captionsCount;
1178+
11561179
if (control === 'playpause') {
11571180
return this.tt.play;
11581181
}
@@ -1172,11 +1195,22 @@ console.log('this.jwPlayer.load');
11721195
return this.tt.forward;
11731196
}
11741197
else if (control === 'captions') {
1175-
if (this.captionsOn) {
1176-
return this.tt.hideCaptions;
1198+
if (this.usingYouTubeCaptions) {
1199+
captionsCount = this.ytCaptions.length;
1200+
}
1201+
else {
1202+
captionsCount = this.captions.length;
1203+
}
1204+
if (captionsCount > 1) {
1205+
return this.tt.captions;
11771206
}
11781207
else {
1179-
return this.tt.showCaptions;
1208+
if (this.captionsOn) {
1209+
return this.tt.hideCaptions;
1210+
}
1211+
else {
1212+
return this.tt.showCaptions;
1213+
}
11801214
}
11811215
}
11821216
else if (control === 'descriptions') {

scripts/caption.js

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,64 @@
11
(function ($) {
2-
AblePlayer.prototype.updateCaption = function (time) {
3-
if (this.captionsOn) {
4-
this.$captionDiv.show();
5-
this.showCaptions(time || this.getElapsed());
6-
}
7-
else if (this.$captionDiv) {
8-
this.$captionDiv.hide();
2+
AblePlayer.prototype.updateCaption = function (time) {
3+
if (!this.usingYouTubeCaptions) {
4+
if (this.captionsOn) {
5+
this.$captionDiv.show();
6+
this.showCaptions(time || this.getElapsed());
7+
}
8+
else if (this.$captionDiv) {
9+
this.$captionDiv.hide();
10+
}
911
}
1012
};
1113

1214
// Returns the function used when a caption is clicked in the captions menu.
1315
AblePlayer.prototype.getCaptionClickFunction = function (track) {
1416
var thisObj = this;
1517
return function () {
16-
thisObj.captionsOn = true;
18+
console.log('caption click?');
1719
thisObj.selectedCaptions = track;
1820
thisObj.captionLang = track.language;
1921
thisObj.currentCaption = -1;
20-
// Try and find a matching description track.
21-
for (var ii in thisObj.descriptions) {
22-
if (thisObj.descriptions[ii].language === track.language) {
23-
thisObj.selectedDescriptions = thisObj.descriptions[ii];
24-
thisObj.currentDescription = -1;
22+
if (thisObj.usingYouTubeCaptions) {
23+
if (thisObj.captionsOn) {
24+
// captions are already on. Just need to change the language
25+
thisObj.youTubePlayer.setOption(thisObj.ytCaptionModule, 'track', {'languageCode': thisObj.captionLang});
2526
}
27+
else {
28+
// captions are off (i.e., captions module has been unloaded; need to reload it)
29+
// user's selected language will be reset after module has successfully loaded
30+
// (the onApiChange event will be fired -- see initialize.js > initYouTubePlayer())
31+
thisObj.resettingYouTubeCaptions = true;
32+
thisObj.youTubePlayer.loadModule(thisObj.ytCaptionModule);
33+
}
2634
}
35+
else {
36+
// Try and find a matching description track for rebuilding transcript
37+
for (var ii in thisObj.descriptions) {
38+
if (thisObj.descriptions[ii].language === track.language) {
39+
thisObj.selectedDescriptions = thisObj.descriptions[ii];
40+
thisObj.currentDescription = -1;
41+
}
42+
}
43+
thisObj.updateCaption();
44+
thisObj.updateDescription();
45+
}
46+
thisObj.captionsOn = true;
2747
thisObj.hidingPopup = true;
2848
thisObj.captionsPopup.hide();
2949
thisObj.$ccButton.focus();
3050
thisObj.refreshControls();
31-
thisObj.updateCaption();
32-
thisObj.updateDescription();
3351
}
3452
};
3553

3654
// Returns the function used when the "Captions Off" button is clicked in the captions tooltip.
3755
AblePlayer.prototype.getCaptionOffFunction = function () {
3856
var thisObj = this;
3957
return function () {
58+
console.log('caption off function?');
59+
if (thisObj.player == 'youtube') {
60+
thisObj.youTubePlayer.unloadModule(thisObj.ytCaptionModule);
61+
}
4062
thisObj.captionsOn = false;
4163
thisObj.currentCaption = -1;
4264
thisObj.captionsPopup.hide();

0 commit comments

Comments
 (0)