/// <inheritdoc/>
        /// <exception cref="ObjectDisposedException">thrown if the instance is disposed</exception>
        public async Task <TPlayer> JoinAsync <TPlayer>(
            PlayerFactory <TPlayer> playerFactory, ulong guildId, ulong voiceChannelId, bool selfDeaf = false,
            bool selfMute = false) where TPlayer : LavalinkPlayer
        {
            EnsureNotDisposed();

            var player = GetPlayer <TPlayer>(guildId);

            if (player is null)
            {
                Players[guildId] = player = LavalinkPlayer.CreatePlayer(
                    playerFactory, this, _discordClient, guildId, _disconnectOnStop);
            }

            if (!player.VoiceChannelId.HasValue || player.VoiceChannelId != voiceChannelId)
            {
                await player.ConnectAsync(voiceChannelId, selfDeaf, selfMute);
            }

            return(player);
        }