From 93cb27fa423063895e54193e90ebfc5914c9ba0f Mon Sep 17 00:00:00 2001 From: Sascha Kluger Date: Tue, 22 Oct 2013 16:23:16 +0200 Subject: [PATCH] quality update event for dynamic streams --- CHANGELOG.md | 2 + src/controller/projekktor.js | 38 ++++++++------ src/models/player.audio.video.osmf.js | 28 ++++++++-- src/plugins/projekktor.display.js | 74 ++++++++++++--------------- 4 files changed, 81 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e875e11..df2826b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,14 @@ V1.2.39 addtions: * [core] added OSMF player model + * [core] "streamType" can now be specified separately for each alternate media entry of a playlist item (allows mixing e.g. of RTMP, HTTP for one single playlist item) fixes: * [core] fixed jQuery 1.4 issues changes: * [core] made OSMF player model default + * [core] missing or broken plugins are now reported via an alert() diff --git a/src/controller/projekktor.js b/src/controller/projekktor.js index 3838dcb..be9c444 100644 --- a/src/controller/projekktor.js +++ b/src/controller/projekktor.js @@ -386,7 +386,7 @@ projekktor = $p = function() { }); } } - + extRegEx = '^.*\.(' + extRegEx.join('|') + ")$"; // incoming file is a string only, no array @@ -411,8 +411,7 @@ projekktor = $p = function() { if (typeof data.file[index]=='string') { data.file[index] = {'src':data.file[index]}; } - - + // nothing to do, next one if (data.file[index].src==null) { continue; @@ -433,18 +432,20 @@ projekktor = $p = function() { if (codecMatch[1]!=null) { data.file[index].codec = codecMatch[1]; } - data.file[index].type = codecMatch[0]; // .replace(/x-/, ''); - // data.file[index].originalType = codecMatch[0]; + data.file[index].type = codecMatch[0].replace(/x-/, ''); + data.file[index].originalType = codecMatch[0]; } catch(e){} } else { data.file[index].type = this._getTypeFromFileExtension( data.file[index].src ); } - - if (typesModels[data.file[index].type] .length>0) { - typesModels[data.file[index].type] .sort(function(a, b) { + + if (typesModels[data.file[index].type] && typesModels[data.file[index].type].length>0) { + + typesModels[data.file[index].type].sort(function(a, b) { return a.level - b.level; - }); + }); + modelSets.push(typesModels[data.file[index].type] [0]); } } @@ -459,14 +460,14 @@ projekktor = $p = function() { modelSets.sort(function(a, b) { return a.level - b.level; }); - + bestMatch = modelSets[0].level; modelSets = $.grep(modelSets, function(value) { return value.level == bestMatch; }); } - + types = []; $.each(modelSets || [], function() { types.push(this.type); @@ -599,6 +600,11 @@ projekktor = $p = function() { modelRef.start(); }); break; + + case 'availableQualitiesChange': + this.media[this._currentItem].qualities = value; + this._promote('availableQualitiesChange', value); + break; case 'qualityChange': this.setConfig({playbackQuality: value}); @@ -1627,9 +1633,9 @@ projekktor = $p = function() { return this.playerModel.getMediaDimensions() || {width:0, height:0}; }; - this.getAppropriateQuality = function() { - return this._getAppropriateQuality(this.media[this._currentItem].qualities || []) - } + this.getAppropriateQuality = function() { + return this._getAppropriateQuality(this.media[this._currentItem].qualities || []) + } this._getAppropriateQuality = function(quals) { @@ -2778,7 +2784,7 @@ projekktor = $p = function() { result.playlist[0].push({ src: childNode.attr('src'), type: childNode.attr('type') || this._getTypeFromFileExtension(childNode.attr('src')), - quality: childNode.attr('data-quality') || '' + quality: childNode.attr('data-quality') || '' }); break; case 'TRACK': @@ -2805,7 +2811,7 @@ projekktor = $p = function() { result.playlist[0].push({ src: $(this).attr('src'), type: $(this).attr('type') || ref._getTypeFromFileExtension($(this).attr('src')), - quality: $(this).attr('data-quality') || '' + quality: $(this).attr('data-quality') || '' }); break; case 'TRACK': diff --git a/src/models/player.audio.video.osmf.js b/src/models/player.audio.video.osmf.js index edafc5d..f36a371 100644 --- a/src/models/player.audio.video.osmf.js +++ b/src/models/player.audio.video.osmf.js @@ -16,6 +16,7 @@ $p.newModel({ flashVersion: "10.1", flashVerifyMethod: 'addEventListener', + iLove: [ {ext:'flv', type:'video/flv', platform:'flash', fixed: true, streamType: ['*']}, {ext:'mp4', type:'video/mp4', platform:'flash', streamType: ['*']}, @@ -31,6 +32,8 @@ $p.newModel({ isPseudoStream: false, streamType: 'http', + availableQualities: {}, + _isStream: false, _isMuted: false, _isStarted: false, @@ -215,10 +218,19 @@ $p.newModel({ }, /* todo */ - OSMF_updateDynamicStream: function() { + OSMF_updateDynamicStream: function() { var dynamicStreams = this.mediaElement.get(0).getStreamItems(), - switchMode = this.mediaElement.get(0).getAutoDynamicStreamSwitch() ? "Auto" : "Manual"; - // console.log("OSMF_updateDynamicStream", switchMode, dynamicStreams) + name = ''; + // 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; + this.availableQualities[ this.pp.getConfig('OSMFQualityMap') ? this.pp.getConfig('OSMFQualityMap')[name] || name : name] = index; + } + } + + this.sendUpdate('availableQualitiesChange', this.availableQualities); }, /* todo */ @@ -234,8 +246,14 @@ $p.newModel({ }, errorListener: function() { - if (arguments[0]!==0) { - this.sendUpdate('error', arguments[0]); + switch (arguments[0]) { + case 16: + this.sendUpdate('error', 80); + break; + + default: + // this.sendUpdate('error', 0); + break; } }, diff --git a/src/plugins/projekktor.display.js b/src/plugins/projekktor.display.js index 602736e..514c2e9 100644 --- a/src/plugins/projekktor.display.js +++ b/src/plugins/projekktor.display.js @@ -35,7 +35,7 @@ projekktorDisplay.prototype = { staticControls: false, /* time to delay buffering-icon-overlay once "waiting" event has been triggered */ - bufferIconDelay: 1000, + bufferIconDelay: 1, /* if set the indicator animation is tinkered from a cssprite - must be horizontal */ spriteUrl: '', @@ -50,45 +50,39 @@ projekktorDisplay.prototype = { /* triggered on plugin-instanciation */ initialize: function() { - // create the display container itself - this.display = this.applyToPlayer($('
')); - - // create the startbutton - this.startButton = this.applyToPlayer( $('
').addClass('start'), 'startbtn'); - - // create buffericon - this.buffIcn = this.applyToPlayer( $('
').addClass('buffering'), 'buffericn'); + // create the display container itself + this.display = this.applyToPlayer($('
')); + + // create the startbutton + this.startButton = this.applyToPlayer( $('
').addClass('start'), 'startbtn'); - this.imaContainer = this.applyToPlayer( $('
').addClass('ima'), 'ima'); - - - + // create buffericon + this.buffIcn = this.applyToPlayer( $('
').addClass('buffering'), 'buffericn'); + + this.imaContainer = this.applyToPlayer( $('
').addClass('ima'), 'ima'); + this.setActive(); - // add spritelayer to buffericon (if required) - if (this.config.spriteUrl!=='') { - this.buffIcnSprite = $('
') - .appendTo(this.buffIcn) - .css({ - width: this.config.spriteWidth, - height: this.config.spriteHeight, - marginLeft: ((this.buffIcn.width()-this.config.spriteWidth) / 2)+"px", - marginTop: ((this.buffIcn.height()-this.config.spriteHeight) / 2)+"px", - backgroundColor: 'transparent', - backgroundImage: 'url('+this.config.spriteUrl+')', - backgroundRepeat: 'no-repeat', - backgroundPosition: '0 0' - }) - .addClass('inactive'); + // add spritelayer to buffericon (if required) + if (this.config.spriteUrl!=='') { + this.buffIcnSprite = $('
') + .appendTo(this.buffIcn) + .css({ + width: this.config.spriteWidth, + height: this.config.spriteHeight, + marginLeft: ((this.buffIcn.width()-this.config.spriteWidth) / 2)+"px", + marginTop: ((this.buffIcn.height()-this.config.spriteHeight) / 2)+"px", + backgroundColor: 'transparent', + backgroundImage: 'url('+this.config.spriteUrl+')', + backgroundRepeat: 'no-repeat', + backgroundPosition: '0 0' + }) + .addClass('inactive'); } - // create a dedicated media container (if none exists) - this.pp.getMediaContainer(); - /* - this.display - .append(this.startButton) - .append(this.buffIcn) -*/ + // create a dedicated media container (if none exists) + this.pp.getMediaContainer(); + this.pluginReady = true; }, @@ -150,7 +144,7 @@ projekktorDisplay.prototype = { break; case 'AWAKENING': - // this.hideBufferIcon();; + this.showBufferIcon(); this.hideStartButton(); break; @@ -301,7 +295,7 @@ projekktorDisplay.prototype = { if (this.buffIcn.hasClass('active') ) return; this.buffIcn.addClass('active').removeClass('inactive'); - if (ref.buffIcnSprite==null) return; + if (ref.buffIcnSprite===null) return; var startOffset=(ref.config.spriteCountUp===true) ? 0 : (ref.config.spriteHeight + ref.config.spriteOffset)*(ref.config.spriteTiles-1), spriteOffset = startOffset; @@ -309,7 +303,7 @@ projekktorDisplay.prototype = { (function() { if (!ref.buffIcn.is(':visible')) return; - ref.buffIcnSprite.css('backgroundPosition', '0px -'+spriteOffset+"px") + ref.buffIcnSprite.css('backgroundPosition', '0px -'+spriteOffset+"px"); if (ref.config.spriteCountUp===true) spriteOffset += ref.config.spriteHeight + ref.config.spriteOffset; @@ -323,5 +317,5 @@ projekktorDisplay.prototype = { })(); } -} -}); +}; +}); \ No newline at end of file