示例#1
0
        void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e)
        {
            if (!Plugin.Instance.Configuration.SelectedGUIDs.Contains(e.Session.UserId.HasValue ? e.Session.UserId.Value.ToString("N") : null))
            {
                return;
            }
            Plugin.DebugLogger("Session manager PlaybackStart!");
            SessionDescriptor descr = new SessionDescriptor((Guid)e.Session.UserId,
                                                            e.Session.FullNowPlayingItem.Id);

            // First one to play
            if (!content_state.ContainsKey(descr))
            {
                content_state[descr] = new TogetherSession(TogetherSession.State.playing)
                {
                    ticks = e.PlaybackPositionTicks
                };
                Plugin.DebugLogger("Created new EmbyTogether Session!");
            }
            // Someone else is already playing, seek to their location
            else
            {
                Plugin.DebugLogger("New Client joining to established Session!");
                // Lets get the first matching session with matching userid and content id
                var sessions = _sessionManager.Sessions.Where(
                    s => e.Session.UserId == s.UserId &&
                    e.Session.FullNowPlayingItem.Id == s.FullNowPlayingItem.Id &&
                    s.Id != e.Session.Id &&    // force different session, otherwise we might pick up ourselves
                    s.IsActive
                    );

                if (sessions.Count() > 0)
                {
                    // Get ticks from this session and seek new user there
                    var session = sessions.First();

                    long last_update = session.LastActivityDate.Ticks;
                    long current     = DateTime.Now.Ticks;
                    Plugin.DebugLogger($"Difference in ticks: {last_update} {current} {current - last_update}!");
                    send_seek_command(session.PlayState.PositionTicks, e.Session.Id, e.Session.UserId);

                    // Is the current state paused? If yes, pause new user
                    if (content_state[descr].state == TogetherSession.State.paused)
                    {
                        send_command(PlaystateCommand.Pause, e.Session.Id, e.Session.UserId);
                    }
                }
                else
                {
                    Plugin.DebugLogger("Session exists, but without users. This should never happen!");
                }
            }
        }
示例#2
0
        void _sessionManager_PlaybackProgress(object sender, PlaybackProgressEventArgs e)
        {
            if (!Plugin.Instance.Configuration.SelectedGUIDs.Contains(e.Session.UserId.HasValue ? e.Session.UserId.Value.ToString("N") : null))
            {
                return;
            }
            //Plugin.DebugLogger($"Session manager PlaybackProgress! {e.PlaybackPositionTicks}, {e.IsPaused}, {e.Session.UserId.Value.ToString("N")}, {e.Session.FullNowPlayingItem.Id}");
            Plugin.DebugLogger($"{e.Session.Id}: Session manager PlaybackProgress::! {e.PlaybackPositionTicks}, {e.IsPaused}");


            SessionDescriptor descr = new SessionDescriptor((Guid)e.Session.UserId,
                                                            e.Session.FullNowPlayingItem.Id);

            // Playback Progress might get triggered before playback started --> key might not exist yet
            if (!content_state.ContainsKey(descr))
            {
                Plugin.DebugLogger($"{e.Session.Id}: Key not Found!");
                return;
            }
            TogetherSession ts = content_state[descr];

            // only check play/pause changes at most once per 5 seconds, to avoid feedback loops (reduced to 1, if same user issued last command)
            Plugin.DebugLogger($"{e.Session.Id}: Time from last command: {(DateTime.Now - ts.last_update).TotalSeconds}");
            if (((DateTime.Now - ts.last_update).TotalSeconds > Plugin.Instance.Configuration.Timeoffset_cmd_same_user && ts.last_commander_uid == e.Session.UserId) ||
                ((DateTime.Now - ts.last_update).TotalSeconds > Plugin.Instance.Configuration.Timeoffset_cmd_diff_user))
            {
                List <PlaystateRequest> commands = ProcessClientstate(e, ts);

                int    num     = 0;
                string targets = $"{e.Session.Id}: Send to: ";
                //only send commands to sessions of the same user which play the same content
                foreach (SessionInfo s in _sessionManager.Sessions.Where(s =>
                                                                         e.Session.UserId == s.UserId &&
                                                                         e.Session.FullNowPlayingItem.Id == s.FullNowPlayingItem.Id &&
                                                                         s.Id != e.Session.Id))
                {
                    // Plugin.DebugLogger($"{e.Session.Id}: Sending command to #{num} {s.UserId.Value.ToString("N")}, {s.FullNowPlayingItem.Id}");
                    num++;
                    foreach (var command in commands)
                    {
                        _sessionManager.SendPlaystateCommand(s.Id, s.Id, command, CancellationToken.None);
                    }
                    targets += $"{s.Id}; ";
                }
                Plugin.DebugLogger(targets);
            }
            else
            {
                Plugin.DebugLogger($"{e.Session.Id}: Not scanning package for commands, since it arrived too soon!");
            }
        }
示例#3
0
        private static List <PlaystateRequest> ProcessClientstate(PlaybackProgressEventArgs e, TogetherSession ts)
        {
            List <PlaystateRequest> commands = new List <PlaystateRequest>();

            //Check for seeking [no command send, just different time)
            // Plugin.DebugLogger($"{e.Session.Id}: Seeking chk! {Math.Abs(ts.ticks - e.PlaybackPositionTicks ?? 0)}, {ts.ticks}, {e.PlaybackPositionTicks}, {e.IsPaused}");
            if (Math.Abs((ts.ticks - e.PlaybackPositionTicks) ?? 0) > Plugin.Instance.Configuration.Timeoffset_seek * 10000000) // 10000000 == 1 second
            {
                //Assume a user has seeked. --> seek with all users
                Plugin.DebugLogger($"{e.Session.Id}: Seeking all clients! {Math.Abs(ts.ticks - e.PlaybackPositionTicks ?? 0)} {e.PlaybackPositionTicks}, {e.IsPaused}");
                commands.Add(new PlaystateRequest
                {
                    Command           = PlaystateCommand.Seek,
                    SeekPositionTicks = e.PlaybackPositionTicks,
                    ControllingUserId = e.Session.UserId.HasValue ? e.Session.UserId.Value.ToString("N") : null
                });
            }
            ts.ticks = e.PlaybackPositionTicks; // TODO: This will jump around with multiple clients. implement some kind of averaging?

            //if stream paused, but state is playing, pause all clients
            if (e.IsPaused && ts.state == TogetherSession.State.playing)
            {
                //pause all clients
                Plugin.DebugLogger($"{e.Session.Id}: Pausing all clients! {e.PlaybackPositionTicks}, {e.IsPaused}");
                commands.Add(new PlaystateRequest
                {
                    Command           = PlaystateCommand.Pause,
                    ControllingUserId = e.Session.UserId.HasValue ? e.Session.UserId.Value.ToString("N") : null
                });
                ts.state              = TogetherSession.State.paused;
                ts.last_update        = DateTime.Now;
                ts.last_commander_uid = e.Session.UserId;
            }
            else if (!e.IsPaused && ts.state == TogetherSession.State.paused)
            {
                // Seek all clients to the time of the unpausing user
                Plugin.DebugLogger($"{e.Session.Id}: Unpausing all clients! {e.PlaybackPositionTicks}, {e.IsPaused}");
                commands.Add(new PlaystateRequest
                {
                    Command           = PlaystateCommand.Seek,
                    SeekPositionTicks = e.PlaybackPositionTicks,
                    ControllingUserId = e.Session.UserId.HasValue ? e.Session.UserId.Value.ToString("N") : null
                });
                // Unpause all clients
                commands.Add(new PlaystateRequest
                {
                    Command           = PlaystateCommand.Unpause,
                    ControllingUserId = e.Session.UserId.HasValue ? e.Session.UserId.Value.ToString("N") : null
                });
                ts.state              = TogetherSession.State.playing;
                ts.last_update        = DateTime.Now;
                ts.last_commander_uid = e.Session.UserId;
            }
            return(commands);
        }