Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
02560be
VP-211: First draft for the new version of VideoPlayer to work with U…
anvk Feb 28, 2013
c1450b7
VP-211: Creating a separate transcript menu languages array in a mode…
anvk Mar 4, 2013
53d215f
VP-211: Do not allow to initialize unisub if there are no links to th…
anvk Mar 5, 2013
c93087d
VP-211: Making uniSub component to work with Amara api 2.0
anvk Mar 5, 2013
4ce84ac
VP-211: Amara component will try to get captions only from the first …
anvk Mar 7, 2013
8cd58ed
VP-211: First working version of video player which queries amara for…
anvk Mar 11, 2013
349b267
VP-211: Removing unused flag. Do not call requestChange for captions …
anvk Mar 11, 2013
b384b92
VP-211: First attempt to fix video player tests.
anvk Mar 11, 2013
f4f6e43
VP-282: Updating the README for the 0.1 release
jobara Feb 28, 2013
4eb8e6d
VP-282: Fixing a typo in the readme.
michelled Feb 28, 2013
abe30ff
VP-283: updating the licence info for captionator
jobara Feb 28, 2013
f07847c
VP-282: Updating the known issues
jobara Mar 4, 2013
82b22ec
VP-290: Fixing failing VideoPlayerShowHide-test
anvk Mar 11, 2013
0488d2f
VP-287
kmithemanth Mar 8, 2013
81f19fe
VP-211: Fixing up transcripts to use languages and captions pulled fr…
anvk Mar 11, 2013
f9b89a6
VP-211: More UniSub component refactoring. Trying to use free functio…
anvk Mar 12, 2013
544a360
VP-211: A tiny step towards unisub integration tests.
anvk Mar 15, 2013
c37ebf0
VP-211: Finally a working test for a delayed language caption retrieval
anvk Mar 15, 2013
95a94f5
VP-211: Adding more structure to the UniSub component. Changing integ…
anvk Mar 18, 2013
57fb6b3
Merge branch 'umaster' into VP-211
anvk Mar 18, 2013
c645cbc
VP-211: Adding more tests for UniSub component. Adding extra function…
anvk Mar 18, 2013
a7b2da5
VP-211: Renaming "UniSub" to be a "subtitlesFinder" component
anvk Mar 18, 2013
e907342
VP-211: Merging master branch with its latest changes. Fixing up test…
anvk Mar 26, 2013
12d1a5f
VP-211: Cleanup files from my changes which were put temporarily for …
anvk Mar 26, 2013
4d8e90a
VP-211: Refactoring subtitleFinder to use DataSource component.
anvk Mar 27, 2013
a9f073b
VP-211: Me and Justin, refactoring subtitleFinder component and refac…
anvk Apr 4, 2013
4bf4f2e
VP-211: Refactoring integration tests in order to comply with a new s…
anvk Apr 4, 2013
5d024dd
VP-211: Made few cleanups and quick changes after Justin's review
anvk Apr 4, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions demos/VideoPlayer.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
<script type="text/javascript" src="../js/VideoPlayer_controllers.js"></script>
<script type="text/javascript" src="../js/ToggleButton.js"></script>
<script type="text/javascript" src="../js/MenuButton.js"></script>
<script type="text/javascript" src="../js/DataSource.js"></script>
<script type="text/javascript" src="../js/VideoPlayer_subtitlesFinder.js"></script>
<script type="text/javascript" src="../js/VideoPlayer_media.js"></script>
<script type="text/javascript" src="../js/VideoPlayer_transcript.js"></script>
<script type="text/javascript" src="../js/VideoPlayer_intervalEventsConductor.js"></script>
Expand Down Expand Up @@ -100,13 +102,13 @@ <h1>Infusion HTML 5 Video Player</h1>
src: "http://www.youtube.com/watch?v=_VxQEPw1x9E&language=en",
type: "text/amarajson",
srclang: "en",
label: "English"
label: "English local"
},
{
src: "videos/ReorganizeFuture/ReorganizeFuture.fr.vtt",
type: "text/vtt",
srclang: "fr",
label: "French"
label: "French local"
}
],
transcripts: [
Expand All @@ -119,13 +121,13 @@ <h1>Infusion HTML 5 Video Player</h1>
//src: "videos/ReorganizeFuture/ReorganizeFuture.transcripts.en.json",
//type: "JSONcc",
srclang: "en",
label: "English"
label: "English local"
},
{
src: "videos/ReorganizeFuture/ReorganizeFuture.transcripts.fr.json",
type: "JSONcc",
srclang: "fr",
label: "French"
label: "French local"
}
]
},
Expand Down
60 changes: 60 additions & 0 deletions js/DataSource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright 2012 OCAD University
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copyright data should be 2013


Licensed under the Educational Community License (ECL), Version 2.0 or the New
BSD license. You may not use this file except in compliance with one these
Licenses.

You may obtain a copy of the ECL 2.0 License and BSD License at
https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
*/

/*global jQuery, window, fluid*/

// JSLint options
/*jslint white: true, funcinvoke: true, undef: true, newcap: true, nomen: true, regexp: true, bitwise: true, browser: true, forin: true, maxerr: 100, indent: 4 */

(function () {

fluid.defaults("fluid.dataSource", {
gradeNames: ["autoInit", "fluid.eventedComponent", "fluid.modelComponent"],
events: {
onError: null,
onSuccess: null
},
invokers: {
get: "fluid.dataSource.get",
dataParse: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be written simply as:
dataParse: "fluid.dataSource.dataPrase"

funcName: "fluid.dataSource.dataParse",
args: ["{arguments}.0"]
}
},
model: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why these are in a model, instead of plain default options.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because those values could be changed potentially. There could be the case when the same dataSource would be used to query 2 different webservices. In that case we want to change those values and according to our conventions options block has settings which do not change when state of the component changes

dataType: "jsonp", // Default ajax data type
params: {}, // parameters which will be added to the url
baseURL: null // url where the call will be made
},
timeout: 10000 // do not allow jsonp to halt. max timeout request
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is mandatory for jsonp requests. By default they could query indefinitely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be in members then.

});

fluid.dataSource.dataParse = function (data) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is how the function looks like, default invoker implementation should be fluid.identity.

return data;
};

fluid.dataSource.get = function (that) {
var events = that.events,
model = that.model;

$.ajax({
dataType: /* "jsonp", */model.dataType,
url: model.baseURL,
data: model.params,
timeout : that.options.timeout
}).done(function (data) {
events.onSuccess.fire(that.dataParse(data));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should parse on a separate line to have a possibility of seeing the result.

}).fail(function () {
events.onError.fire();
});
};

})();
23 changes: 15 additions & 8 deletions js/MenuButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ var fluid_1_5 = fluid_1_5 || {};
postInitFunction: "fluid.videoPlayer.languageMenu.postInit",
finalInitFunction: "fluid.videoPlayer.languageMenu.finalInit",
produceTree: "fluid.videoPlayer.languageMenu.produceTree",
languages: [],
currentLanguagePath: "activeLanguages",
showHidePath: "showLanguage",
model: {},
Expand All @@ -48,7 +47,8 @@ var fluid_1_5 = fluid_1_5 || {};
},
activated: null,
hiddenByKeyboard: null,
onControlledElementReady: null
onControlledElementReady: null,
onLanguageListUpdated: null
},
listeners: {
onControlledElementReady: {
Expand Down Expand Up @@ -80,14 +80,12 @@ var fluid_1_5 = fluid_1_5 || {};
// TODO: Could this be specified declaratively, in a "protoTree" option?
// Ans: not very effectively... the renderer still needs to be burned to the ground
fluid.videoPlayer.languageMenu.produceTree = function (that) {
// Silly damn renderer with its crazy JSON idiolect!
that.model.languages = that.options.languages;
var tree = {
// create a menu item for each language in the model
expander: {
type: "fluid.renderer.repeat",
repeatID: "language",
controlledBy: "languages",
controlledBy: that.options.languageListPath,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a meaningful default, even if it's an empty array.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

languageListPath points to an empty arrays in the model of a VideoPlayer for transcripts and captions

pathAs: "lang",
tree: {
value: "${{lang}.label}",
Expand Down Expand Up @@ -216,6 +214,12 @@ var fluid_1_5 = fluid_1_5 || {};
fluid.videoPlayer.languageMenu.bindEventListeners(that);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most if not all contents of this final init function should be eliminated. We can use default component events such as onCreate or onAttach to finish up initialization.

fluid.videoPlayer.languageMenu.setUpKeyboardA11y(that);

that.events.onLanguageListUpdated.addListener(function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be defined in defaults rather than in final init function.

that.refreshView();
fluid.videoPlayer.languageMenu.bindEventListeners(that);
fluid.videoPlayer.languageMenu.setUpKeyboardA11y(that);
});

that.container.attr("role", "menu");
that.container.css("z-index", 9999);
that.hideMenu();
Expand Down Expand Up @@ -243,6 +247,8 @@ var fluid_1_5 = fluid_1_5 || {};
onReady: null,
onRenderingComplete: null,
onControlledElementReady: null,
onLanguageListUpdated: null,

afterFetchResources: null
},
listeners: {
Expand All @@ -251,9 +257,9 @@ var fluid_1_5 = fluid_1_5 || {};
priority: "last"
}
},
languages: [],
currentLanguagePath: "",
showHidePath: "",
languageListPath: "",
strings: {
showLanguage: "Show Language",
hideLanguage: "Hide Language"
Expand Down Expand Up @@ -286,13 +292,14 @@ var fluid_1_5 = fluid_1_5 || {};
container: "{languageControls}.dom.menu",
options: {
model: "{languageControls}.model",
languages: "{languageControls}.options.languages",
applier: "{languageControls}.applier",
showHidePath: "{languageControls}.options.showHidePath",
currentLanguagePath: "{languageControls}.options.currentLanguagePath",
languageListPath: "{languageControls}.options.languageListPath",
strings: "{languageControls}.options.strings",
events: {
onControlledElementReady: "{languageControls}.events.onControlledElementReady"
onControlledElementReady: "{languageControls}.events.onControlledElementReady",
onLanguageListUpdated: "{languageControls}.events.onLanguageListUpdated"
}
}
},
Expand Down
91 changes: 76 additions & 15 deletions js/VideoPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ var fluid_1_5 = fluid_1_5 || {};
model: "{videoPlayer}.model",
applier: "{videoPlayer}.applier",
events: {
onLoadedMetadata: "{videoPlayer}.events.onLoadedMetadata"
onLoadedMetadata: "{videoPlayer}.events.onLoadedMetadata",
onTimeUpdate: "{intervalEventsConductor}.events.onTimeUpdate"
},
listeners: {
onExitFullScreen: {
Expand Down Expand Up @@ -165,7 +166,9 @@ var fluid_1_5 = fluid_1_5 || {};
onScrub: "{videoPlayer}.events.onScrub",
afterScrub: "{videoPlayer}.events.afterScrub",
onTranscriptsReady: "{videoPlayer}.events.canBindTranscriptMenu",
onCaptionsReady: "{videoPlayer}.events.canBindCaptionMenu"
onCaptionsReady: "{videoPlayer}.events.canBindCaptionMenu",
onCaptionListUpdated: "{videoPlayer}.events.onCaptionListUpdated",
onTranscriptListUpdated: "{videoPlayer}.events.onTranscriptListUpdated"
},
listeners: {
onReady: "{videoPlayer}.events.onControllersReady"
Expand All @@ -178,7 +181,19 @@ var fluid_1_5 = fluid_1_5 || {};
html5Captionator: {
type: "fluid.videoPlayer.captionator",
container: "{videoPlayer}.dom.videoPlayer",
createOnEvent: "onMediaReady"
createOnEvent: "onSubtitlesFinderReady"
},
subtitlesFinder: {
type: "fluid.subtitlesFinder",
createOnEvent: "onMediaReady",
options: {
sources: "{videoPlayer}.options.video.sources",
serviceURL: "https://www.universalsubtitles.org/api2/partners/videos/",
languagesPath: "objects.0.languages",
events: {
onReady: "{videoPlayer}.events.onSubtitlesFinderReady"
}
}
}
},
preInitFunction: "fluid.videoPlayer.preInit",
Expand Down Expand Up @@ -209,6 +224,15 @@ var fluid_1_5 = fluid_1_5 || {};
args: ["{videoPlayer}"]
},

onCaptionListUpdated: null,
onTranscriptListUpdated: null,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user is probably interested in |onSubtitlesFinderReadyBoiled| event rather than |onSubtitlesFinderReady| we should probably rename this to have something like this:
onSubtitlesFinderReadyBoiled -> onSubtitlesFinderReady
onSubtitlesFinderReady -> onSubtitlesFinderReadyBoiledInternal

onSubtitlesFinderReady: null,
onSubtitlesFinderReadyBoiled: {
event: "onSubtitlesFinderReady",
args: ["{videoPlayer}", "{arguments}.0"]
},

// public, time events
onTimeUpdate: null,

Expand Down Expand Up @@ -281,7 +305,9 @@ var fluid_1_5 = fluid_1_5 || {};
volume: 60,
muted: false,
canPlay: false,
play: false
play: false,
captions: [],
transcripts: []
},
templates: {
videoPlayer: {
Expand Down Expand Up @@ -465,6 +491,12 @@ var fluid_1_5 = fluid_1_5 || {};
that.toggleFullscreen = function () {
that.applier.requestChange("fullscreen", !that.model.fullscreen);
};

// This is the place when we move integrator specified captions and transcripts into the model of a VideoPlayer
// This model could be potentially extended by some other components like subtitlesFinder
// Also we agreed on keeping things simple for an integrator where an integrator lists options without touching videoPlayer model.
that.model.captions = fluid.copy(that.options.video.captions);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this can go into members. If not, we can express these two lines with a mergePolicy.

that.model.transcripts = fluid.copy(that.options.video.transcripts);
};

fluid.videoPlayer.postInit = function (that) {
Expand Down Expand Up @@ -500,9 +532,49 @@ var fluid_1_5 = fluid_1_5 || {};
};
};

fluid.videoPlayer.uniqueMergeArray = function(firstArray, secondArray, elPath) {
var languageArray = [], i;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use makeArray here.

firstArray = firstArray || [];
secondArray = secondArray || [];

var result = firstArray.concat(secondArray);
result = fluid.remove_if(result, function (elem) {
var srclang = fluid.get(elem, elPath);
if (srclang === undefined) {
return;
}

if (languageArray.indexOf(srclang) > -1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only supported in IE9+. Should use $.inArray

return elem;
}
languageArray.push(srclang);
});

return result;
};

fluid.videoPlayer.extendLanguages = function(that, captionData) {
captionData = captionData || [];
if (captionData.length === 0) {
return;
}

// Apply uniqueMergeArray for captions and transcripts based on the captionData returned from the subtitlesFinder component
fluid.each(["captions", "transcripts"], function (type) {
var tempData = fluid.copy(captionData);
fluid.videoPlayer.addDefaultKind(tempData, fluid.get(that.options.defaultKinds, type));
tempData = fluid.videoPlayer.uniqueMergeArray(fluid.get(that.model, type), tempData, "srclang");
that.applier.requestChange(type, tempData);
});
};

fluid.videoPlayer.finalInit = function (that) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This final init function should only contain model/applier binding material. Everything else should be moved out into onCreate or onAttach. The fetchResources call should result in an event firing and the callback should be registered through the defaults and bind to a global function.

that.container.attr("role", "application");

that.applier.modelChanged.addListener("captions", that.events.onCaptionListUpdated.fire);
that.applier.modelChanged.addListener("transcripts", that.events.onTranscriptListUpdated.fire);
that.events.onSubtitlesFinderReadyBoiled.addListener(fluid.videoPlayer.extendLanguages);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be defined in defaults.


// Render each media source with its custom renderer, registered by type.
// If we aren't on an HTML 5 video-enabled browser, don't bother setting up the controller, captions or transcripts.

Expand Down Expand Up @@ -662,16 +734,5 @@ var fluid_1_5 = fluid_1_5 || {};
funcName: "fluid.videoPlayer.hideControllersSimple",
args: ["{videoPlayer}"]
});

/***************************************************************************************************
* The wiring up of the onTimeUpdate event btw timer component "media" and intervalEventsConductor *
***************************************************************************************************/
fluid.demands("fluid.videoPlayer.media", ["fluid.videoPlayer.intervalEventsConductor", "fluid.videoPlayer"], {
options: {
events: {
onTimeUpdate: "{intervalEventsConductor}.events.onTimeUpdate"
}
}
});

})(jQuery, fluid_1_5);
11 changes: 9 additions & 2 deletions js/VideoPlayer_controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ var fluid_1_5 = fluid_1_5 || {};
model: "{controllers}.model",
applier: "{controllers}.applier",
showHidePath: "displayTranscripts",
languageListPath: "transcripts",
currentLanguagePath: "currentTracks.transcripts",
styles: {
button: "fl-videoPlayer-transcripts-button",
Expand All @@ -115,7 +116,8 @@ var fluid_1_5 = fluid_1_5 || {};
},
events: {
onControlledElementReady: "{controllers}.events.onTranscriptsReady",
onReady: "{controllers}.events.onTranscriptControlsReady"
onReady: "{controllers}.events.onTranscriptControlsReady",
onLanguageListUpdated: "{controllers}.events.onTranscriptListUpdated"
},
templates: {
menuButton: {
Expand Down Expand Up @@ -167,6 +169,9 @@ var fluid_1_5 = fluid_1_5 || {};
onStartTimeChange: null,
afterTimeChange: null,
onMarkupReady: null,
onCaptionListUpdated: null,
onTranscriptListUpdated: null,

onScrub: null,
onStartScrub: null,
afterScrub: null,
Expand Down Expand Up @@ -257,6 +262,7 @@ var fluid_1_5 = fluid_1_5 || {};
applier: "{controllers}.applier",
showHidePath: "displayCaptions",
currentLanguagePath: "currentTracks.captions",
languageListPath: "captions",
styles: {
button: "fl-videoPlayer-captions-button",
buttonWithShowing: "fl-videoPlayer-captions-button-on"
Expand All @@ -268,7 +274,8 @@ var fluid_1_5 = fluid_1_5 || {};
release: "Captions"
},
events: {
onControlledElementReady: "{controllers}.events.onCaptionsReady"
onControlledElementReady: "{controllers}.events.onCaptionsReady",
onLanguageListUpdated: "{controllers}.events.onCaptionListUpdated"
},
templates: {
menuButton: {
Expand Down
4 changes: 2 additions & 2 deletions js/VideoPlayer_html5Captionator.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ https://source.fluidproject.org/svn/LICENSE.txt
var display = that.readIndirect("elPaths.displayCaptions");
if (display) {
fluid.videoPlayer.html5Captionator.showCurrentTrack(that.readIndirect("elPaths.currentCaptions"),
tracks, that.options.captions);
tracks, that.options.model.captions);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, should probably be in members and be referred to as that.captions

} else {
fluid.videoPlayer.html5Captionator.hideAllTracks(tracks);
}
Expand All @@ -92,7 +92,7 @@ https://source.fluidproject.org/svn/LICENSE.txt
};

fluid.videoPlayer.html5Captionator.finalInit = function (that) {
var captions = that.options.captions;
var captions = that.options.model.captions;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, should probably be in members and be referred to as that.captions


// Need to know when all the tracks have been created so we can trigger captionator
that.tracksToCreate = captions.length;
Expand Down
Loading