void RefreshItems()
        {
            if (Playlist is LocalPlaylist localPlaylist)
            {
                var localPlaylistItems = new ObservableCollection<IVideoContent>(localPlaylist.GetPlaylistItems().ToList());
                PlaylistItems = localPlaylistItems;

                // キューと「あとで見る」はHohoemaPlaylistがリスト内容を管理しているが
                // ローカルプレイリストは内部DBが書き換えられるだけなので
                // 表示向けの更新をVMで引き受ける必要がある
                Observable.FromEventPattern<LocalPlaylistItemRemovedEventArgs>(
                    h => localPlaylist.ItemRemoved += h,
                    h => localPlaylist.ItemRemoved -= h
                    )
                    .Subscribe(e =>
                    {
                        var args = e.EventArgs;
                        foreach (var itemId in args.RemovedItems)
                        {
                            var removedItem = PlaylistItems.FirstOrDefault(x => x.Id == itemId);
                            if (removedItem != null)
                            {
                                localPlaylistItems.Remove(removedItem);
                            }
                        }
                    })
                    .AddTo(_NavigatingCompositeDisposable);

                _localMylistManager.LocalPlaylists.ObserveRemoveChanged()
                    .Subscribe(removed =>
                    {
                        if (Playlist.Id == removed.Id)
                        {
                            _pageManager.ForgetLastPage();
                            _pageManager.OpenPage(HohoemaPageType.UserMylist);
                        }
                    })
                    .AddTo(_NavigatingCompositeDisposable);
            }
            else if (Playlist is PlaylistObservableCollection collection)
            {
                PlaylistItems = collection;
            }
        }
Beispiel #2
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);
            }
        }