/// <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()); }
/// <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; } }
/// <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); } } }
/// <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); } }
/// <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); }
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); } }