Open ghost opened 8 years ago
I've never had issues with multiple plyr objects on the same page. Could you throw up some code on jsfiddle or something and share it? Might be able to better help you that way.
I think what he's suggesting is that we have an option to pause other instances on play of a particular player? We could certainly add this as an option.
Hi, I was testing Plyr just now and this improvement would be great. If one has audio and videos instances in the same page, it doesn't stop one before playing.
I second this request. I have 2 plyr instances on the same page and I need to automatically stop playing one video when the user starts playing the other one otherwise they both play at the same time.
I'll dive into the code and see if I can implement a method to accomplish this.
It would need to sit behind a setting/option ideally as not everyone may want the behaviour but sure go ahead.
Indeed, that's the approach I have in mind, otherwise we'll be modifying the current behavior and that should't be necessary.
At first try I thought you had already implemented this but it was just being tricked by iOS' native behavior of playing one media file at a time, automatically stopping any previously media being played when playing a new video.
Hey,
In the latest version you can get the instance reference to all players on a page using plyr.get()
. This will return an array of instances so you could do something like:
plyr.get().forEach(function(instance) {
instance.pause();
});
That's going to pause all players of course though. I'll still look into the unique
option though.
Thanks for the update Sam. I still don't have enough time to properly build and share my solution to this but I did came up with a quick workaround, which you can see active here: http://www.unwork.nu/#/records/nuv7/
There are better ways of accomplishing this but I thought I'd post my example in case it helps anyone.
Adding a id to each instance(would be nice to have this as default ;-) Identify the new played Player. Adopted from mediaelement.js. Works great with all types of player.
var instances = plyr.setup({
enabled: true,
debug: false
});
var i = 1;
instances.forEach(function (instance) {
instance.on('ready', function (event) {
instance.getContainer().setAttribute('id', 'plyId-' + i);
instance.plyId = 'plyr-' + i;
// console.log(instance.pid);
i++;
});
instance.on('play', function (event) {
var currentPid = instance.plyId;
instances.forEach(function (instance) {
if (currentPid != instance.plyId) {
instance.pause();
}
});
});
});
When looping through the instances to pause them, I check the source to determine if it's the current player. It's a bit hacky as it assumes that no two instances have the same source, which isn't the case in my app.
myplayer.on('playing', function(event) { plyr.get().forEach(function(instance) { if(instance.source()!=event.detail.plyr.source()) instance.pause(); }); });
Hi, I initialized multiple video players on a page by :
const players = Array.from(document.querySelectorAll('.js-player')).map(player => new Plyr(player)); players.forEach(function(instance) { });
How m i supposed to pause all other players when one player gets played.
How m i supposed to pause all other players when one player gets played.
Use Array.filter to filter out the current player from the array, then pause every instance in the filtered array.
Thank you! It worked by the following code :
const players = Array.from(document.querySelectorAll('.js-player')).map(player => new Plyr(player));
players.forEach(function(instance,index) {
instance.on('play',function(){
players.forEach(function(instance1,index1){
if(instance != instance1){
instance1.pause();
}
});
});
});
But if there are already some players on the page, and some of the players are added dynamically after a timeout, how will it work ? Do I need to initialize all the players again and write the same code as mentioned above ?
Simplest solution I found so far, merging answers from @ZilMehta and @friday
var players = plyr.setup();
players.forEach(function(player) {
player.on('play',function(){
var others = players.filter(other => other != player)
others.forEach(function(other) {
other.pause();
})
});
});
But I'd love to see this officially supported. Agree with @sampotts that it would be better as a config option, something like a stopOthers
or solo
boolean.
The thing is Plyr is a 1-to-1 constructor in v3+ so it has no knowledge of the other players.
Your snippet is for pre v3 by the looks of it as there's no setup
method anymore.
@sampotts Yep, sorry should've mentioned that. I'm not ready for all the breaking changes in v3 yet so I haven't updated. I prefer the ease and facility that setup()
in v2 offers.
@weavermedia It might be something I could port over as a static method that sets up multiple players. Will have a think.
@sampotts That would be very handy indeed. Didn't mean to diminish all the hard work that went into v3. It's highly appreciated (on that topic, please consider a Patreon for Plyr) - I just haven't had the time to figure out how the changes will affect my use.
I have multiple players on the same page like this:
<audio id="player" controls>
<source src="http://motherdev.rankubator.com/faq/audio/mp3/101_Narcissist_Monet.mp3" type="audio/mp3">
<source src="http://motherdev.rankubator.com/faq/audio/ogg/101_Narcissist_Monet.ogg" type="audio/ogg">
</audio>
<audio id="player" controls>
<source src="http://motherdev.rankubator.com/faq/audio/mp3/101_Narcissist_David.mp3" type="audio/mp3">
<source src="http://motherdev.rankubator.com/faq/audio/ogg/101_Narcissist_David.ogg" type="audio/ogg">
</audio>
How can I pause one audio file when the other audio file is played?
Just use this simple Jquery script :)
$('audio').bind('play', function() { activated = this; $('audio').each(function() { if(this != activated) this.pause(); }); });
@remiburett
Your solution works fine for me. But one question. I have a page with several videos, there I use your code. But one video is a simple animation which should run endless. With your code it also gets stopped. How can I prevent it from stopping while another video plays?
Thanks.
Because I used an audio or video selector you need to be more specific and replace the $('audio') with a class or ID so your video that should run endless will not be stopped by the script ;)
How do I write this code for pause on other videos when I init one player at a time - on each click. My code goes like this:
$('somebutton').on('click', function(){
// stuff happens here, defere video src
// then init player on wanted video
const player = new Plyr(id);
player.on('ready', function() {
player.play();
});
// other stuff happens there
});
const players = Array.from(document.querySelectorAll('audio')).map(p => new Plyr(p, {
controls: ['play', 'mute', 'volume']
}));
players.forEach(player => {
player.on('ready', event => {
console.info(player.id + event.target.id);
event.target.setAttribute('data-id' , player.id);
});
player.on('play', ev => {
playerPrincipal.pause();
var Id = ev.target.dataset.id;
players.forEach(pl => {
if (Id != pl.id) {
pl.pause();
}
});
});
});
const players = Array.from(document.querySelectorAll('audio')).map(p => new Plyr(p, { controls: ['play', 'mute', 'volume'] })); players.forEach(player => { player.on('ready', event => { console.info(player.id + event.target.id); event.target.setAttribute('data-id' , player.id); }); player.on('play', ev => { playerPrincipal.pause(); var Id = ev.target.dataset.id; players.forEach(pl => { if (Id != pl.id) { pl.pause(); } }); }); });
This code doesn't work for me. The first audio still plays when I hit the 2nd audio player. Here's a codepen: https://codepen.io/ableslayer/pen/zYYjNZV
i use plyr for my react app and i handle this by the following code
document.getElementById('container').addEventListener('play', (event)=>{
let temp = document.getElementsByTagName('audio')
for(let i=0; i<temp.length; i++){
if(temp[i]!==event.target){
temp[i].pause()
}
}
})
I need this feature too. Has anything been done?
This feature would be very helpful. Is this still something being considered?
me too
Plyr instance already has an id, so you don't have to create one yourself.
instances.forEach(function (instance) {
instance.on('play', function (event) {
var currentPid = instance.id;
instances.forEach(function (instance) {
if (currentPid != instance.id) {
instance.pause();
}
});
});
});
Thanks for this thread - I am quite new but trying hard at this -- wondering if anyone can lend some insight.
I have a codepen where i've got the jQuery function working, but when I implement in a page locally (I'm using brackets editor) the 'pause when another audio element plays' is not working. anyone know why?
Codepen: https://codepen.io/xxsoundgirlxx/pen/WNGONYQ
HTML (i have put the js in the html so it can all be opened in one file - I have attached it here as a txt file)
In case any one didn't find how to achieve pausing other playing instances, here is how I've implemented it.
currentPlyr = Plyr.setup(selector, plyrParams);
if(typeof currentPlyr == 'object') {
currentPlyr.forEach(function(p) {
p.on('playing', event => {
appNS.pauseOtherPlyrs(event.detail.plyr.id, currentPlyr);
});
});
}
appNS.pauseOtherPlyrs = function(excluded_id, plyrs) {
plyrs.forEach(function(p) {
if(excluded_id != p.id && p.playing) {
p.pause();
}
});
}
To manage playback across multiple Plyr instances, you can utilize a global array. This is great when you have 100s of videos (think of infinite scroll).
Here's a quick snippet to implement this:
// Global array to hold all Plyr instances
window.players = window.players || [];
// Initialization of Plyr
var player = new Plyr('#player');
window.players.push(player);
// On 'play' event, pause all other players
player.on('play', function() {
window.players.forEach(p => {
if (p !== player && !p.paused) p.pause();
});
});
Hi, I love this player, but I'm running into an issue when I have multiple media players on a page. It does not appear that plyr stops one before starting another, and so I end up with multiple audio files playing at once. Am I missing something in the docs?