Protected 52 Posted October 30, 2024 Posted October 30, 2024 (edited) Emby Party is a solution for watching videos with multiple friends through your Emby web client. It requires no additional dependencies - only a device running Emby (presumably with good enough hardware for serving all the attendees, especially if you're transcoding) and at least one web browser. It consists in two halves: A server plugin and a web client module. They must be used together! Each half expects the other to be present. This is an experimental open source project. Feel free to fork and contribute pull requests and issues (my availability for fixing issues on my own may vary wildly and may be low in the near future). The source code and all known issues can be found in the github repository. Any information there should be considered the most up to date. Currently testing in Emby 4.8.10, Windows and Debian Bookworm (Linux), Firefox, Chrome and Edge. Features Hassle-free hosting: Doesn't matter who creates the party. Whoever initiates playback while in a party transparently becomes the party host, and host is reassigned if they leave. No need to recreate the party for someone else to host something later. The hosts controls the party video and video position. Video access permission check: Will only play a video if all party members have access to it, and will prevent new party members who don't have access to the current video (if any). Accurate synchronization of video player positions when the host seeks or changes videos using a multi-part protocol that leverages remote control commands under the hood. Accurate catch-up seek commands issued for guests when they fall behind or are otherwise offset from the host. Efficient transition between videos in a playback queue that accounts for slightly offset attendee positions and allows each attendee to start loading the next video while others finish the previous one. Late joiner support: Brings late joiners immediately into the video at the correct position. Joiners already watching a video will automatically start hosting that video if the party was idle. Host can change audio and subtitle streams for all attendees (guests can change it back for themselves if they want). Distributed pause/unpause requests - all users can pause and unpause. Return to video button for guests to return to the video being watched by the host if they closed it for some reason. Guests are automatically returned to the correct video if they open the wrong one or under certain other circumstances. Keep alive: Plugin keeps party member sessions and websockets open as needed and disconnects party members who time out. Support for multiple sessions/devices per user account. Just don't duplicate browser tabs! Support for remote control: Party members can control other Emby clients and those clients will benefit from party synchronization. (Caveats: Working, but not thoroughly tested yet. Due to the lack of client-side support, remote controlled clients are capable of issuing pause/unpause commands that break synchronization. I recommend being careful about pausing/unpausing in a device being remote controlled by a party member.) Cool resizable sidebar with list of party attendees and log of chat and events. The sidebar has docked (squeezes the video aside) and undocked (overlaps the video) modes and uses your Emby profile picture. Dark and light mode supported. Visual indicators for synchronization states of party members when synchronizing with host (icons). Visual indicator when receiving seek commands from the server (your name flashes orange). Host remedies for synchronization issues: Guests who are not responding can be sent another playback command by the host or kicked from the party after 20 seconds have passed. Emoji support in chat using :shortnames: or emoticons. Markdown styles support in chat, including spoilers and preformatted text. Preserves chat focus and selectively blocks keyboard shortcuts or UI interactables when chatting or syncing in order to prevent control mistakes/command spam. Chat bridge endpoint: External applications can connect to `ws://localhost:8196/bridge` to exchange chat (and some events) with the party sidebar. I threw together a module for my self-hosted Discord bot that shows how to use it. Remote control chain resilience for party attendees only: Prevents you from creating a loop of remote control targets. If you do this in vanilla Emby your clients will nuke the server with requests. Automatic skip to next video for videos stalled at the end because the last segment isn't decoding. This is also for party attendees only. Installation To install the server plugin, download it or build it in Visual Studio, then copy it normally to your Emby server's plugins folder and restart the server. Currently the plugin doesn't modify any Emby files (yet?), so you'll have to manually edit one of the web client's existing modules and import the Emby Party module there. Head on over to system/dashboard-ui/modules/appheader/appheader.js and locate the end of the render function, which in Emby 4.8.10 is in position 21877. Insert this code there: , Emby.importModule("./modules/embyparty/partyheader.js").then(function(PartyHeader) { return (new PartyHeader()).show(skinHeaderElement.querySelector(".headerRight")); }); Save, clear your browser cache and refresh. If the party button appears in the top right corner, you're good to go! I'm sure someone will tell me a better way to do this soon enough. I don't know if there's a commonly accepted way and haven't really put any thought into it yet. Whole bunch of disclaimers Use at your own risk! If something breaks that you don't want broken, revert the steps above to remove the plugin from your server installation. Emby Party was iteratively developed and tested with several friends over several weeks, but it was developed to suit our own needs. It was not (yet) tested alongside features we don't use, including, but not limited to, Emby Connect, Emby Premiere, Live TV, the audio player, conversions, cinema previews, most other plugins, etc. Currently no mobile styles. Not tested on mobile. We've been in active development until now. There are vaguely known issues that are hard to reproduce and instability can be caused by video decoding failures, networking issues, browser crashes, browser extensions, lack of hardware resources, forgetting your browser won't play until you click the window unless you've given Emby autoplay permissions.. New and exciting bugs should also appear as we get more people using it. Thanks in advance for helping test, report or fix this stuff! Otherwise, check back for updates, I guess? Please keep comments and suggestions in this thread. Issues should be reported only on github so they're all in the same place. You may notice a whole lot of things in the source code that make you think, wow, it sure would be nice if this was in the Emby settings. I agree! If you would like to implement a plugin settings page, please submit it as a pull request on github! I'm so horribly far behind schedule with this project, and my free time is far in the negative right now. There may be better ways to do some of the things Emby Party does that I am simply not aware of at this time (one of the reasons I'm keeping these instructions outside the repository for the moment) or were simply not considered because the feature grew organically. Pull requests please! Also recommended If you're feeling adventurous, consider improving your watch party's subtitle experience with these (much harder to apply) client-side fixes we worked out in tandem: Temporary workaround for subtitles coming in too early when resuming a video with transcoding (Important for this whole thing if you watch videos with subtitles) Web client ignoring AudioStreamIndex and SubtitleStreamIndex (Required for party host to guest stream index sync if you use that) Fixing mismatch between subtitle canvas and video aspect ratio breaking ass subtitles (imperfect) Playing plaintext subtitles through Subtitles Octopus by faking subtitle type Support mkvs with embedded fonts (requires the associated plugin) These may become obsolete over time if things are fixed or integrated into the main software. Don't forget to clear your cache and refresh after making changes to the client. Edited October 30, 2024 by Protected 18 3
rbjtech 4820 Posted October 30, 2024 Posted October 30, 2024 Very nice - well done. I'll be interested to read in the code how you control the sync of the sessions. Such a shame it's web client only but I suspect that's because there is little ability to 'input' from the other clients. Thanks for making it open source on github - I'm eager to try this.
jspanitz 11 Posted October 30, 2024 Posted October 30, 2024 I might start my emby instance back up to play around with this. Appreciate you doing what the devs can't or won't. Thanks again.
Protected 52 Posted October 30, 2024 Author Posted October 30, 2024 (edited) To be fair to the devs, this wasn't easy so far. I'd been expecting to publish more than a month ago. I had to solve more than fifty different issues (this is not an exaggeration) with the help of my poor users (ten people) who had to suffer through many unstable sessions. I'm (ab)using the Remote Control features to make this work - in other words, the ability to remotely tell a client to play, stop, pause, unpause and seek, as well as the client reporting to the server that it's playing, paused, unpaused, and its current position (every ten seconds or after seeking). These are native features, but remote control as implemented is heavily client-based, with clients talking to other clients and the server largely just bouncing things around. Things that require client support include: Blocking pause and unpause when the user shouldn't be pausing and unpausing, namely when the user's client is supposed to be waiting for other participants (essential). That's why remote control of non-client-modified sessions introduces potential instability if used. Responding to server ping. Emby Party is a real time feature built on top of an asynchronous server. It pings the client every 30 seconds. Without ping, if the user is having connection troubles or simply closes the tab, everyone else in the party will be subjected to instability (this usually manifests as things not working or going out of sync). The sidebar isn't a standard piece of UI; it requires full DOM access. One thing it has to do is put the rest of the application inside a container so it can be reliably rendered side by side with it. The vanilla web client inserts all kinds of things directly as children of the body HTML tag, so they can't be reliably squeezed aside. There is of course no reason why any of it can't be implemented in any of the other clients but I only had access to the source code of this one. Edited October 30, 2024 by Protected 1 2
Protected 52 Posted October 30, 2024 Author Posted October 30, 2024 More than you ever wanted to know about host synchronization This applies when initiating playback or when the party host's video player is not where it should be. We use three pieces of data to estimate party attendee positions: Position reported by the client in the latest non-bogus TimeUpdate event The amount of time that has passed since the latest position report The ping When a new update arrives, if the host is too far from estimate we assume that user has seeked to a different position (or the client was delayed for some reason, which is functionally the same because we want to keep everyone in the same position regardless). During synchronization, we track attendee states. I'm going to simplify things here and just say we mainly care about whether each guest is still moving to/loading the new position or has reported that they're ready to continue. We also use custom General Commands to report to every client: If synchronization has started, if each guest is ready to continue, and if synchronization has ended (so they can do UI things). So the overall sequence of events is something like this: Announce synchronization, pause the host and set it to "ready to continue". Set every guest to "loading the new position". Tell every guest to seek/play. For each guest, once they've reported progress/playback, change them to (and announce) "ready to continue". Tell the guest to pause as well. When the last guest is ready, instead of pausing it, we tell everyone else to unpause and announce end of synchronizartion. In practice, events can arrive in any order. Things are also complicated by playback queue video changes. A lot of work was put into making those happen reasonably smoothly; it's even possible for party guests to all arrive at the next video before the host due to estimation inaccuracies and/or the host having slow hardware. Emby Party should hopefully be resilient to attendees being in different videos at the same time around the times videos are changed. Guest catch-up Much simpler. We estimate the guest's intended video position much the same way I described above, but instead of comparing it with itself in the previous iteration, we compare it with the host's. If it's too far off, we send a seek command to the guest and increase the margin of accuracy for that guest (currently by 1 second at a time). This is meant to keep the viewing experience more comfortable if the guest just has crap network acccess, by sacrificing some synchronization in exchange for reducing the amount of seeks. Currently the maximum accuracy tolerance is 7 seconds, so if the guest can't stay within 7 seconds of the host they'll just seek all the time. It resets every video. 3
rbjtech 4820 Posted October 30, 2024 Posted October 30, 2024 Really interesting - thanks for taking the time to explain. We hit some of the same issues during the original POC maybe 18 months ago, but it looks like you have managed to resolve/work around these I haven't tried it yet - but from the Features list it looks as if this is going to deliver !
Protected 52 Posted November 11, 2024 Author Posted November 11, 2024 I did not implement or test anything to do with Emby Connect up until now if that's what you're asking (as written in the top post). Otherwise, my friends and I connect to our server from remote devices and it works just fine. If you're experiencing a specific issue please report it on github with a detailed description!
devinfan 0 Posted November 16, 2024 Posted November 16, 2024 hi, there after installing the plugin and inserting the code, no button appears. Can you help me with that?
Protected 52 Posted November 16, 2024 Author Posted November 16, 2024 Did you completely clear your browser cache before refreshing?
bscholer 0 Posted November 16, 2024 Posted November 16, 2024 @devinfanI'm not sure if you're having the same issue as this user, but this is how I fixed it! https://github.com/Protected/EmbyParty/issues/3#issuecomment-2480755569
DragoMag 4 Posted November 24, 2024 Posted November 24, 2024 Hello everyone, personally, I make clean code because I couldn't manage otherwise.
Neureka 0 Posted January 4 Posted January 4 @ProtectedThank you so much for your hard work, this was the one thing preventing me from moving over from Plex! While I still hope a native implementation is added (we use Emby on a lot of TV's), this has worked wonderfully for me in the meantime. I noticed that the installation process isn't exactly the greatest right now, so I made it easier to install Emby Party for docker users. I opened an [issue](https://github.com/Protected/EmbyParty/issues/4) on GitHub with instructions because I wasn't sure where else to put it. If you enable the discussions feature, I'll happily move it there instead.
Protected 52 Posted January 5 Author Posted January 5 Glad to know it's working for you! Is there a benefit to moving it to discussions? Maybe I should just put it in the wiki? I could include the script in the repository if you want to contribute that. 1
Neureka 0 Posted January 5 Posted January 5 Quote Is there a benefit to moving it to discussions? Maybe I should just put it in the wiki? Only if you want to avoid cluttering issues with unrelated guides, etc. Wiki might be another good place to include it! Feel free to add it wherever you like. I just wanted to give something to the community to make it a bit easier for docker users.
KayDox64 1 Posted January 9 Posted January 9 Do you think we can get a video tutorial for how this should install? the instructions dont show what it looks like, for example my appheader.js was minified, and there was no position 21877, at least not one i could find.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now