Skip to content

Commit f531264

Browse files
authored
Merge pull request jplayer#391 from happyworm/feature/logarithmic-volume
Feature/logarithmic volume
2 parents 823e735 + 4be1519 commit f531264

File tree

1 file changed

+47
-34
lines changed

1 file changed

+47
-34
lines changed

src/javascript/jplayer/jquery.jplayer.js

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@
495495
supplied: "mp3", // Defines which formats jPlayer will try and support and the priority by the order. 1st is highest,
496496
auroraFormats: "wav", // List the aurora.js codecs being loaded externally. Its core supports "wav". Specify format in jPlayer context. EG., The aac.js codec gives the "m4a" format.
497497
preload: 'metadata', // HTML5 Spec values: none, metadata, auto.
498-
volume: 0.512, // The volume. Number 0 to 1. 0.512 (logarithmic) == 0.8 (percentile).
498+
volume: 0.8, // The volume. Number 0 to 1.
499499
volumePower: 3, // The factor use for logarithmic volume control. Recommended = 3. Higher values create a sharper curve. See http://dr-lex.be/info-stuff/volumecontrols.html
500500
muted: false,
501501
remainingDuration: false, // When true, the remaining time is shown in the duration GUI element.
@@ -505,7 +505,7 @@
505505
defaultPlaybackRate: 1,
506506
minPlaybackRate: 0.5,
507507
maxPlaybackRate: 4,
508-
wmode: "opaque", // Valid wmode: window, transparent, opaque, direct, gpu.
508+
wmode: "opaque", // Valid wmode: window, transparent, opaque, direct, gpu.
509509
backgroundColor: "#000000", // To define the jPlayer div and Flash background color.
510510
cssSelectorAncestor: "#jp_container_1",
511511
cssSelector: { // * denotes properties that should only be required when video media type required. _cssSelector() would require changes to enable splitting these into Audio and Video defaults.
@@ -578,6 +578,7 @@
578578
iemobile: /iemobile/,
579579
webos: /webos/
580580
},
581+
useLogarithmicVolume: false, // When set true, makes silent end of the volume bar less sensitive, and the loud end of the volume bar more sensitive
581582
noVolume: {
582583
ipad: /ipad/,
583584
iphone: /iphone/,
@@ -815,9 +816,9 @@
815816
},
816817
_init: function() {
817818
var self = this;
818-
819+
819820
this.element.empty();
820-
821+
821822
this.status = $.extend({}, this.status); // Copy static to unique instance.
822823
this.internal = $.extend({}, this.internal); // Copy static to unique instance.
823824

@@ -848,7 +849,7 @@
848849
this.formats = []; // Array based on supplied string option. Order defines priority.
849850
this.solutions = []; // Array based on solution string option. Order defines priority.
850851
this.require = {}; // Which media types are required: video, audio.
851-
852+
852853
this.htmlElement = {}; // DOM elements created by jPlayer
853854
this.html = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array.
854855
this.html.audio = {};
@@ -857,7 +858,7 @@
857858
this.aurora.formats = [];
858859
this.aurora.properties = [];
859860
this.flash = {}; // In _init()'s this.desired code and setmedia(): Accessed via this[solution], where solution from this.solutions array.
860-
861+
861862
this.css = {};
862863
this.css.cs = {}; // Holds the css selector strings
863864
this.css.jq = {}; // Holds jQuery selectors. ie., $(css.cs.method)
@@ -899,7 +900,7 @@
899900
}
900901
}
901902
});
902-
903+
903904
// Create Aurora.js formats array
904905
$.each(this.options.auroraFormats.toLowerCase().split(","), function(index1, value1) {
905906
var format = value1.replace(/^\s+|\s+$/g, ""); //trim
@@ -1004,7 +1005,7 @@
10041005
this.internal.poster.jq.bind("click.jPlayer", function() {
10051006
self._trigger($.jPlayer.event.click);
10061007
});
1007-
1008+
10081009
// Generate the required media elements
10091010
this.html.audio.available = false;
10101011
if(this.require.audio) { // If a supplied format is audio
@@ -1078,11 +1079,11 @@
10781079

10791080
// Set up the css selectors for the control and feedback entities.
10801081
this._cssSelectorAncestor(this.options.cssSelectorAncestor);
1081-
1082+
10821083
// If neither html nor aurora nor flash are being used by this browser, then media playback is not possible. Trigger an error event.
10831084
if(!(this.html.used || this.aurora.used || this.flash.used)) {
10841085
this._error( {
1085-
type: $.jPlayer.error.NO_SOLUTION,
1086+
type: $.jPlayer.error.NO_SOLUTION,
10861087
context: "{solution:'" + this.options.solution + "', supplied:'" + this.options.supplied + "'}",
10871088
message: $.jPlayer.errorMsg.NO_SOLUTION,
10881089
hint: $.jPlayer.errorHint.NO_SOLUTION
@@ -1102,7 +1103,7 @@
11021103
flashVars = 'jQuery=' + encodeURI(this.options.noConflict) + '&id=' + encodeURI(this.internal.self.id) + '&vol=' + this.options.volume + '&muted=' + this.options.muted;
11031104

11041105
// Code influenced by SWFObject 2.2: http://code.google.com/p/swfobject/
1105-
// Non IE browsers have an initial Flash size of 1 by 1 otherwise the wmode affected the Flash ready event.
1106+
// Non IE browsers have an initial Flash size of 1 by 1 otherwise the wmode affected the Flash ready event.
11061107

11071108
if($.jPlayer.browser.msie && (Number($.jPlayer.browser.version) < 9 || $.jPlayer.browser.documentMode < 9)) {
11081109
var objStr = '<object id="' + this.internal.flash.id + '" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="0" height="0" tabindex="-1"></object>';
@@ -1122,7 +1123,7 @@
11221123
} else {
11231124
var createParam = function(el, n, v) {
11241125
var p = document.createElement("param");
1125-
p.setAttribute("name", n);
1126+
p.setAttribute("name", n);
11261127
p.setAttribute("value", v);
11271128
el.appendChild(p);
11281129
};
@@ -1180,7 +1181,7 @@
11801181
});
11811182
}
11821183
}
1183-
1184+
11841185
// Add the Aurora.js solution if being used.
11851186
if(this.aurora.used) {
11861187
// Aurora.js player need to be created for each media, see setMedia function.
@@ -1249,7 +1250,7 @@
12491250
this.element.removeData("jPlayer"); // Remove jPlayer data
12501251
this.element.unbind(".jPlayer"); // Remove all event handlers created by the jPlayer constructor
12511252
this.element.empty(); // Remove the inserted child elements
1252-
1253+
12531254
delete this.instances[this.internal.instance]; // Clear the instance on the static instance object
12541255
},
12551256
destroyRemoved: function() { // Destroy any instances that have gone away.
@@ -1348,7 +1349,7 @@
13481349
// Create the event listeners
13491350
// Only want the active entity to affect jPlayer and bubble events.
13501351
// Using entity.gate so that object is referenced and gate property always current
1351-
1352+
13521353
mediaElement.addEventListener("progress", function() {
13531354
if(entity.gate) {
13541355
if(self.internal.cmdsIgnored && this.readyState > 0) { // Detect iOS executed the command
@@ -1508,7 +1509,7 @@
15081509
// Create the event listeners
15091510
// Only want the active entity to affect jPlayer and bubble events.
15101511
// Using entity.gate so that object is referenced and gate property always current
1511-
1512+
15121513
player.on("progress", function() {
15131514
if(entity.gate) {
15141515
if(self.internal.cmdsIgnored && this.readyState > 0) { // Detect iOS executed the command
@@ -1588,7 +1589,7 @@
15881589
sp = 100;
15891590
cpr = cpa;
15901591
}
1591-
1592+
15921593
if(override) {
15931594
ct = 0;
15941595
cpr = 0;
@@ -1624,7 +1625,7 @@
16241625
sp = 100;
16251626
cpr = cpa;
16261627
}
1627-
1628+
16281629
if(override) {
16291630
ct = 0;
16301631
cpr = 0;
@@ -1692,7 +1693,7 @@
16921693

16931694
// Need to read original status before issuing the setMedia command.
16941695
var currentTime = this.status.currentTime,
1695-
paused = this.status.paused;
1696+
paused = this.status.paused;
16961697

16971698
this.setMedia(this.status.media);
16981699
this.volumeWorker(this.options.volume);
@@ -1944,7 +1945,7 @@
19441945
}
19451946
},
19461947
setMedia: function(media) {
1947-
1948+
19481949
/* media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats.
19491950
* media.poster = String: Video poster URL.
19501951
* media.track = Array: Of objects defining the track element: kind, src, srclang, label, def.
@@ -2012,7 +2013,7 @@
20122013
}
20132014
self.status.video = false;
20142015
}
2015-
2016+
20162017
supported = true;
20172018
return false; // Exit $.each
20182019
}
@@ -2266,7 +2267,11 @@
22662267
}
22672268
},
22682269
volume: function(v) {
2269-
v = Math.pow(v,this.options.volumePower);
2270+
// v is treated differently depending on whether useLogarithmicVolume is 'on'.
2271+
if (this.options.useLogarithmicVolume) {
2272+
v = Math.pow(v,this.options.volumePower);
2273+
}
2274+
22702275
this.volumeWorker(v);
22712276
if(this.options.globalVolume) {
22722277
this.tellOthers("volumeWorker", function() {
@@ -2338,7 +2343,12 @@
23382343
}
23392344
if(this.css.jq.volumeBarValue.length) {
23402345
this.css.jq.volumeBarValue.show();
2341-
this.css.jq.volumeBarValue[this.options.verticalVolume ? "height" : "width"]((Math.pow(v,1/this.options.volumePower)*100)+"%");
2346+
2347+
if (this.options.useLogarithmicVolume) {
2348+
this.css.jq.volumeBarValue[this.options.verticalVolume ? "height" : "width"]((Math.pow(v,1/this.options.volumePower)*100)+"%");
2349+
} else {
2350+
this.css.jq.volumeBarValue[this.options.verticalVolume ? "height" : "width"]((v*100)+"%");
2351+
}
23422352
}
23432353
if(this.css.jq.volumeMax.length) {
23442354
this.css.jq.volumeMax.show();
@@ -2389,7 +2399,7 @@
23892399
if(cssSel) { // Checks for empty string
23902400
this.css.jq[fn] = $(this.css.cs[fn]);
23912401
} else {
2392-
this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set.
2402+
this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set.
23932403
}
23942404

23952405
if(this.css.jq[fn].length && this[fn]) {
@@ -2718,6 +2728,9 @@
27182728
case "autoBlur" :
27192729
this.options[key] = value;
27202730
break;
2731+
case "useLogarithmicVolume" :
2732+
this.options[key] = value;
2733+
break;
27212734
}
27222735

27232736
return this;
@@ -2781,7 +2794,7 @@
27812794
//get the change from last position to this position
27822795
deltaX = self.internal.mouse.x - event.pageX;
27832796
deltaY = self.internal.mouse.y - event.pageY;
2784-
moved = (Math.floor(deltaX) > 0) || (Math.floor(deltaY)>0);
2797+
moved = (Math.floor(deltaX) > 0) || (Math.floor(deltaY)>0);
27852798
} else {
27862799
moved = true;
27872800
}
@@ -3097,19 +3110,19 @@
30973110
}
30983111
},
30993112
_aurora_setAudio: function(media) {
3100-
var self = this;
3101-
3113+
var self = this;
3114+
31023115
// Always finds a format due to checks in setMedia()
31033116
$.each(this.formats, function(priority, format) {
31043117
if(self.aurora.support[format] && media[format]) {
31053118
self.status.src = media[format];
31063119
self.status.format[format] = true;
31073120
self.status.formatType = format;
3108-
3121+
31093122
return false;
31103123
}
31113124
});
3112-
3125+
31133126
this.aurora.player = new AV.Player.fromURL(this.status.src);
31143127
this._addAuroraEventListeners(this.aurora.player, this.aurora);
31153128

@@ -3143,7 +3156,7 @@
31433156
}
31443157
this.status.waitForLoad = false;
31453158
this._aurora_checkWaitForPlay();
3146-
3159+
31473160
// No event from the player, update UI now.
31483161
this._updateButtons(true);
31493162
this._trigger($.jPlayer.event.play);
@@ -3153,11 +3166,11 @@
31533166
this.aurora.player.seek(time * 1000);
31543167
}
31553168
this.aurora.player.pause();
3156-
3169+
31573170
if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button.
31583171
this._aurora_checkWaitForPlay();
31593172
}
3160-
3173+
31613174
// No event from the player, update UI now.
31623175
this._updateButtons(false);
31633176
this._trigger($.jPlayer.event.pause);
@@ -3167,7 +3180,7 @@
31673180
// The seek() sould be in milliseconds, but the only codec that works with seek (aac.js) uses seconds.
31683181
this.aurora.player.seek(percent * this.aurora.player.duration / 100); // Using seconds
31693182
}
3170-
3183+
31713184
if(!this.status.waitForLoad) {
31723185
this._aurora_checkWaitForPlay();
31733186
}
@@ -3233,7 +3246,7 @@
32333246
break;
32343247
case "rtmpv":
32353248
self._getMovie().fl_setVideo_rtmp(media[format]);
3236-
break;
3249+
break;
32373250
}
32383251
self.status.src = media[format];
32393252
self.status.format[format] = true;

0 commit comments

Comments
 (0)