Skip to content

Guide to adding support for a new media player to Syncplay

Etoh edited this page Dec 29, 2022 · 8 revisions

While 99% of the time the best option is to use mpv, if you want to develop and maintain support for a different media player then this guide is for you.

This guide is not super detailed because it expects a high level of pre-existing development knowledge.

Main methods and variables

Media player variables

In the base class are the following variables that need to be set:

speedSupported = True # Does Syncplay have the ability to specify the playback speed of this media player?
customOpenDialog = False # In most cases this should be False, but can be set to True if you are using a custom open file dialogue (although that hasn't been fully tested)
chatOSDSupported = False # True if media player supports OSD messages for that that are different from the regular OSD messages (e.g. mpv)
alertOSDSupported = True # True if media player supports alert messages for that that are different from the regular OSD messages (e.g. mpv)
osdMessageSeparator = "; " # Separator for when Syncplay has to send multiple messages at once (might want to be something like "\n" if the media player supports it)

Methods

See https://github.com/Syncplay/syncplay/blob/master/syncplay/players/basePlayer.py for details on precise input variables, etc. See existing media player implementations if additional clarity is required.

  • askForStatus: This method is supposed to execute updatePlayerStatus(paused, position) on client using the arguments: boolean paused and float position in seconds. See https://github.com/Syncplay/syncplay/blob/master/syncplay/players/mpv.py for an example implementation.
  • displayMessage: Displays an OSD message for a specified duration. OSDType can be the constants OSD_NOTIFICATION, OSD_ALERT or OSD_CHAT; mood can be the constants MESSAGE_NEUTRAL, MESSAGE_BADNEWS or MESSAGE_GOODNEWS.
  • Drop: Clean-up connection with player before Syncplay will close down.
  • Run: Start up the player, returns its instance.
  • setPaused: Sets playing/paused states.
  • setFeatures: Used to tell the mpv implementation to send various initiation commands. You can normally just pass this, as per VLC: https://github.com/Syncplay/syncplay/blob/master/syncplay/players/vlc.py
  • setPosition: Sets position of media player (might be an invalid position).
  • setSpeed: Set playback rate (usually 1, but can be different if slowing down due to time difference, etc).
  • openFile: Specifies a file to open in the media player. Might be a URL. resetPosition is used to specify whether Syncplay wants the player to set position to 0 when the file is loaded or to retain the current playback position.
  • getDefaultPlayerPathsList: Returns a list of relevant media player constants file and returns making use of getExpandedPath. See mpv and VLC for example implementations.
  • isValidPlayerPath: Return true if the media player path is recognised as that for your media player (e.g. it is VLC if it contains vlc in the path). Don't always return true, or Syncplay will think all paths relate to this media player!
  • openCustomOpenDialog: You don't usually need this because opening a custom open dialog is not normal.
  • getPlayerPathErrors: You can probably just return none here. This is meant for returning an error if your media player has to be given a media path to start but no path has been specified (i.e. mplayer2).

Note: When a media file is loaded (or more specifically when the path, filename or duration changes), this should trigger an update send to self._client.updateFile which should be run through a thread. See mpv/VLC implementations.

Supporting a variant of a currently supported player

The most common use case is to add support for a variant of a currently supported media player.

To do this you can:

  1. Add paths relating to your variant media player to syncplay/constants.py in a similar manner to MPV_PATHS. This is where Syncplay will look for the media player, and you will be making use of this later in your implementation of getDefaultPlayerPathsList. Place the new code just below the code for your base class.
  2. In syncplay/constants.py create a constant for your icon using your own variant of the _ICONPATH constant - this will want to be a .png file that you add to the repository (or you can use the path for the base player if that is appropriate).
  3. Create a new .py file in the syncplay/syncplay/players/ folder for that player.
  4. Use https://github.com/Syncplay/syncplay/blob/master/syncplay/players/mpvnet.py as a guide base for how to make this a sub-class of an existing player. Basically, you are making a new class using the base class from the main player as your starting point. You then need to specify the areas where your class differs from the base class. You are likely to want to re-implement run, getDefaultPlayerPathsList, isValidPlayerPath, getExpandedPath and getExpandedPath. These are explained above.
  5. In syncplay/players/init.py import the media player and add the player class to getAvailablePlayers. You can search for references to your base media player's class for examples of how to do this. Import/add your media player after the base media player.
  6. If you want Syncplay to be officially supporting this variant then you will need to add references to it in all the syncplay/messages_*.py references to media players in the player-path-error, player-path-config-error, and executable-path-tooltip messages.

Supporting a new media player

If you want to support a new media player ensure it has an API that can do the following things:

  1. Pause and

From Syncplay's side, you need to:

  1. Add paths relating to your new media player to syncplay/constants.py in a similar manner to MPV_PATHS. This is where Syncplay will look for the media player, and you will be making use of this later in your implementation of getDefaultPlayerPathsList. Look for where the existing paths are and put your new one after the existing ones.
  2. In syncplay/constants.py create a constant for your icon using your own new player of the _ICONPATH constant - this will want to be a .png file that you add to the repository.
  3. Create a new .py file in the syncplay/syncplay/players/ folder for your new player.
  4. Use https://github.com/Syncplay/syncplay/blob/master/syncplay/players/basePlayer.py as a starting point guide base for what you will need to implement from syncplay.players.basePlayer import BasePlayer, and then use that as the basis for your new class. You are likely to need to import os.path as well. See above for more details on methods.
  5. At the start of your class, also specify the player variables (see above).
  6. In syncplay/players/init.py import the media player and add the player class to getAvailablePlayers and import your media player..
  7. If you want Syncplay to be officially supporting this player then you will need to add references to it in all the syncplay/messages_*.py references to media players in the player-path-error, player-path-config-error, and executable-path-tooltip messages.