Jump to content

Watch Party


chef

Recommended Posts

chef

Are we talking about syncing playback between users (devices) on one server, or is it more about attempting to sync playback across multiple servers.

 

I can think of a way to sync playback across multiple devices connected to one server. 

But, I'm not entirely sure about syncing playback across different servers, that might need a 3rd party app, and hosting... Maybe? 🤔

 

Inside one server, where users are on different devices, the playback sync might be easy enough... Not perfectly sync'd, but probabaly within the second... Perhaps millisecond depending on the connection speed, and location.

 

I thought there was an app being developed which did this sort of thing, but I'm not sure what came of it.

 

Sounds like it could be set up as follows, for a one server setup:

1. Users login (create a session)

2. One user is set to the controlling user

3. The controlling session user is responsible for beginning playback.

4. Probabaly some kind of config page off the server dashboard to setup a group to control everything... I guess... to start.

5. When the controlling session starts playback, we grab the event, and send the same command to the other device sessions in the group. 

6. Maybe some kind of playstate pause command to sync everything up close (close enough) to each other.

 

Like I say, that could be the easy part.

Maybe...

Across multiple server, this would need an authentication to setup, and login, sending server IDs around to attempt controlling. Might be too much for me to write.

But the one server setup could be done.

 

 

 

 

Edited by GrimReaper
Renamed Title
  • Agree 7
Link to comment
Share on other sites

BillOatman
14 hours ago, chef said:

Are we talking about syncing playback between users (devices) on one server, or is it more about attempting to sync playback across multiple servers.

Across multiple server, this would need an authentication to setup, and login, sending server IDs around to attempt controlling. Might be too much for me to write.

I believe Plex and JF are single server solutions.  You are watching with friends and family, being on the same server should not be an issue.

For multiple servers, I would envision needing the movie on all servers, and the clients connecting to their respective servers. Then the servers being in communication with each other to keep all of their respective clients in sync.  But that's a buttload of work for probably not much of a use-case IMO :)

Edited by BillOatman
  • Agree 1
Link to comment
Share on other sites

rbjtech
14 hours ago, chef said:

Are we talking about syncing playback between users (devices) on one server, or is it more about attempting to sync playback across multiple servers.

 

I can think of a way to sync playback across multiple devices connected to one server. 

But, I'm not entirely sure about syncing playback across different servers, that might need a 3rd party app, and hosting... Maybe? 🤔

 

Inside one server, where users are on different devices, the playback sync might be easy enough... Not perfectly sync'd, but probabaly within the second... Perhaps millisecond depending on the connection speed, and location.

 

I thought there was an app being developed which did this sort of thing, but I'm not sure what came of it.

 

Sounds like it could be set up as follows, for a one server setup:

1. Users login (create a session)

2. One user is set to the controlling user

3. The controlling session user is responsible for beginning playback.

4. Probabaly some kind of config page off the server dashboard to setup a group to control everything... I guess... to start.

5. When the controlling session starts playback, we grab the event, and send the same command to the other device sessions in the group. 

6. Maybe some kind of playstate pause command to sync everything up close (close enough) to each other.

 

Like I say, that could be the easy part.

Maybe...

Across multiple server, this would need an authentication to setup, and login, sending server IDs around to attempt controlling. Might be too much for me to write.

But the one server setup could be done.

 

 

 

 

For single server @chef - this is almost a spinoff from the session work that Introskip autoskip does.

get sessions, control sessions - that's pretty much it.

I did a proof of concept a while back - controlling multiple sessions is no different to controlling a single session - you just do it multiple times lol.

the 'difficult' bit is providing the control on everyone's session - as you need to watch them all and then feedback - because if one person pauses, then you need to send that to all users etc - and then resync once everyone is going again (easy enough to rewind 5 secs for all users.. something like that).

I'm sure I've seen something along these lines in the Plugin or API posts ...   

 

 

  • Agree 1
Link to comment
Share on other sites

chef
1 hour ago, BillOatman said:

I believe Plex and JF are single server solutions.  You are watching with friends and family, being on the same server should not be an issue.

For multiple servers, I would envision needing the movie on all servers, and the clients connecting to their respective servers. Then the servers being in communication with each other to keep all of their respective clients in sync.  But that's a buttload of work for probably not much of a use-case IMO :)

 

49 minutes ago, rbjtech said:

For single server @chef - this is almost a spinoff from the session work that Introskip autoskip does.

get sessions, control sessions - that's pretty much it.

I did a proof of concept a while back - controlling multiple sessions is no different to controlling a single session - you just do it multiple times lol.

the 'difficult' bit is providing the control on everyone's session - as you need to watch them all and then feedback - because if one person pauses, then you need to send that to all users etc - and then resync once everyone is going again (easy enough to rewind 5 secs for all users.. something like that).

I'm sure I've seen something along these lines in the Plugin or API posts ...   

 

 

Okay, a single server solution should be easy enough.

Once the controlling session initiates playback, and the devices are sync'd, we'll connect all playback events from  each device to the group.

If someone pauses their device, do we  pause them all?

If someone stops playback (that isn't the controlling session), we'll just remove them from the group.

Shouldn't be too complicated really...

@Cheesegeezer @rbjtech, @BillOatman you think we should write this thing?

Probabaly wouldn't take more then a couple days of writing and testing.

Let me know 😁

 

  • Like 3
Link to comment
Share on other sites

rbjtech
11 minutes ago, chef said:

 

Okay, a single server solution should be easy enough.

Once the controlling session initiates playback, and the devices are sync'd, we'll connect all playback events from  each device to the group.

If someone pauses their device, do we  pause them all?

If someone stops playback (that isn't the controlling session), we'll just remove them from the group.

Shouldn't be too complicated really...

@Cheesegeezer @rbjtech, @BillOatman you think we should write this thing?

Probabaly wouldn't take more then a couple days of writing and testing.

Let me know 😁

 

I'm up for a proof of concept for sure.  

I think the key thing to agree before starting even a proof of concept is all agree the scope of what it's trying to achieve - and not get sidelined into adding 'bells and whistles' until after that PoC has been achieved ;) 

Ping us on teams @chef or PM us for the details if you don't have them already.

  • Like 1
Link to comment
Share on other sites

chef
22 minutes ago, rbjtech said:

I'm up for a proof of concept for sure.  

I think the key thing to agree before starting even a proof of concept is all agree the scope of what it's trying to achieve - and not get sidelined into adding 'bells and whistles' until after that PoC has been achieved ;) 

Ping us on teams @chef or PM us for the details if you don't have them already.

Will do! 

  • Like 1
Link to comment
Share on other sites

chef

hey look at this.

We can create Parties.

        private async void SessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e)
        {
            var config = Plugin.Instance.Configuration;
            if (!config.Parties.Any()) return;

            //We have Watch Parties!
            
            //Check if playback that just started belongs to a controller in a watch party.
            var party = config.Parties.FirstOrDefault(p => p.ControllingDeviceId == e.DeviceId);
            
            
            if (party is null) return;
            
            //It was a party controller starting playback so we'll act on it.
            

            foreach (var member in party.Members)
            {
                var currentMemberSession =
                    SessionManager.Sessions.FirstOrDefault(session => session.UserId == member.Id.ToString());

                if(currentMemberSession is null) continue; //<== Maybe they logged off - move on!

                await SessionManager.SendPlayCommand(null, currentMemberSession.Id,
                    new PlayRequest() { ItemIds = new[] { e.Item.InternalId, } }, CancellationToken.None); // Start the playback on the users device.
                                                                    
                //Need to sync the playback here with the other devices... somehow - pause, and unpause?? Maybe...
                //In ProgressEvents on each session, wait for the last session to catch up to the 
                //first session which has been briefly paused 
            }
            
        }

 

Right off the bat I'm starting to see some issues though.

Only server managers will have the ability to create Watch Parties. They are the only ones with access to the dashboard... 😮

Hmm... this must stay simple. 

  • Like 1
Link to comment
Share on other sites

samuelqwe
1 hour ago, chef said:

Only server managers will have the ability to create Watch Parties. They are the only ones with access to the dashboard... 😮

I have a bunch of crazy ideas of how we could get around this, might be too crazy though... 😆

Link to comment
Share on other sites

Yes, I think your biggest challenge trying to do this in a plug-in is going to be how does someone actually join (or leave for that matter) the group?  Without the apps having any knowledge of this, that's going to get tricky...  

Link to comment
Share on other sites

khat17

TLDR: Hope we can get it done. Public voting may give better metrics. Appreciate that everyone has stuff to do and life happens. Maybe borrow code or ideas from the fork?

And now for a long post unfortunately. 

Doing this from my phone. Away from civilization and stuff at the moment. 

Two things. 

Firstly. It's good to see solutions being discussed. Happy for that. Keep ho the good work. Wish I could help, but I can't. I see the code and I grasp some of it, but my programming experience ended in 1997. I can't contribute. 

Secondly. Saw some things flare up. It happens. I get it. One user said they're doing their thesis so they can't. Don't knock it. Everyone has life to deal with. And the options are there. It's just that me personally, I'd love to see the product that has been around, made a name, is mostly stable and had the original user base be on top. If even not at THE top, be up there.

Every other service like Netflix and Amazon has the feature, and competitors and forks have the feature. It's one feature, but it matters to a lot of persons. The primary thing was COVID, but we have some normalcy now, so it's more of a convenience. 

I use Plex and I don't use the feature as much currently. I have work. My friends have work and school. Who's not playing DOTA in their spare time may be on SFV, NFS or something else. I can't join because of work. Our times currently don't match up. 

Does this make me want the feature any less? No. Is it important? It's fallen off a bit. I have alternatives. But I'd rather have only one media platform installed on my VPS for when I'm on the road. And that one feature is preventing me from making it Emby. But I'm just one user. 

Yes, the feature request and such is there. I don't even know where, and being on phone makes it more tedious to search. I get that it doesn't determine what's worked on, but it can't be used as good metrics for what's wanted. Not every user is technical. Not every user joins the forum. If there was a public voting system attached to the site, maybe better metrics could be gathered. Just saying. 

In the end. Thanks to the team for making the solution. Thanks to the members for trying to find a workaround. I'm hopeful that we can find a workable solution soon enough. Even if it has to be borrowed from the fork. Just a suggestion. 

Keep safe everyone. 

Edited by khat17
  • Thanks 1
Link to comment
Share on other sites

Cheesegeezer
20 hours ago, chef said:

 

Okay, a single server solution should be easy enough.

Once the controlling session initiates playback, and the devices are sync'd, we'll connect all playback events from  each device to the group.

If someone pauses their device, do we  pause them all?

If someone stops playback (that isn't the controlling session), we'll just remove them from the group.

Shouldn't be too complicated really...

@Cheesegeezer @rbjtech, @BillOatman you think we should write this thing?

Probabaly wouldn't take more then a couple days of writing and testing.

Let me know 😁

 

For sure Chef!! Always up for a collaboration 👍👍

  • Like 1
Link to comment
Share on other sites

rbjtech

There are a few clunky ways to do it such as using the Playlist's but an idea which I played with for a bit - and may have some merit - is if you want to join the 'party' then you literally go into a 'WatchTogether' library which acts as the 'lobby' and in there is the film(s) that are being played.

These are actually just STRM files to the other real files in other libraries.   Maybe have a 'start time' incorporated into the film title so you know when it's gonna start.

To 'join' you actually click to play the film - the plugin is polling for new 'sessions' and if associated with the above film id - then it knows that user wants to join the party.  It then sends a session to restart the playback and then pauses.  It can send a message to the user telling them they have joined.

If you wanna leave, then just abandon the playback of that item.

When the admin is ready - then the sessions are released and playback begins on all the sessions that have joined.

You can control permissions on joining etc using the library permissions model.

Edited by rbjtech
  • Like 3
Link to comment
Share on other sites

chef
20 minutes ago, rbjtech said:

There are a few clunky ways to do it such as using the Playlist's but an idea which I played with for a bit - and may have some merit - is if you want to join the 'party' then you literally go into a 'WatchTogether' library which acts as the 'lobby' and in there is the film(s) that are being played.

These are actually just STRM files to the other real files in other libraries.   Maybe have a 'start time' incorporated into the film title so you know when it's gonna start.

To 'join' you actually click to play the film - the plugin is polling for new 'sessions' and if associated with the above film id - then it knows that user wants to join the party.  It then sends a session to restart the playback and then pauses.  It can send a message to the user telling them they have joined.

If you wanna leave, then just abandon the playback of that item.

When the admin is ready - then the sessions are released and playback begins on all the sessions that have joined.

You can control permissions on joining etc using the library permissions model.

Oh. That is a very cleaver solution. Wow.

 

 

  • Agree 1
Link to comment
Share on other sites

rbjtech
3 minutes ago, chef said:

Oh. That is a very cleaver solution. Wow.

 

 

You can also do 'trickery' such as having the film backdrop as a 'picture of a 'lobby' for example - maybe even manipulate the 'cast and crew' as people that have already joined... lol

But lets get the concept working first haha - as Eric has said, there is no easy way to use the interface for 'other user input' - outside of playlists and favourite, so trying to do this without Core Dev input is gonna be a set of compromises.

  • Like 2
Link to comment
Share on other sites

I agree, that is a clever solution.  Could work pretty nicely actually...

  • Like 2
Link to comment
Share on other sites

chef

Sounds like the plugin needs to do some setup when it is installed.

1. Create the Watch Party library on the server if it doesn't exist.

2. A method that creates .strm files

3. Message sender to active sessions

 "{user.Name} has joined the party."

4. Figure out how to update the library when strm files are added.

 

Maybe start there. That's quite a bit.

Link to comment
Share on other sites

chef

I'm seeing two different ways about creating the party environment.

Do you guys think it would be best to try creating a "Watch Party" Channel or create it as a Library?

I'm not entirely sure how strm files interact with a Channel, compared to a Library.

Or, Perhaps it really doesn't matter which one get used?

Link to comment
Share on other sites

rbjtech
3 minutes ago, chef said:

Sounds like the plugin needs to do some setup when it is installed.

1. Create the Watch Party library on the server if it doesn't exist.

2. A method that creates .strm files

3. Message sender to active sessions

 "{user.Name} has joined the party."

4. Figure out how to update the library when strm files are added.

 

Maybe start there. That's quite a bit.

Small steps @chef - can we get the 'control/sesion' mechanism working - as without that there is little point moving forward with the other stuff.

We know the API can control the sessions, but can we poll them and get the info we need to control the 'party' ? 

  • Like 1
Link to comment
Share on other sites

rbjtech
1 minute ago, chef said:

I'm seeing two different ways about creating the party environment.

Do you guys think it would be best to try creating a "Watch Party" Channel or create it as a Library?

I'm not entirely sure how strm files interact with a Channel, compared to a Library.

Or, Perhaps it really doesn't matter which one get used?

From my experience, they are no different to any other media item as a Library - the only difference is they will not be fully identified when created - but by copying the existing metadata from the local 'source' - you can show the meta data and images that way.   Bonus of course is the watch status actually reflects the 'source' - so if you watch it in the party,  it will be marked as watched in the main library for that user as well.    I don't have any views on how they behave as a 'Channel'.

  • Agree 1
Link to comment
Share on other sites

chef
7 minutes ago, rbjtech said:

Small steps @chef - can we get the 'control/sesion' mechanism working - as without that there is little point moving forward with the other stuff.

We know the API can control the sessions, but can we poll them and get the info we need to control the 'party' ? 

yes. We can see everything from when user log's on (session starting), and also in most cases see what they are currently viewing.

We can also get the event when they attempted playback of an item.

I suppose we act on playback if the item is in our 'Watch Party'  library?

 

This seems to create the "Watch Party" library:

                LibraryManager.AddVirtualFolder("Watch Party", new LibraryOptions()
                {
                    AutomaticRefreshIntervalDays = 0, //<== ints default to 0. probabaly dont; need this. This library should never be refresh, unless an item is added to it...
                    CollapseSingleItemFolders = true, //Not sure what this does.
                    ContentType = "Movies", //Hmmm... will this be a problem if watch parties wanted to watch tv shows? Someones gonna request eventually.
                    DownloadImagesInAdvance = false,
                    EnableAdultMetadata = false,
                    EnableArchiveMediaFiles = false,
                    Name = "Watch Party",
                    EnableMarkerDetection = false, //No do not detect intros
                    EnableRealtimeMonitor = false, //No do not monitor this library
                }, false);

 

Edited by chef
  • Like 2
Link to comment
Share on other sites

rbjtech
12 minutes ago, chef said:

I suppose we act on playback if the item is in our 'Watch Party'  library?

Yea, as you say, we can use the fact they are in the Watch Party library/channel and have started playback of the item as the trigger they want to join the party and watch that film.  At this point, we have their session username and session id - so can control their session.   I don't *think* we can see the user in the lobby viewing that item until they press play (I did look, but couldn't see a way) - but we can just pause them asap or even stop the play (with a message they have joined the party) until we are ready - as at this point we have the session info we need.  Probably need a little bit of experimentation on the session control - I assume the plugin can list all the users that have joined the party so they know when to 'start' it.  Could also be time based.. film will start in 5 minutes etc.

Edited by rbjtech
  • Like 1
Link to comment
Share on other sites

chef

What does emby call it when there is multiple content types of media in a folder?

Edit: mixed content.

The watch party has to be mixed content.

 

Link to comment
Share on other sites

rbjtech
1 minute ago, chef said:

What does emby call it when there is multiple content types of media in a folder?

Edit: mixed content.

The watch party has to be mixed content.

 

Are you thinking of this covering TV shows as well ?

Link to comment
Share on other sites

chef
2 minutes ago, rbjtech said:

Yea, as you say, we can use the fact they are in the Watch Party library/channel and have started playback of the item as the trigger they want to join the party and watch that film.  At this point, we have their session username and session id - so can control their session.   I don't *think* we can see the user in the lobby viewing that item until they press play (I did look, but couldn't see a way) - but we can just pause them asap or even stop the play (with a message they have joined the party) until we are ready - as at this point we have the session info we need.  Probably need a little bit of experimentation on the session control - I assume the plugin can list all the users that have joined the party so they know when to 'start' it.  Could also be time based.. film will start in 5 minutes etc.

Cool.

That seems pretty straightforward.

I think we can just use the plugin config to save dictionaries of item (keys), and session (values).

You press the item in the library and we save your session to the key (item id)

Iterate the dictionary when it comes time to play, by sending a PlayRequest of the key (item.Id) to all values (sessions).

 

  • Like 1
Link to comment
Share on other sites

chef
Just now, rbjtech said:

Are you thinking of this covering TV shows as well ?

I don't know. 

Should it?  Might be to complicated at first.

As Luke always says "it's possible for the future, thanks" 😳😁.

Most likely we should just handle movies to start. What do you think?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...