Beispiel #1
0
 /// <summary>
 /// Reports playback start
 /// </summary>
 /// <param name="info">The information.</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 ReportPlaybackStart(PlaybackStartInfo info, bool isOffline, IApiClient apiClient)
 {
     if (!isOffline)
     {
         await apiClient.ReportPlaybackStartAsync(info).ConfigureAwait(false);
     }
 }
        public async Task <ActionResult> OnPlaybackStart(
            [FromRoute] Guid userId,
            [FromRoute] Guid itemId,
            [FromQuery] string?mediaSourceId,
            [FromQuery] int?audioStreamIndex,
            [FromQuery] int?subtitleStreamIndex,
            [FromQuery] PlayMethod playMethod,
            [FromQuery] string?liveStreamId,
            [FromQuery] string playSessionId,
            [FromQuery] bool canSeek = false)
        {
            var playbackStartInfo = new PlaybackStartInfo
            {
                CanSeek             = canSeek,
                ItemId              = itemId,
                MediaSourceId       = mediaSourceId,
                AudioStreamIndex    = audioStreamIndex,
                SubtitleStreamIndex = subtitleStreamIndex,
                PlayMethod          = playMethod,
                PlaySessionId       = playSessionId,
                LiveStreamId        = liveStreamId
            };

            playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
            playbackStartInfo.SessionId  = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
            await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);

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

            try
            {
                var track = BackgroundAudioPlayer.Instance.Track;
                if (track != null)
                {
                    var info = new PlaybackStartInfo
                    {
                        CanSeek             = false,
                        ItemId              = track.Tag,
                        QueueableMediaTypes = new List <string>(),
                    };
                    await _apiClient.ReportPlaybackStartAsync(info);
                }
            }
            catch (HttpException ex)
            {
                _logger.FatalException("InformOfPlayingTrack()", ex);
            }

            NotifyComplete();
        }
        public async Task <ActionResult> ReportPlaybackStart([FromBody] PlaybackStartInfo playbackStartInfo)
        {
            playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
            playbackStartInfo.SessionId  = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;
            await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);

            return(NoContent());
        }
Beispiel #5
0
        /// <summary>
        /// Starts this instance.
        /// </summary>
        /// <returns>Task.</returns>
        public async Task Start()
        {
            var item = _mediaPlayer.CurrentMedia;

            if (item == null)
            {
                return;
            }

            if (item.Id == null)
            {
                // Item is local media to the client (i.e playing local dvd)
                // todo - fix up local media progress reporting
                return;
            }

            try
            {
                var queueTypes = _mediaPlayer.CanQueue
                                     ? new List <string> {
                    item.MediaType
                }
                                     : new List <string> {
                };

                var info = new PlaybackStartInfo
                {
                    ItemId              = item.Id,
                    CanSeek             = _mediaPlayer.CanSeek,
                    QueueableMediaTypes = queueTypes.ToList(),

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

                var apiClient = _connectionManager.GetApiClient(item);

                await apiClient.ReportPlaybackStartAsync(info);

                if (_mediaPlayer.CanTrackProgress)
                {
                    _timer = new Timer(TimerCallback, null, 100, 900);
                }

                _mediaPlayer.MediaChanged      += _mediaPlayer_MediaChanged;
                _mediaPlayer.PlaybackCompleted += _mediaPlayer_PlaybackCompleted;
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error sending playback start checking for {0}", ex, item.Name);

                throw;
            }
        }
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>
        /// Reports the playback start.
        /// </summary>
        /// <param name="message">The message.</param>
        private void OnPlaybackStart(WebSocketMessageInfo message)
        {
            _logger.Debug("Received PlaybackStart message");

            var session = GetSessionFromMessage(message);

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

                var itemId = vals[0];

                var queueableMediaTypes = string.Empty;
                var canSeek             = true;

                if (vals.Length > 1)
                {
                    canSeek = string.Equals(vals[1], "true", StringComparison.OrdinalIgnoreCase);
                }
                if (vals.Length > 2)
                {
                    queueableMediaTypes = vals[2];
                }

                var info = new PlaybackStartInfo
                {
                    CanSeek             = canSeek,
                    ItemId              = itemId,
                    SessionId           = session.Id,
                    QueueableMediaTypes = queueableMediaTypes.Split(',').ToList()
                };

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

                if (vals.Length > 4 && !string.IsNullOrWhiteSpace(vals[4]))
                {
                    info.AudioStreamIndex = int.Parse(vals[4], _usCulture);
                }

                if (vals.Length > 5 && !string.IsNullOrWhiteSpace(vals[5]))
                {
                    info.SubtitleStreamIndex = int.Parse(vals[5], _usCulture);
                }

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

            var session = GetSession(info.SessionId);

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

            UpdateNowPlayingItem(session, info, libraryItem);

            session.QueueableMediaTypes = info.QueueableMediaTypes;

            var users = GetUsers(session);

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

                foreach (var user in users)
                {
                    await OnPlaybackStart(user.Id, key, libraryItem).ConfigureAwait(false);
                }
            }

            // Nothing to save here
            // Fire events to inform plugins
            EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs
            {
                Item          = libraryItem,
                Users         = users,
                MediaSourceId = info.MediaSourceId
            }, _logger);

            await SendPlaybackStartNotification(session, CancellationToken.None).ConfigureAwait(false);
        }
Beispiel #9
0
        private async Task InitiatePlayback(bool isResume, int?subtitleIndex = null)
        {
            Messenger.Default.Send(new NotificationMessage(Constants.Messages.ClearNowPlayingMsg));
            EndTime = TimeSpan.Zero;

            var streamInfo = new StreamInfo();

            switch (PlayerSourceType)
            {
            case PlayerSourceType.Playlist:
            case PlayerSourceType.Video:
                if (SelectedItem.VideoType != VideoType.VideoFile)
                {
                    var result = MessageBox.Show(AppResources.MessageExperimentalVideo, AppResources.MessageExperimentalTitle, MessageBoxButton.OKCancel);
                    if (result == MessageBoxResult.Cancel)
                    {
                        NavigationService.GoBack();
                        return;
                    }
                }

                if (SelectedItem.UserData != null && isResume)
                {
                    _startPositionTicks = SelectedItem.UserData.PlaybackPositionTicks;
                }

                if (_startPositionTicks == 0)
                {
                    // Although the API will return 0 items if the user doesn't have cinema mode enabled,
                    // that's still precious time on a slow connection needlessly wasted. So let's make sure
                    // the user actually has it enabled first.
                    if (AuthenticationService.Current.LoggedInUser.Configuration.EnableCinemaMode)
                    {
                        try
                        {
                            var items = await ApiClient.GetIntrosAsync(SelectedItem.Id, AuthenticationService.Current.LoggedInUserId);

                            if (items != null && !items.Items.IsNullOrEmpty())
                            {
                                if (PlaylistItems == null)
                                {
                                    PlaylistItems = new List <BaseItemDto>(items.Items)
                                    {
                                        SelectedItem
                                    };
                                }
                                else
                                {
                                    var list = items.Items.ToList();
                                    list.AddRange(PlaylistItems);

                                    PlaylistItems = list;
                                }

                                var firstItem = PlaylistItems.FirstOrDefault();
                                if (firstItem != null)
                                {
                                    SelectedItem = firstItem;
                                }
                            }
                        }
                        catch (HttpException ex)
                        {
                            Log.ErrorException("GetIntros (Cinema Mode)", ex);
                        }
                    }
                }

                streamInfo = await CreateVideoStream(SelectedItem.Id, _startPositionTicks, SelectedItem.MediaSources, SelectedItem.Type.ToLower().Equals("channelvideoitem"));

                if (SelectedItem.RunTimeTicks.HasValue)
                {
                    EndTime = TimeSpan.FromTicks(SelectedItem.RunTimeTicks.Value);
                }

                Log.Info("Playing {0} [{1}] ({2})", SelectedItem.Type, SelectedItem.Name, SelectedItem.Id);
                break;

            case PlayerSourceType.Recording:
                streamInfo = await CreateVideoStream(RecordingItem.Id, _startPositionTicks);

                if (RecordingItem.RunTimeTicks.HasValue)
                {
                    EndTime = TimeSpan.FromTicks(RecordingItem.RunTimeTicks.Value);
                }

                Log.Info("Playing {0} [{1}] ({2})", RecordingItem.Type, RecordingItem.Name, RecordingItem.Id);
                break;

            case PlayerSourceType.Programme:
                try
                {
                    var channel = await ApiClient.GetItemAsync(ProgrammeItem.ChannelId, AuthenticationService.Current.LoggedInUserId);

                    streamInfo = await CreateVideoStream(ProgrammeItem.ChannelId, _startPositionTicks, channel.MediaSources, useHls : true);
                }
                catch (HttpException ex)
                {
                    Utils.HandleHttpException(ex, "GetVideoChannel", NavigationService, Log);
                    NavigationService.GoBack();
                    return;
                }

                if (ProgrammeItem.RunTimeTicks.HasValue)
                {
                    EndTime = TimeSpan.FromTicks(ProgrammeItem.RunTimeTicks.Value);
                }

                Log.Info("Playing {0} [{1}] ({2})", ProgrammeItem.Type, ProgrammeItem.Name, ProgrammeItem.Id);
                break;
            }

            if (streamInfo == null)
            {
                NavigationService.GoBack();
                return;
            }

            if (subtitleIndex.HasValue)
            {
                streamInfo.SubtitleStreamIndex = subtitleIndex.Value;
            }

            var url = streamInfo.ToUrl(ApiClient.GetApiUrl("/"), ApiClient.AccessToken);

            _streamInfo = streamInfo;
            //Captions = GetSubtitles(SelectedItem);

            var isSyncedVideo = url.StartsWith("AnyTime", StringComparison.InvariantCultureIgnoreCase);

            if (EndTime.Ticks > 0 && !IsDirectStream)
            {
                EndTime = TimeSpan.FromTicks(EndTime.Ticks - _startPositionTicks);
            }

            StopAudioPlayback();

            _streamInfo = streamInfo;

            if (_isResume && IsDirectStream)
            {
                StartFrom = TimeSpan.FromTicks(_startPositionTicks);
            }

            RaisePropertyChanged(() => IsDirectStream);

            if (isSyncedVideo)
            {
                SetVideoUrl(string.Empty);
                if (VideoStream == null || _storageUrl != url)
                {
                    _storageUrl = url;
                    using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        var stream = storage.OpenFile(url, FileMode.Open);
                        VideoStream = stream;
                    }
                }
            }
            else
            {
                VideoStream = null;
                SetVideoUrl(url);
                _storageUrl = string.Empty;
            }

            Debug.WriteLine(VideoUrl);
            Log.Debug(VideoUrl);

            try
            {
                Log.Info("Sending playback started message to the server.");

                _itemId = streamInfo.ItemId;

                var info = new PlaybackStartInfo
                {
                    ItemId              = _itemId,
                    CanSeek             = false,
                    QueueableMediaTypes = new List <string>()
                };

                await ApiClient.ReportPlaybackStartAsync(info);
            }
            catch (HttpException ex)
            {
                Utils.HandleHttpException("VideoPageLoaded", ex, NavigationService, Log);
            }
        }