private async Task InformOfStoppedTrack()
        {
            if (_apiClient == null)
            {
                return;
            }

            try
            {
                var track = BackgroundAudioPlayer.Instance.Track;
                if (track != null)
                {
                    var info = new PlaybackStopInfo
                    {
                        ItemId = track.Tag,
                        //UserId = _apiClient.CurrentUserId
                    };
                    await _apiClient.ReportPlaybackStoppedAsync(info);
                }
            }
            catch (HttpException ex)
            {
                _logger.FatalException("InformOfStoppedTrack()", ex);
            }

            NotifyComplete();
        }
Beispiel #2
0
        /// <summary>
        /// Handles the PlaybackCompleted event of the _mediaPlayer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="PlaybackStopEventArgs"/> instance containing the event data.</param>
        async void _mediaPlayer_PlaybackCompleted(object sender, PlaybackStopEventArgs e)
        {
            _mediaPlayer.MediaChanged      -= _mediaPlayer_MediaChanged;
            _mediaPlayer.PlaybackCompleted -= _mediaPlayer_PlaybackCompleted;

            if (_timer != null)
            {
                _timer.Dispose();
                _timer = null;
            }

            if (e.EndingMedia != null)
            {
                var info = new PlaybackStopInfo
                {
                    ItemId        = e.EndingMedia.Id,
                    PositionTicks = e.EndingPositionTicks
                };

                var apiClient = _connectionManager.GetApiClient(e.EndingMedia);

                try
                {
                    await apiClient.ReportPlaybackStoppedAsync(info);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error sending playback stopped checking for {0}", ex, e.EndingMedia.Name);
                }
            }
        }
        public async Task <ActionResult> OnPlaybackStopped(
            [FromRoute] Guid userId,
            [FromRoute] Guid itemId,
            [FromQuery] string?mediaSourceId,
            [FromQuery] string?nextMediaType,
            [FromQuery] long?positionTicks,
            [FromQuery] string?liveStreamId,
            [FromQuery] string?playSessionId)
        {
            var playbackStopInfo = new PlaybackStopInfo
            {
                ItemId        = itemId,
                PositionTicks = positionTicks,
                MediaSourceId = mediaSourceId,
                PlaySessionId = playSessionId,
                LiveStreamId  = liveStreamId,
                NextMediaType = nextMediaType
            };

            _logger.LogDebug("ReportPlaybackStopped PlaySessionId: {0}", playbackStopInfo.PlaySessionId ?? string.Empty);
            if (!string.IsNullOrWhiteSpace(playbackStopInfo.PlaySessionId))
            {
                await _transcodingJobHelper.KillTranscodingJobs(_authContext.GetAuthorizationInfo(Request).DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
            }

            playbackStopInfo.SessionId = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
            await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);

            return(NoContent());
        }
Beispiel #4
0
        /// <summary>
        /// Reports the playback stopped.
        /// </summary>
        /// <param name="message">The message.</param>
        private void ReportPlaybackStopped(WebSocketMessageInfo message)
        {
            _logger.Debug("Received PlaybackStopped message");

            var session = GetSessionFromMessage(message);

            if (session != null && session.User != null)
            {
                var vals = message.Data.Split('|');

                var item = _dtoService.GetItemByDtoId(vals[0]);

                long?positionTicks = null;

                if (vals.Length > 1)
                {
                    long pos;

                    if (long.TryParse(vals[1], out pos))
                    {
                        positionTicks = pos;
                    }
                }

                var info = new PlaybackStopInfo
                {
                    Item          = item,
                    PositionTicks = positionTicks,
                    SessionId     = session.Id
                };

                _sessionManager.OnPlaybackStopped(info);
            }
        }
        /// <summary>
        /// Reports playback progress
        /// </summary>
        /// <param name="info">The information.</param>
        /// <param name="serverId">The server identifier.</param>
        /// <param name="userId">The user identifier.</param>
        /// <param name="isOffline">if set to <c>true</c> [is offline].</param>
        /// <param name="isVideo">if set to <c>true</c> [is video].</param>
        /// <param name="apiClient">The current apiClient. It can be null if offline</param>
        /// <returns>Task.</returns>
        public async Task ReportPlaybackStopped(PlaybackStopInfo info, string serverId, string userId, bool isOffline, bool isVideo, IApiClient apiClient)
        {
            if (isOffline)
            {
                var action = new UserAction
                {
                    Date          = DateTime.UtcNow,
                    ItemId        = info.ItemId,
                    PositionTicks = info.PositionTicks,
                    ServerId      = serverId,
                    Type          = UserActionType.PlayedItem,
                    UserId        = userId
                };

                await _localAssetManager.RecordUserAction(action).ConfigureAwait(false);

                return;
            }

            // Put a try/catch here because we need to stop transcoding regardless
            try
            {
                await apiClient.ReportPlaybackStoppedAsync(info).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error in ReportPlaybackStoppedAsync", ex);
            }

            if (isVideo)
            {
                await apiClient.StopTranscodingProcesses(_device.DeviceId).ConfigureAwait(false);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Handles the MediaChanged event of the _mediaPlayer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="MediaChangeEventArgs"/> instance containing the event data.</param>
        async void _mediaPlayer_MediaChanged(object sender, MediaChangeEventArgs e)
        {
            if (e.PreviousMedia != null)
            {
                var info = new PlaybackStopInfo
                {
                    ItemId        = e.PreviousMedia.Id,
                    PositionTicks = e.EndingPositionTicks
                };

                var apiClient = _connectionManager.GetApiClient(e.PreviousMedia);

                try
                {
                    await apiClient.ReportPlaybackStoppedAsync(info);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error sending playback stopped checking for {0}", ex, e.PreviousMedia.Name);
                }
            }

            if (e.NewMedia != null)
            {
                try
                {
                    var queueTypes = _mediaPlayer.CanQueue
                                ? new List <string> {
                        e.NewMedia.MediaType
                    }
                                : new List <string> {
                    };

                    var info = new PlaybackStartInfo
                    {
                        ItemId = e.NewMedia.Id,

                        CanSeek             = _mediaPlayer.CanSeek,
                        QueueableMediaTypes = queueTypes.ToList(),

                        // TODO: Remove this hardcoding
                        PlayMethod = PlayMethod.DirectPlay
                    };

                    var apiClient = _connectionManager.GetApiClient(e.NewMedia);

                    await apiClient.ReportPlaybackStartAsync(info);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error sending playback start checking for {0}", ex, e.NewMedia.Name);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Used to report that playback has ended for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">info</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackStopped(PlaybackStopInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.Item == null)
            {
                throw new ArgumentException("PlaybackStopInfo.Item cannot be null");
            }

            if (info.SessionId == Guid.Empty)
            {
                throw new ArgumentException("PlaybackStopInfo.SessionId cannot be Guid.Empty");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = Sessions.First(i => i.Id.Equals(info.SessionId));

            RemoveNowPlayingItem(session, info.Item);

            var key = info.Item.GetUserDataKey();

            var user = session.User;

            var data = _userDataRepository.GetUserData(user.Id, key);

            if (info.PositionTicks.HasValue)
            {
                UpdatePlayState(info.Item, data, info.PositionTicks.Value);
            }
            else
            {
                // If the client isn't able to report this, then we'll just have to make an assumption
                data.PlayCount++;
                data.Played = true;
                data.PlaybackPositionTicks = 0;
            }

            await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false);

            EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackProgressEventArgs
            {
                Item = info.Item,
                User = user,
                PlaybackPositionTicks = info.PositionTicks
            }, _logger);
        }
        public async Task <ActionResult> ReportPlaybackStopped([FromBody] PlaybackStopInfo playbackStopInfo)
        {
            _logger.LogDebug("ReportPlaybackStopped PlaySessionId: {0}", playbackStopInfo.PlaySessionId ?? string.Empty);
            if (!string.IsNullOrWhiteSpace(playbackStopInfo.PlaySessionId))
            {
                await _transcodingJobHelper.KillTranscodingJobs(_authContext.GetAuthorizationInfo(Request).DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
            }

            playbackStopInfo.SessionId = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
            await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);

            return(NoContent());
        }
Beispiel #9
0
        /// <summary>
        /// Used to report that playback has ended for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">info</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackStopped(PlaybackStopInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = GetSession(info.SessionId);

            var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
                ? null
                : _libraryManager.GetItemById(new Guid(info.ItemId));

            // Normalize
            if (string.IsNullOrWhiteSpace(info.MediaSourceId))
            {
                info.MediaSourceId = info.ItemId;
            }

            RemoveNowPlayingItem(session);

            var users = GetUsers(session);
            var playedToCompletion = false;

            if (libraryItem != null)
            {
                var key = libraryItem.GetUserDataKey();

                foreach (var user in users)
                {
                    playedToCompletion = await OnPlaybackStopped(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false);
                }
            }

            EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
            {
                Item  = libraryItem,
                Users = users,
                PlaybackPositionTicks = info.PositionTicks,
                PlayedToCompletion    = playedToCompletion,
                MediaSourceId         = info.MediaSourceId
            }, _logger);

            await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false);
        }
        /// <summary>
        /// Used to report that playback has ended for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">info</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackStopped(PlaybackStopInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.Item == null)
            {
                throw new ArgumentException("PlaybackStopInfo.Item cannot be null");
            }

            if (info.SessionId == Guid.Empty)
            {
                throw new ArgumentException("PlaybackStopInfo.SessionId cannot be Guid.Empty");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = Sessions.First(i => i.Id.Equals(info.SessionId));

            RemoveNowPlayingItem(session, info.Item);

            var key = info.Item.GetUserDataKey();

            var users = GetUsers(session);

            var playedToCompletion = false;

            foreach (var user in users)
            {
                playedToCompletion = await OnPlaybackStopped(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
            }

            EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
            {
                Item  = info.Item,
                Users = users,
                PlaybackPositionTicks = info.PositionTicks,
                PlayedToCompletion    = playedToCompletion
            }, _logger);
        }
Beispiel #11
0
        /// <summary>
        /// Posts the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        public void Delete(OnPlaybackStopped request)
        {
            var user = _userManager.GetUserById(request.UserId);

            var item = _dtoService.GetItemByDtoId(request.Id, user.Id);

            var session = GetSession();

            var info = new PlaybackStopInfo
            {
                Item          = item,
                PositionTicks = request.PositionTicks,
                SessionId     = session.Id
            };

            var task = _sessionManager.OnPlaybackStopped(info);

            Task.WaitAll(task);
        }
Beispiel #12
0
        /// <summary>
        /// Reports the playback stopped.
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnPlaybackStopped(WebSocketMessageInfo message)
        {
            _logger.Debug("Received PlaybackStopped message");

            var session = GetSessionFromMessage(message);

            if (session != null && session.UserId.HasValue)
            {
                var vals = message.Data.Split('|');

                var itemId = vals[0];

                long?positionTicks = null;

                if (vals.Length > 1)
                {
                    long pos;

                    if (long.TryParse(vals[1], out pos))
                    {
                        positionTicks = pos;
                    }
                }

                var info = new PlaybackStopInfo
                {
                    ItemId        = itemId,
                    PositionTicks = positionTicks,
                    SessionId     = session.Id
                };

                if (vals.Length > 2)
                {
                    info.MediaSourceId = vals[2];
                }

                _sessionManager.OnPlaybackStopped(info);
            }
        }
Beispiel #13
0
        /// <summary>
        /// Reports playback progress
        /// </summary>
        /// <param name="info">The information.</param>
        /// <param name="streamInfo">The stream information.</param>
        /// <param name="serverId">The server identifier.</param>
        /// <param name="userId">The user identifier.</param>
        /// <param name="isOffline">if set to <c>true</c> [is offline].</param>
        /// <param name="apiClient">The current apiClient. It can be null if offline</param>
        /// <returns>Task.</returns>
        public async Task ReportPlaybackStopped(PlaybackStopInfo info, StreamInfo streamInfo, string serverId, string userId, bool isOffline, IApiClient apiClient)
        {
            if (isOffline)
            {
                var action = new UserAction
                {
                    Date          = DateTime.UtcNow,
                    ItemId        = info.ItemId,
                    PositionTicks = info.PositionTicks,
                    ServerId      = serverId,
                    Type          = UserActionType.PlayedItem,
                    UserId        = userId
                };

                await _localAssetManager.RecordUserAction(action).ConfigureAwait(false);

                return;
            }

            if (streamInfo != null)
            {
                info.PlaySessionId = streamInfo.PlaySessionId;

                if (streamInfo.MediaSource != null)
                {
                    info.LiveStreamId = streamInfo.MediaSource.LiveStreamId;
                }
            }

            // Put a try/catch here because we need to stop transcoding regardless
            try
            {
                await apiClient.ReportPlaybackStoppedAsync(info).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error in ReportPlaybackStoppedAsync", ex);
            }
        }
        /// <summary>
        /// Reports the playback stopped.
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnPlaybackStopped(WebSocketMessageInfo message)
        {
            _logger.Debug("Received PlaybackStopped message");

            var session = GetSessionFromMessage(message);

            if (session != null && session.UserId.HasValue)
            {
                var vals = message.Data.Split('|');

                var itemId = vals[0];

                long? positionTicks = null;

                if (vals.Length > 1)
                {
                    long pos;

                    if (long.TryParse(vals[1], out pos))
                    {
                        positionTicks = pos;
                    }
                }

                var info = new PlaybackStopInfo
                {
                    ItemId = itemId,
                    PositionTicks = positionTicks,
                    SessionId = session.Id
                };

                if (vals.Length > 2)
                {
                    info.MediaSourceId = vals[2];
                }

                _sessionManager.OnPlaybackStopped(info);
            }
        }
Beispiel #15
0
        /// <summary>
        /// Used to report that playback has ended for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">info</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackStopped(PlaybackStopInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = GetSession(info.SessionId);

            var libraryItem = string.IsNullOrWhiteSpace(info.ItemId)
                ? null
                : _libraryManager.GetItemById(new Guid(info.ItemId));

            // Normalize
            if (string.IsNullOrWhiteSpace(info.MediaSourceId))
            {
                info.MediaSourceId = info.ItemId;
            }

            if (!string.IsNullOrWhiteSpace(info.ItemId) && libraryItem != null)
            {
                var current = session.NowPlayingItem;

                if (current == null || !string.Equals(current.Id, info.ItemId, StringComparison.OrdinalIgnoreCase))
                {
                    info.Item = GetItemInfo(libraryItem, libraryItem, info.MediaSourceId);
                }
                else
                {
                    info.Item = current;
                }
            }

            RemoveNowPlayingItem(session);

            var users = GetUsers(session);
            var playedToCompletion = false;

            if (libraryItem != null)
            {
                var key = libraryItem.GetUserDataKey();

                foreach (var user in users)
                {
                    playedToCompletion = await OnPlaybackStopped(user.Id, key, libraryItem, info.PositionTicks).ConfigureAwait(false);
                }
            }

            EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
            {
                Item = libraryItem,
                Users = users,
                PlaybackPositionTicks = info.PositionTicks,
                PlayedToCompletion = playedToCompletion,
                MediaSourceId = info.MediaSourceId,
                MediaInfo = info.Item,
                DeviceName = session.DeviceName,
                ClientName = session.Client,
                DeviceId = session.DeviceId

            }, _logger);

            await SendPlaybackStoppedNotification(session, CancellationToken.None).ConfigureAwait(false);
        }
        /// <summary>
        /// Used to report that playback has ended for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">info</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackStopped(PlaybackStopInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.Item == null)
            {
                throw new ArgumentException("PlaybackStopInfo.Item cannot be null");
            }

            if (info.SessionId == Guid.Empty)
            {
                throw new ArgumentException("PlaybackStopInfo.SessionId cannot be Guid.Empty");
            }
            
            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = Sessions.First(i => i.Id.Equals(info.SessionId));

            RemoveNowPlayingItem(session, info.Item);

            var key = info.Item.GetUserDataKey();

            var user = session.User;

            var data = _userDataRepository.GetUserData(user.Id, key);

            if (info.PositionTicks.HasValue)
            {
                UpdatePlayState(info.Item, data, info.PositionTicks.Value);
            }
            else
            {
                // If the client isn't able to report this, then we'll just have to make an assumption
                data.PlayCount++;
                data.Played = true;
                data.PlaybackPositionTicks = 0;
            }

            await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false);

            EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackProgressEventArgs
            {
                Item = info.Item,
                User = user,
                PlaybackPositionTicks = info.PositionTicks
            }, _logger);
        }
Beispiel #17
0
        /// <summary>
        /// Used to report that playback has ended for an item
        /// </summary>
        /// <param name="info">The info.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">info</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">positionTicks</exception>
        public async Task OnPlaybackStopped(PlaybackStopInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (info.Item == null)
            {
                throw new ArgumentException("PlaybackStopInfo.Item cannot be null");
            }

            if (info.SessionId == Guid.Empty)
            {
                throw new ArgumentException("PlaybackStopInfo.SessionId cannot be Guid.Empty");
            }

            if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
            {
                throw new ArgumentOutOfRangeException("positionTicks");
            }

            var session = Sessions.First(i => i.Id.Equals(info.SessionId));

            RemoveNowPlayingItem(session, info.Item);

            var key = info.Item.GetUserDataKey();

            var users = GetUsers(session);

            var playedToCompletion = false;
            foreach (var user in users)
            {
                playedToCompletion = await OnPlaybackStopped(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
            }

            EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
            {
                Item = info.Item,
                Users = users,
                PlaybackPositionTicks = info.PositionTicks,
                PlayedToCompletion = playedToCompletion

            }, _logger);
        }
        private void ReportEmbyStatus()
        {
            //used to report position on stop - by the time the reporter polls, the player might have closed already
            //long lastPosition = 0;
            //when MPC-HC is loading a file, its state is None;
            //before playback starts properly, newer versions of MPC-HC may also report Paused or even Stopped
            //This flag prevents the reporter from terminating before the player loads the file
            bool startedPlaying = false;

            var stopwatch = new Stopwatch();

            log.Debug("ProgressReporter thread starting");
            for (;;)
            {
                stopwatch.Start();
                var status = player.GetPlayerStatus();

                if (!startedPlaying)
                {
                    startedPlaying = status.State == PlayerState.Playing;
                }
                else
                {
                    if (status.State == PlayerState.Stopped)
                    {
                        log.Info("MPC-HC is no longer playing");
                        var stopInfo = new PlaybackStopInfo
                        {
                            ItemId        = itemId,
                            PositionTicks = status.Position * Utils.EmbyTicksPerMs
                        };
                        Utils.IgnoreExceptions(() => embyClient.ReportPlaybackStoppedAsync(stopInfo).Wait());
                        OnPlayerStopped(EventArgs.Empty);
                        log.Info("Progress reporter terminating");
                        return;
                    }

                    var progressInfo = new PlaybackProgressInfo
                    {
                        CanSeek       = player.CanSeek(),
                        IsPaused      = status.State == PlayerState.Paused,
                        IsMuted       = status.Muted,
                        ItemId        = itemId,
                        PlayMethod    = PlayMethod.DirectPlay,
                        PositionTicks = status.Position * Utils.EmbyTicksPerMs,
                        VolumeLevel   = status.VolumeLevel,
                        RepeatMode    = RepeatMode.RepeatNone
                    };
                    Utils.IgnoreExceptions(() => embyClient.ReportPlaybackProgressAsync(progressInfo).Wait());
                    //lastPosition = status.Position;
                }

                stopwatch.Stop();
                int sleepTime = reportPeriod - (int)stopwatch.ElapsedMilliseconds;
                log.DebugFormat("Status report took {0}ms.", stopwatch.ElapsedMilliseconds);
                lock (monitor)
                {
                    if (stop)
                    {
                        break;
                    }
                    if (sleepTime > 0)
                    {
                        Monitor.Wait(monitor, sleepTime);
                    }
                    if (stop)
                    {
                        break;
                    }
                }
                stopwatch.Reset();
            }
        }
Beispiel #19
0
        public override void WireMessages()
        {
            Messenger.Default.Register <VideoMessage>(this, m =>
            {
                PlaylistItems = null;
                switch (m.PlayerSourceType)
                {
                case PlayerSourceType.Video:
                    if (m.VideoItem != null)
                    {
                        SelectedItem  = m.VideoItem;
                        PlaylistItems = null;
                    }
                    break;

                case PlayerSourceType.Recording:
                    if (m.VideoItem != null)
                    {
                        RecordingItem = m.VideoItem;
                        PlaylistItems = null;
                    }
                    break;

                case PlayerSourceType.Programme:
                    if (m.VideoItem != null)
                    {
                        ProgrammeItem = m.VideoItem;
                        PlaylistItems = null;
                    }
                    break;

                case PlayerSourceType.Playlist:
                    PlaylistItems = m.VideoPlaylists;
                    SelectedItem  = m.VideoItem;
                    break;
                }

                PlayerSourceType    = m.PlayerSourceType;
                _isResume           = m.IsResume;
                _startPositionTicks = m.ResumeTicks ?? 0;
            });

            Messenger.Default.Register <NotificationMessage>(this, async m =>
            {
                if (m.Notification.Equals(Constants.Messages.SetResumeMsg))
                {
                    _isResume = true;
                }

                if (m.Notification.Equals(Constants.Messages.SendVideoTimeToServerMsg))
                {
                    try
                    {
                        var totalTicks = _startPositionTicks + PlayedVideoDuration.Ticks;

                        Log.Info("Sending current runtime [{0}] to the server", totalTicks);

                        var info = new PlaybackStopInfo
                        {
                            ItemId        = _itemId,
                            PositionTicks = totalTicks
                        };

                        await _playbackManager.ReportPlaybackStopped(info, _streamInfo, App.ServerInfo.Id, AuthenticationService.Current.LoggedInUserId, false, ApiClient);

                        SetPlaybackTicks(totalTicks);

                        if (_timer != null && _timer.IsEnabled)
                        {
                            _timer.Stop();
                        }

                        Messenger.Default.Send(new NotificationMessage(_itemId, totalTicks, Constants.Messages.RefreshResumeMsg));
                    }
                    catch (HttpException ex)
                    {
                        Utils.HandleHttpException("SendVideoTimeToServer", ex, NavigationService, Log);
                    }

                    if (!PlaylistItems.IsNullOrEmpty())
                    {
                        var index = PlaylistItems.IndexOf(SelectedItem);
                        if (index >= 0 && index < PlaylistItems.Count - 1)
                        {
                            SelectedItem = PlaylistItems[index + 1];
                            await InitiatePlayback(false);
                        }
                    }
                }

                if (m.Notification.Equals(Constants.Messages.VideoStateChangedMsg))
                {
                    try
                    {
                        var totalTicks = _startPositionTicks + PlayedVideoDuration.Ticks;
                        var isPaused   = m.Sender != null && (bool)m.Sender;

                        if (_timer != null)
                        {
                            if (isPaused)
                            {
                                if (_timer.IsEnabled)
                                {
                                    _timer.Stop();
                                }
                            }
                            else
                            {
                                if (!_timer.IsEnabled)
                                {
                                    _timer.Start();
                                }
                            }
                        }

                        Log.Info("Sending current runtime [{0}] to the server", totalTicks);

                        var info = new PlaybackProgressInfo
                        {
                            IsMuted       = false,
                            ItemId        = _itemId,
                            PositionTicks = totalTicks,
                            IsPaused      = isPaused
                        };

                        await ApiClient.ReportPlaybackProgressAsync(info);
                        SetPlaybackTicks(totalTicks);
                    }
                    catch (HttpException ex)
                    {
                        Utils.HandleHttpException("VideoStateChanged", ex, NavigationService, Log);
                    }
                }
            });
        }