Re: Two Issues: Two sets of controls and Trouble with Chrome, Safari

131 views
Skip to first unread message

Mark Panaghiston

unread,
Nov 20, 2012, 12:04:29 PM11/20/12
to jpl...@googlegroups.com
I'm not sure why Chrome andd Safari are being "slow". It is possible that your m4a MP4 files are encoded with some uber audio setting that is not really supported in the browsers. The mp4 audio should be AAC-LC.
http://jplayer.org/latest/developer-guide/#jPlayer-media-encoding

As for making multiple interfaces, you can do that pretty easily with an audio player. Not sensible for a video player of course... But you use a trick with the cssSelectorAncestor, whereby you use a class selector instead of an ID selector. This allows you to put multiple interfaces on the page that then all get hooked onto the same jPlayer instance.

<div class="multi-container-1">
  <!-- the gui html -->
</div>

Then put another somewhere else:
<div class="multi-container-1">
  <!-- the gui html -->
</div>

Then use the option:
cssSelectorAncestor: ".multi-container-1"

That way, both HTML areas will be updated with the information since they are both associated with the jPlayer instance via the class selector.

And remember that IDs and classes are different. You should only have 1 ID, whereas you may have hundreds of class occurrences... Hence why good CSS only contains class names.


On Friday, 16 November 2012 20:04:41 UTC, bmathias wrote:
Hello,

I'm currently having trouble with two different issues.

1. I have a section in the footer that plays a random audio file on each page. On some pages, I would like to have another area in the sidebar that plays the same random audio file. Is there a way to link the sidebar instance to the one in the footer, so that both sets of controls run on a single instance of jPlayer?

2. I'm having trouble with jPlayer loading the file in Chrome and Safari, though it works perfectly in Firefox. Sometimes it eventually loads, but very slowly. Other times, it doesn't load at all. It's also common for one instance to load fine, but for the other to not load at all. In searching for a solutions, I've seen many posts suggesting that my hosting provider (GoDaddy) doesn't support byte-range requests. However, when I load the header in Firebug, the Accept-Ranges: bytes line is present (and it works perfectly in Firefox). Is there something else that could be causing this?

You can see a working samples at:
http://www.brianmathias.org/dev - one instance in footer, and one is sidebar.
http://www.brianmathias.org/dev/audio/506 - one instance in main content area, and one in footer (two instances playing two different files, which works fine, except for the slow loading issue in webkit browers).

Any help you can offer would be greatly appreciated.

Thank you,

Brian

Mark Panaghiston

unread,
Nov 20, 2012, 12:06:21 PM11/20/12
to jpl...@googlegroups.com
I forgot to mention that some of you image urls are pointing to your localhost IP address.
For example:
http://192.168.1.65/wp-content/uploads/portrait-4.jpg

bmathias

unread,
Nov 20, 2012, 5:15:34 PM11/20/12
to jpl...@googlegroups.com
Thanks so much for your help. Since posting, I discovered that it was social plugins slowing the site down - not issues with jPlayer. Your thoughts on multiple interfaces are much appreciated. 

Thanks again for your reply.

bmathias

unread,
Nov 20, 2012, 6:04:00 PM11/20/12
to jpl...@googlegroups.com
Hi Mark,

Sorry - one last issue. Using a class selector instead of an id selector as cssSelectorAncestor worked like a charm for creating a second interface for the audio player. However, there's one bit of unexpected behavior: clicking the seek bar on the interface in the sidebar works perfectly, but clicking the seek bar in the footer interface sets the track back to the beginning of the track. Any thoughts on why this might be? I'm stumped.


Thanks again,

Brian

Mark Panaghiston

unread,
Nov 21, 2012, 12:02:24 PM11/21/12
to jpl...@googlegroups.com
That will teach me to try stuff out before suggesting things... I knew it worked for the other buttons, but the progress bar is a bit different. It needs to work out where you clicked on it in relation to the its placement on the page... And thinking about it now, I bet that the internal code is only looking at the first one it finds. As in, it compares your click on the 2nd progress bar in the footer with the placement of the 1st progress bar in the side stripe.

That will be a problem inside jPlayer itself and not easy to correct externally. Well, unless you do everything externally and bypass the simplified user interface association.

Current code:

        seekBar: function(e) { // Handles clicks on the seekBar
            if(this.css.jq.seekBar) {
                var offset = this.css.jq.seekBar.offset();
                var x = e.pageX - offset.left;
                var w = this.css.jq.seekBar.width();
                var p = 100*x/w;
                this.playHead(p);
            }
        },

I'll need to look into that... Maybe using $(this) to get the offset of the item clicked or getting the info from the event param.

My first guess is the following (This code is wrong btw, see discussion below.):
                var offset = $(this).offset();

Which would normally return the offset of the item clicked... But erm we are already in a wrapper and this is the jPlayer instance object in that context.

This bit of code is the wrapper:

                        var handler = function(e) {
                            self[fn](e);
                            $(this).blur();
                            return false;
                        };

We just need to get the event target of the event object, which is being passed through... And consider that the play bar may be the item clicked instead... Which should have the same offsets as the seek-bar... But no sensible way to distinguish which was clicked... But the playBar function could edit the event object passed to the seekbar method.

        playBar: function(e) { // Handles clicks on the playBar
            this.seekBar(e);
        },


Sorry... I'm just thinking stuff up as I'm going along. I'm not expecting you to do any of this. I might implement it myself and this will help explain the process.

The event.target looks like the correct property:
http://api.jquery.com/event.target/

So my second guess will be:
                var offset = $(e.target).offset();

You can patch the change into jPlayer through the prototype. So put this into you page before you instance jPlayer.

$.jPlayer.prototype.seekBar = function(e) { // Handles clicks on the seekBar
    if(this.css.jq.seekBar) {
        var offset = $(e.target).offset();
        var x = e.pageX - offset.left;
        var w = $(e.target).width();
        var p = 100*x/w;
        this.playHead(p);
    }
};

$.jPlayer.prototype.playBar: function(e) { // Handles clicks on the playBar
    e.target = $(e.target).parent().get(0);
    this.seekBar(e);
};

This does assume that the play bar is the first child of the seek bar, but I think that is pretty standard. It is in our skins at least.

Mark Panaghiston

unread,
Nov 21, 2012, 12:07:29 PM11/21/12
to jpl...@googlegroups.com
Actually, since the event.target is a DOM node, there is no point doing all the jQuery stuff to it.
https://developer.mozilla.org/en-US/docs/DOM/Node.parentNode

$.jPlayer.prototype.
playBar: function(e) { // Handles clicks on the playBar
    e.target = e.target.parentNode;
    this.seekBar(e);
};

Mark Panaghiston

unread,
Nov 21, 2012, 12:54:43 PM11/21/12
to jpl...@googlegroups.com
Just in case you cannot spot the obvious error there:

$.jPlayer.prototype.playBar = function(e) { // Handles clicks on the playBar
    e.target = e.target.parentNode;
    this.seekBar(e);
};

bmathias

unread,
Nov 21, 2012, 3:10:38 PM11/21/12
to jpl...@googlegroups.com
Brilliant. Worked like a charm. Thanks SO much for your help. Glad to have this all worked out.

Mark Panaghiston

unread,
Nov 22, 2012, 7:30:03 AM11/22/12
to jpl...@googlegroups.com
Great.

Putting the code together here and a bit of my waffle after it... I had started waffling in another thread, but I wanted to keep my rambles in 1 place.


$.jPlayer.prototype.seekBar = function(e) { // Handles clicks on the seekBar
    if(this.css.jq.seekBar) {
        var offset = $(e.target).offset();
        var x = e.pageX - offset.left;
        var w = $(e.target).width();
        var p = 100*x/w;
        this.playHead(p);
    }
};
$.jPlayer.prototype.playBar = function(e) { // Handles clicks on the playBar
    e.target = e.target.parentNode;
    this.seekBar(e);
};

I'm considering whether to add this change to the jPlayer core. It appears to make sense to do so, as I had always believed multiple interfaced did work. But I was wrong and the progress bar had issues... As would the volume bar too if that was duplicated.

I'd prefer the core code to be a little more clever though, just in case there is someone out there that puts another element between the seekbar and the play bar.

In some ways, if the playbar was not registered in the way it is (with that return false;) then the seekbar would be capturing the event during the bubble phase and there would not be an issue at all.

Mark Panaghiston

unread,
May 30, 2013, 7:06:02 PM5/30/13
to jpl...@googlegroups.com
Support for multiple seek bars and volume bars has been added to jPlayer in 2.3.9.
You can now have as many as you want and they will all update and they will all independently work correctly no matter where you put them on the page.
Tested with default horizontal bars and with vertical volume bars too.
Reply all
Reply to author
Forward
0 new messages