Skip to content

Commit

Permalink
DVR support
Browse files Browse the repository at this point in the history
  • Loading branch information
frankyghost committed Nov 17, 2013
1 parent 18ef3bb commit 56e131d
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 27 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
PROJEKKTOR - simply mighty <video>
http://www.projekktor.com


V1.3.04
=======

additions:
* [model:OSMF] added DVR support
* [plugin:controlbar] added "go live" button
* [plugin:controlbar] scrubber tooltip know shows relative time on DVR

fixes:
* [core] proper restore of user quality prefs for dynamic streams


V1.3.03
=======

fixes:
* [core] improper request for undefined poster images removed


V1.3.02
=======

Expand Down
14 changes: 10 additions & 4 deletions src/controller/projekktor.js
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,13 @@ projekktor = $p = function() {
this._addGUIListeners();
}
break;


case 'streamTypeChange':
if (value=='dvr') {
this.getDC().addClass(this.getNS() + 'dvr');
}
this._promote(type, value);
break;
default:
this._promote(type, value);
break;
Expand Down Expand Up @@ -1855,10 +1861,10 @@ projekktor = $p = function() {
this.media[this._currentItem].errorCode = 8;
} else {
// apply item specific class(es) to player
if (this.getConfig('className', null)!=null)
if (this.getConfig('className', null)!=null) {
this.getDC().addClass(this.getNS() + this.getConfig('className'))
this.getDC().addClass(this.getNS() + (this.getConfig('streamType') || 'http') );
}
this.getDC().addClass(this.getNS() + (this.getConfig('streamType') || 'http') );

if (!$p.utils.cssTransitions()) this.getDC().addClass('notransitions')
if (this.getIsMobileClient()) this.getDC().addClass('mobile')
Expand Down
18 changes: 8 additions & 10 deletions src/models/player.audio.video.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ $p.newModel({
loadstart: null
},

isGingerbread: false,
isGingerbread: false,
allowRandomSeek: false,
videoWidth: 0,
Expand All @@ -48,10 +49,8 @@ $p.newModel({

init: function() {
var ua = navigator.userAgent;
if( ua.indexOf("Android") >= 0 )
{
if (parseFloat(ua.slice(ua.indexOf("Android")+8)) < 3)
{
if( ua.indexOf("Android") >= 0 ) {
if (parseFloat(ua.slice(ua.indexOf("Android")+8)) < 3) {
this.isGingerbread = true;
}
}
Expand All @@ -60,14 +59,13 @@ $p.newModel({


applyMedia: function(destContainer) {

if ($('#'+this.pp.getMediaId()+"_html").length===0) {
this.wasPersistent = false;
destContainer.html('').append(
$('<video/>')
.attr({
"id": this.pp.getMediaId()+"_html",
"poster": (this.pp.getIsMobileClient('ANDROID')) ? this.getPoster() : $p.utils.imageDummy(),
"poster": $p.utils.imageDummy(),
"loop": false,
"autoplay": false,
"x-webkit-airplay": "allow"
Expand Down Expand Up @@ -103,7 +101,7 @@ $p.newModel({
var src = $('<source/>');
src.attr('src', this.src);
if (!ref.isGingerbread) {
src.attr('type', this.type);
src.attr('type', this.originalType );
}
src.appendTo(ref.mediaElement);
});
Expand Down Expand Up @@ -332,9 +330,9 @@ $p.newModel({
iosVersion: 4,
iLove: [
{ext:'m3u8', type:'application/mpegURL', platform: ['ios', 'android'], streamType: ['http','httpVideo', 'httpVideoLive']},
{ext:'m3u', type:'application/mpegURL', platform: ['ios', 'android'], streamType: ['http', 'httpVideo', 'httpVideoLive']},
// {ext:'m3u8', type:'vnd.apple.mpegURL', platform:'ios'},
// {ext:'m3u', type:'vnd.apple.mpegURL', platform:'ios'},
{ext:'m3u', type:'application/mpegURL', platform: ['ios', 'android'], streamType: ['http', 'httpVideo', 'httpVideoLive']},
{ext:'m3u8', type:'application/vnd.apple.mpegURL', platform: ['ios', 'android'], streamType: ['http','httpVideo', 'httpVideoLive']},
{ext:'m3u', type:'application/vnd.apple.mpegURL', platform: ['ios', 'android'], streamType: ['http', 'httpVideo', 'httpVideoLive']},
{ext:'ts', type:'video/MP2T', platforms: ['ios' ,'android'], streamType: ['http', 'httpVideo', 'httpVideoLive']}
]
}, 'VIDEO');
Expand Down
47 changes: 38 additions & 9 deletions src/models/player.audio.video.osmf.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ $p.newModel({
{ext:'f4v', type:'video/mp4', platform:'flash', streamType: ['*']},
{ext:'mov', type:'video/quicktime', platform:'flash', streamType: ['*']},
{ext:'m4v', type:'video/mp4', platform:'flash', fixed: true, streamType: ['*']},
{ext:'f4m', type:'application/f4m+xml', platform:'flash', fixed: true, streamType: ['*']},
{ext:'m3u8', type:'application/mpegURL', platform:'flash', fixed: true, streamType: ['*']}
{ext:'f4m', type:'application/f4m+xml', platform:'flash', fixed: true, streamType: ['*']}
// {ext:'m3u8', type:'application/mpegURL', platform:'flash', fixed: true, streamType: ['*']}
],

hasGUI: false,
Expand All @@ -35,6 +35,7 @@ $p.newModel({
availableQualities: {},

_isStream: false,
_isDVR: false,
_isMuted: false,
_isStarted: false,
_qualitySwitching: false,
Expand Down Expand Up @@ -87,6 +88,7 @@ $p.newModel({
playButtonOverlay: false,
// showVideoInfoOverlayOnStartUp: true,
// dvrSnapToLiveClockOffset: "5",
autoDynamicStreamSwitch: false,
bufferingOverlay: false,
javascriptCallbackFunction: 'window.projekktorOSMFReady'+this.pp.getId()
}, this.pp.getConfig('OSMFVars'))
Expand Down Expand Up @@ -170,7 +172,10 @@ $p.newModel({
this.timeListener({position: this.media.position, duration: value || 0 });
},

OSMF_currentTimeChange: function(value) {
OSMF_currentTimeChange: function(value) {
if (this._isDVR) {
this.sendUpdate('isLive', (value+20 >= this.media.duration)); // 20 => default dvr buffer of SMP
}
this.timeListener({position: value, duration: this.media.duration || 0 });
},

Expand Down Expand Up @@ -201,14 +206,31 @@ $p.newModel({
}
},

/* catching playStateChange and playerStateChange */
/* catching playStateChange and playerStateChange and playerStateChange aaaand... and playerStateChange */
OSMF_playerStateChange: function(state) {
var ref = this;

// getIsDVR & getIsDVRLive seem to be broken - workaround:
if (!this._isDVR && this.mediaElement.get(0).getStreamType()=='dvr') {
this._isDVR = true;
this.sendUpdate('streamTypeChange', 'dvr');
}

switch(state) {
case 'playing':
this.playingListener();
break;
case 'paused':
this.pauseListener();
if (this._isDVR) {
// simulate sliding time window:
(function() {
if (ref.media.position>=0.5) {
ref.timeListener({position: ref.media.position-0.5, duration: ref.media.duration || 0 });
setTimeout(arguments.callee, 500);
}
})();
}
break;
case 'stopped':
if (!this.getSeekState('SEEKING')) {
Expand All @@ -218,13 +240,12 @@ $p.newModel({
}
},

/* todo */
OSMF_updateDynamicStream: function() {
var dynamicStreams = this.mediaElement.get(0).getStreamItems(),
name = '',
result = [];
// switchMode = this.mediaElement.get(0).getAutoDynamicStreamSwitch() ? "Auto" : "Manual";

for (var index in dynamicStreams) {
if (dynamicStreams.hasOwnProperty(index) && dynamicStreams[index].bitrate!==undefined) {
name = dynamicStreams[index].width + "x" + dynamicStreams[index].height;
Expand All @@ -243,8 +264,8 @@ $p.newModel({

result.push('auto');

this.sendUpdate('availableQualitiesChange', result);
this._isDynamicStream = true;
this._isDynamicStream = true; // important: set this before sending the update
this.sendUpdate('availableQualitiesChange', result);
},

/* todo */
Expand Down Expand Up @@ -297,7 +318,11 @@ $p.newModel({
this.applySrc();
return;
}


if (newpos==-1) {
newpos = this.getDuration();
}

this.mediaElement.get(0).seek(newpos);
},

Expand Down Expand Up @@ -351,6 +376,10 @@ $p.newModel({
} catch(e) {return null;}
},

getQuality: function () {
return this._quality;
},

/************************************************
* disablers
************************************************/
Expand Down
6 changes: 5 additions & 1 deletion src/models/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ jQuery(function ($) {
/*******************************
ELEMENT GETTERS
*******************************/
getQuality: function () {
return this._quality;
},

getVolume: function () {
if (this.mediaElement==null) {
return this._volume;
Expand Down Expand Up @@ -700,7 +704,7 @@ jQuery(function ($) {
$p.utils.blockSelection(imageObj);

// empty URL... apply placeholder
if (url === '' || url === undefined) {
if (url == null || url === false) {
return $('<span/>').attr({
"id": this.pp.getMediaId() + "_image"
}).appendTo(destObj);
Expand Down
41 changes: 38 additions & 3 deletions src/plugins/projekktor.controlbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ var projekktorControlbar = function () {};
jQuery(function ($) {
projekktorControlbar.prototype = {

version: '1.1.00',
version: '1.1.01',

_cTimer: null,
_isDVR: false,
_noHide: false,
_vSliderAct: false,

Expand Down Expand Up @@ -49,6 +50,13 @@ jQuery(function ($) {
call: null
},
'loaded': null, // { on:['touchstart', 'click'], call:'scrubberClk'},
'golive': [{
on: ['touchstart', 'click'],
call: 'goliveClk'
}, {
on: ['touchend'],
call: 'touchEnd'
}],
'scrubber': null, // { on:['touchstart', 'click'], call:'scrubberClk'},
'scrubbertip': null,
'scrubberknob': null,
Expand Down Expand Up @@ -773,7 +781,6 @@ jQuery(function ($) {
},

stateHandler: function (state) {

this.updateDisplay();

if ('STOPPED|AWAKENING|IDLE|DONE'.indexOf(state) > -1) {
Expand Down Expand Up @@ -827,6 +834,21 @@ jQuery(function ($) {
qualityChangeHandler: function (qual) {
this.displayQualityToggle(qual);
},

streamTypeChangeHandler: function (streamType) {
if (streamType=='dvr') {
this._isDVR = true;
this.setActive(this.controlElements['golive'], true);
}
},

isLiveHandler: function (islive) {
if (islive) {
this.controlElements['golive'].addClass('on').removeClass('off');
} else {
this.controlElements['golive'].addClass('off').removeClass('on');
}
},

fullscreenHandler: function (inFullscreen) {

Expand Down Expand Up @@ -900,6 +922,10 @@ jQuery(function ($) {
this.pp.setPlaybackQuality($(evt.currentTarget).data('qual'));
},

goliveClk: function (evt) {
this.pp.setSeek(-1);
},

playClk: function (evt) {
this.pp.setPlay();
},
Expand Down Expand Up @@ -1035,7 +1061,16 @@ jQuery(function ($) {
pageX = (evt.originalEvent.touches) ? evt.originalEvent.touches[0].pageX : evt.pageX,
pageY = (evt.originalEvent.touches) ? evt.originalEvent.touches[0].pageY : evt.pageY,
newPos = pageX - slider.offset().left - (tip.outerWidth() / 2),
times = this._clockDigits(this.pp.getDuration() / 100 * ((pageX - slider.offset().left) * 100 / slider.width()), 'tip');
timeIdx = this.pp.getDuration() / 100 * ((pageX - slider.offset().left) * 100 / slider.width()),
times = this._clockDigits(timeIdx, 'tip');

if (this._isDVR) {
timeIdx = this.pp.getDuration() - timeIdx;
var then = new Date( (new Date().getTime() / 1000 - timeIdx) * 1000), // date minus timeidx
then = then.getSeconds() + (60 * then.getMinutes()) + (60 * 60 * then.getHours()); // second of today

times = this._clockDigits( then , 'tip');
}

for (var key in this.controlElements) {
if (key == 'cb')
Expand Down

0 comments on commit 56e131d

Please sign in to comment.