3 'remoto!stdlib:js/panes/pane.js',
4 'remoto!stdlib:js/include/objectRegistry.js',
5 'remoto!stdlib:js/include/utils.js',
34 var attrs = [
"src",
"controls",
"loop",
"muted",
"poster",
"play",
"volume",
"restart",
"chapter",
"feedback"];
35 var boolTags = [
"controls",
"loop",
"muted"];
36 var chapterEpsilon = .5;
51 pane.call(
this,layout);
59 this._controls =
null;
65 this._chapterTrack =
null;
68 this._activityPulse =
null;
69 this._firstLoad =
false;
70 this._feedback =
true;
71 this._playbutton =
null;
85 if (this._html)
return this._html;
89 this._video = $(
"<video>").appendTo(this._content);
90 this._video.attr(
"id",
"video_"+
utils.
uuid() );
91 this._videoE = this._video[0];
95 "background-color":
"black",
103 'error':
function() { console.log(
"video error"); },
130 var detachPlaystate = !this._videoE.paused;
133 var inserted = (
function(e) {
134 if (jQuery.contains(document.documentElement,
this._videoE))
135 this.
play = detachPlaystate;
136 $(
'body').unbind(
'DOMNodeInserted',inserted);
139 $(
'body').bind(
'DOMNodeInserted',inserted);
171 if (this._subscribed)
174 this._subscribed =
true;
180 return this._objectLoader.fetchDefinition( data.base, data,
this.applyDiff.bind(
this) );
201 if (
"attributes" in diff)
202 diff = diff.attributes;
206 if ( attrs.indexOf(a) > -1)
209 {
case "play": this.
play = diff.play.value;
break;
210 case "volume": this.
volume = diff.volume.value;
break;
211 case "muted": this.
muted = diff.muted.value;
break;
212 case "loop": this.
loop = diff.loop.value;
break;
214 case "feedback":this._feedback = !!diff.feedback.value;
break;
216 case "chapter":
if (
'options' in diff.chapter)
217 this.
buildChapters(diff.chapter.options.options,diff.chapter.value);
218 this.
chapter = diff.chapter.value;
221 case "src": this._src = diff.src.value;
223 for (var mime in this._src)
224 $(
"<source>").attr({
type:mime,src:this._src[mime]}).appendTo(this._video);
225 this._content.trigger(
"paneLoadStart");
228 default:
this[
"_"+a] = diff[a].value;
229 if (boolTags.indexOf(a) > -1)
230 {
if (diff[a].
value) this._video.attr(a,
true);
231 else this._video.removeAttr(a);
234 this._video.attr(a,diff[a].
value);
272 this.
play = this._play;
274 if (!this._firstLoad)
275 { this._content.trigger(
"paneLoadComplete");
276 this._firstLoad =
true;
279 this._content.find(
".videoError").remove();
300 this._videoE.src = this._videoE.currentSrc;
304 if (!this._loop && this._feedback)
306 var u = { attributes: {
play: {
value:
false } } };
323 console.error(
"Video load error!");
324 console.log(arguments);
328 if (!this._firstLoad)
329 { this._content.trigger(
"paneLoadComplete");
330 this._firstLoad =
true;
347 if (this._play !== (!this._videoE.paused))
350 var p = this.
play = !this._videoE.paused;
351 var u = { attributes: {
play: {
value: p } } };
368 if (this._volume !== this._videoE.volume)
370 var v = this.
volume = this._videoE.volume;
379 if (this._muted !== this._videoE.muted)
381 var m = this.
muted = this._videoE.muted;
383 var u = { attributes: {
muted: {
value: m } } };
405 videoPane.prototype.__defineSetter__(
"play",
function(p)
412 let startPlayPromise = this._videoE.play();
414 if (startPlayPromise !== undefined) {
415 startPlayPromise.then(() => {
419 if (
error.name ===
"NotAllowedError" &&
this._playbutton ==
null) {
420 if (!this._firstLoad)
421 { this._content.trigger(
"paneLoadComplete");
422 this._firstLoad = true;
425 this._playbutton = $(
"<button>").addClass(
"playButton").appendTo(
this._content);
426 this._playbutton.css({
427 position:
"absolute",
433 "background-repeat":
"no-repeat",
434 "background-color":
"transparent",
435 "background-size":
"contain",
436 "background-image":
"url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9JzMwMHB4JyB3aWR0aD0nMzAwcHgnICBmaWxsPSIjRkZGRkZGIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgNjAgNjAiIHg9IjBweCIgeT0iMHB4Ij48ZGVmcz48Y2xpcFBhdGggaWQ9ImEiPjxyZWN0IHdpZHRoPSI2MCIgaGVpZ2h0PSI2MCI+PC9yZWN0PjwvY2xpcFBhdGg+PC9kZWZzPjxnIGRhdGEtbmFtZT0iY3VzdG9tIOKAkyAyMCIgY2xpcC1wYXRoPSJ1cmwoI2EpIj48cGF0aCBkYXRhLW5hbWU9IlRyYWPDqSA5IiBkPSJNMTcuNzM1LDAsMzUuNDcsMzAuNzg1SDBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0NS43ODUgMTIpIHJvdGF0ZSg5MCkiPjwvcGF0aD48L2c+PC9zdmc+)"
439 this._playbutton.click(
function(){
442 that._playbutton = null;
448 if (!this._activityPulse)
449 { this._activityPulse = setInterval( (
function() { this._content.trigger(
"paneActivity"); }).bind(
this), 3000 );
451 this._content.trigger(
"paneActivity");
455 { this._videoE.pause();
456 if (this._activityPulse)
457 { clearInterval( this._activityPulse );
458 this._activityPulse =
null;
472 videoPane.prototype.__defineSetter__(
"volume",
function(v)
474 v = Math.min( Math.max( v, 0 ), 1 );
477 this._videoE.volume = v;
486 videoPane.prototype.__defineSetter__(
"muted",
function(m)
490 this._videoE.muted = m;
493 this._video.attr(
"muted",
true);
495 this._video.removeAttr(
"muted");
504 videoPane.prototype.__defineSetter__(
"loop",
function(l)
507 this._videoE.loop = l;
510 this._video.attr(
"loop",
true);
512 this._video.removeAttr(
"loop");
522 videoPane.prototype.__defineSetter__(
"currentTime",
function(t)
526 this._videoE.currentTime = t;
535 videoPane.prototype.__defineSetter__(
"chapter",
function(c)
539 if (this._chapter != c || Math.abs(
this._videoE.currentTime - c) > chapterEpsilon)
540 if ( c < this._videoE.duration)
548 if (Math.abs(
this._videoE.currentTime - c) > chapterEpsilon)
581 if (!this._chapterTrack)
582 { this._chapterTrack = this._videoE.addTextTrack(
"chapters");
586 $(this._chapterTrack).bind(
"cuechange",
function(e) {
590 if (THIS._chapterTrack.activeCues.length)
591 { var cue = THIS._chapterTrack.activeCues[0];
592 THIS.chapter = cue.startTime;
600 while (this._chapterTrack.cues.length)
601 this._chapterTrack.removeCue( this._chapterTrack.cues[0] );
604 for (var i=0;i<chapters.length;i++)
609 var s = chapters[i].value;
610 var e = i < chapters.length - 1 ? chapters[i+1].value - .001 : 10000000;
611 var cue =
new VTTCue( s, e, chapters[i].
text );
612 this._chapterTrack.addCue( cue );
622 console.error(
"Unable to create chapters... sorry.");
637 if (this._activityPulse)
638 { clearInterval( this._activityPulse );
639 this._activityPulse =
null;
645 this._playbutton =
null;
setter play
a setter DOCME
setter chapter
a setter DOCME
setter value
a setter DOCME
setter volume
a setter DOCME
setter type
a setter DOCME
applyDiff(id, diff, user, except)
setter postUpdate
Assign a callback to the paneFactory class for VFS_node::submit() commands.
Create a pane which will be mounted into a paneManager layout.
Utility functions for javascript clients.
uuid()
Generate a universally unique identifier.
The videoPane will create a <video> tag and manage its settings.
videoPane(layout)
videoPane constructor
setter muted
a setter DOCME
setter loop
a setter DOCME
buildChapters(chapters, chapter)
setter currentTime
a setter DOCME
applySubscription(data, metadata)