private void QueuePlayableItemLegacy(PlayableItem playable) { Microsoft.MediaCenter.MediaType type = MediaType.Audio; bool success = true; if (playable.HasMediaItems && playable.MediaItems.All(f => f.WillStream && f is Song)) { IEnumerable <string> files = playable.FilesFormattedForPlayer; string playlistFile = PlaybackControllerHelper.CreateASXPlaylist(playable); if (!PlaybackControllerHelper.CallPlayMedia(Application.MediaCenterEnvironment, type, playlistFile, true)) { success = false; } } else { foreach (string file in playable.FilesFormattedForPlayer) { if (!PlaybackControllerHelper.CallPlayMedia(Application.MediaCenterEnvironment, type, file, true)) { success = false; break; } } } if (!success) { OnErrorPlayingItem(playable, "PlayMedia returned false"); } }
public PlayableItem Create(Media media) { PlayableItem playable = null; foreach (CanPlay canPlay in PlayableItems.Keys) { if (canPlay(media)) { Type type = PlayableItems[canPlay]; playable = (PlayableItem)Activator.CreateInstance(type, media); break; } } if (playable == null) { playable = new PlayableVideoFile(media); } foreach (var controller in Kernel.Instance.PlaybackControllers) { if (controller.CanPlay(playable.Filename)) { playable.PlaybackController = controller; return(playable); } } return(playable); }
/// <summary> /// Gets arguments to be passed to the command line. /// http://wiki.videolan.org/VLC_command-line_help /// </summary> protected override List<string> GetCommandArgumentsList(PlayableItem playInfo) { List<string> args = new List<string>(); args.Add("{0}"); // Be explicit about start time, to avoid any possible player auto-resume settings double startTimeInSeconds = new TimeSpan(playInfo.StartPositionTicks).TotalSeconds; args.Add("--start-time=" + startTimeInSeconds); // Play in fullscreen args.Add("--fullscreen"); // Keep the window on top of others args.Add("--video-on-top"); // Start a new instance args.Add("--no-one-instance"); // Close the player when playback finishes args.Add("--play-and-exit"); // Disable system screen saver during playback args.Add("--disable-screensaver"); // Keep the ui minimal args.Add("--qt-minimal-view"); args.Add("--no-video-deco"); args.Add("--no-playlist-tree"); // OSD marquee font args.Add("--freetype-outline-thickness=6"); // Startup the Http interface so we can send out requests to monitor playstate args.Add("--extraintf=http"); args.Add("--http-host=" + HttpServer); args.Add("--http-port=" + HttpPort); // Disable the new version notification for this session args.Add("--no-qt-updates-notif"); // Map the stop button on the remote to close the player args.Add("--global-key-quit=\"Media Stop\""); args.Add("--global-key-play=\"Media Play\""); args.Add("--global-key-pause=\"Media Pause\""); args.Add("--global-key-play-pause=\"Media Play Pause\""); args.Add("--global-key-vol-down=\"Volume Down\""); args.Add("--global-key-vol-up=\"Volume Up\""); args.Add("--global-key-vol-mute=\"Mute\""); args.Add("--key-nav-up=\"Up\""); args.Add("--key-nav-down=\"Down\""); args.Add("--key-nav-left=\"Left\""); args.Add("--key-nav-right=\"Right\""); args.Add("--key-nav-activate=\"Enter\""); args.Add("--global-key-jump-long=\"Media Prev Track\""); args.Add("--global-key-jump+long=\"Media Next Track\""); return args; }
/// <summary> /// This is designed to help subclasses during the Progress and Finished event. /// Most subclasses can identify the currently playing file, so this uses that to determine the corresponding Media object that's playing /// If a subclass can figure this out on their own, it's best that they do so to avoid traversing the entire playlist /// </summary> private void NormalizeEventProperties(PlaybackStateEventArgs args) { PlayableItem playable = args.Item; if (playable != null) { // Auto-fill current file index if there's only one file if (args.CurrentFileIndex == -1 && playable.FilesFormattedForPlayer.Count() == 1) { args.CurrentFileIndex = 0; } // Fill this in if the subclass wasn't able to supply it if (playable.HasMediaItems && args.CurrentMediaIndex == -1) { // If there's only one Media item, set CurrentMediaId in the args object // This is just a convenience for subclasses that only support one Media at a time if (playable.MediaItems.Count() == 1) { args.CurrentMediaIndex = 0; } else { SetMediaEventPropertiesBasedOnCurrentFileIndex(playable, args); } } } }
internal async void OnPlaybackStopped(PlayableItem media, long?positionTicks, TrackCompletionReason reason, int?newTrackIndex) { DisposeMount(media); // TODO // Notify }
private void PlayQueue_ItemTapped(object sender, TappedRoutedEventArgs e) { PlayableItem i = (sender as Grid).Tag as PlayableItem; if (i == null) return; MenuFlyout menuFlyout = new MenuFlyout(); string str = i.DisplayName; if (str.Length > 15) str = str.Substring(0, 14) + "..."; MenuFlyoutItem miDelete = new MenuFlyoutItem(); menuFlyout.Items.Add(miDelete); miDelete.Text = "delete '" + str + "'"; miDelete.Click += (object ss, RoutedEventArgs ee) => { MainViewModel.Instance.DeleteFromQueue(i); }; MenuFlyoutItem miNext = new MenuFlyoutItem(); menuFlyout.Items.Add(miNext); miNext.Text = "play '" + str + "' next"; miNext.Click += (object ss, RoutedEventArgs ee) => { MainViewModel.Instance.PlayNext(i); }; MenuFlyoutItem miNow = new MenuFlyoutItem(); menuFlyout.Items.Add(miNow); miNow.Text = "play '" + str + "' now"; miNow.Click += (object ss, RoutedEventArgs ee) => { MainViewModel.Instance.PlayNow(i); }; menuFlyout.ShowAt(sender as Grid); }
public PlayableItem Create(Video video) { PlayableItem playable = null; if (PlayableExternal.CanPlay(video.Path)) { playable = new PlayableExternal(video.Path); } else if (PlayableVideoFile.CanPlay(video)) { playable = new PlayableVideoFile(video); } else if (PlayableIso.CanPlay(video)) { playable = new PlayableIso(video); } else if (PlayableMultiFileVideo.CanPlay(video)) { playable = new PlayableMultiFileVideo(video); } else if (PlayableDvd.CanPlay(video)) { playable = new PlayableDvd(video); } foreach (var controller in Kernel.Instance.PlaybackControllers) { if (controller.CanPlay(playable.Filename)) { playable.PlaybackController = controller; } } return(playable); }
/// <summary> /// Creates a PlayableItem based on a Media object /// </summary> public PlayableItem Create(Media media) { Video video = media as Video; bool unmountISOAfterPlayback = false; bool useAutoPlay = false; if (video != null && video.MediaType == MediaType.ISO && !CanPlayIsoDirectly(GetAllKnownPlayables(), video)) { media = MountAndGetNewMedia(video); unmountISOAfterPlayback = true; useAutoPlay = Config.Instance.UseAutoPlayForIso; } PlayableItem playable = Create(new Media[] { media }); // Force any streaming item into internal player if not supported by playable if (media.WillStream && !playable.SupportsStreamedContent) { Logging.Logger.ReportInfo("Forcing streamed item {0}/{1} into internal player", media.Name, media.Path); return(CreateForInternalPlayer(new [] { media })); } playable.UnmountISOAfterPlayback = unmountISOAfterPlayback; playable.UseAutoPlay = useAutoPlay; playable.GoFullScreen = playable.GoFullScreen || media is Song; return(playable); }
/// <summary> /// Gets arguments to be passed to the command line. /// http://wiki.videolan.org/VLC_command-line_help /// </summary> protected override List <string> GetCommandArgumentsList(PlayableItem playInfo) { List <string> args = new List <string>(); args.Add("{0}"); // Be explicit about start time, to avoid any possible player auto-resume settings double startTimeInSeconds = new TimeSpan(playInfo.StartPositionTicks).TotalSeconds; args.Add("--start-time=" + startTimeInSeconds); // Play in fullscreen args.Add("--fullscreen"); // Keep the window on top of others args.Add("--video-on-top"); // Start a new instance args.Add("--no-one-instance"); // Close the player when playback finishes args.Add("--play-and-exit"); // Disable system screen saver during playback args.Add("--disable-screensaver"); // Keep the ui minimal args.Add("--qt-minimal-view"); args.Add("--no-video-deco"); args.Add("--no-playlist-tree"); // OSD marquee font args.Add("--freetype-outline-thickness=6"); // Startup the Http interface so we can send out requests to monitor playstate args.Add("--extraintf=http"); args.Add("--http-host=" + HttpServer); args.Add("--http-port=" + HttpPort); // Disable the new version notification for this session args.Add("--no-qt-updates-notif"); // Map the stop button on the remote to close the player args.Add("--global-key-quit=\"Media Stop\""); args.Add("--global-key-play=\"Media Play\""); args.Add("--global-key-pause=\"Media Pause\""); args.Add("--global-key-play-pause=\"Media Play Pause\""); args.Add("--global-key-vol-down=\"Volume Down\""); args.Add("--global-key-vol-up=\"Volume Up\""); args.Add("--global-key-vol-mute=\"Mute\""); args.Add("--key-nav-up=\"Up\""); args.Add("--key-nav-down=\"Down\""); args.Add("--key-nav-left=\"Left\""); args.Add("--key-nav-right=\"Right\""); args.Add("--key-nav-activate=\"Enter\""); args.Add("--global-key-jump-long=\"Media Prev Track\""); args.Add("--global-key-jump+long=\"Media Next Track\""); return(args); }
/// <summary> /// Takes the current playing file in PlaybackStateEventArgs and uses that to determine the corresponding Media object /// </summary> private void SetMediaEventPropertiesBasedOnCurrentFileIndex(PlayableItem playable, PlaybackStateEventArgs state) { int mediaIndex = -1; if (state.CurrentFileIndex != -1) { int totalFileCount = 0; int numMediaItems = playable.MediaItems.Count(); for (int i = 0; i < numMediaItems; i++) { int numFiles = playable.MediaItems.ElementAt(i).Files.Count(); if (totalFileCount + numFiles > state.CurrentFileIndex) { mediaIndex = i; break; } totalFileCount += numFiles; } } state.CurrentMediaIndex = mediaIndex; }
/// <summary> /// Gets arguments to be passed to the command line. /// </summary> protected override List <string> GetCommandArgumentsList(PlayableItem playbackInfo) { var args = new List <string> { "uri={0}" }; return(args); }
/// <summary> /// Creates a PlayableItem based on a Folder object /// </summary> public PlayableItem Create(Folder folder) { PlayableItem playable = Create(folder.RecursiveMedia); playable.Folder = folder; return(playable); }
public void PlayAndWait(PlayableItem playable) { Play(playable); while (PlayState != PlaybackControllerPlayState.Idle) { Thread.Sleep(500); } }
/// <summary> /// Creates a PlayableItem based on a list of files /// </summary> public PlayableItem Create(IEnumerable <string> paths) { PlayableItem playable = GetAllKnownPlayables().FirstOrDefault(p => p.CanPlay(paths)) ?? new PlayableInternal(); playable.Files = paths; return(playable); }
/// <summary> /// Gets arguments to be passed to the command line. /// </summary> protected override List<string> GetCommandArgumentsList(PlayableItem playbackInfo) { List<string> args = new List<string>(); args.Add("uri={0}"); return args; }
/// <summary> /// Creates a PlayableItem based on a list of Media objects /// </summary> public PlayableItem Create(IEnumerable <Media> mediaList) { PlayableItem playable = GetAllKnownPlayables().FirstOrDefault(p => p.CanPlay(mediaList)) ?? new PlayableInternal(); playable.MediaItems = mediaList; return(playable); }
/// <summary> /// Gets arguments to be passed to the command line. /// </summary> protected override List <string> GetCommandArgumentsList(PlayableItem playbackInfo) { List <string> args = new List <string>(); args.Add("{0}"); return(args); }
/// <summary> /// Creates a PlayableItem based on a Folder object /// </summary> public PlayableItem Create(Folder folder) { PlayableItem playable = Create(folder.RecursiveMedia); playable.Folder = folder; playable.GoFullScreen = playable.GoFullScreen || folder.ContainsMusic; return(playable); }
/// <summary> /// Creates a PlayableItem based on a list of Media objects /// </summary> public PlayableItem Create(IEnumerable <Media> mediaList) { PlayableItem playable = GetAllKnownPlayables().FirstOrDefault(p => p.CanPlay(mediaList)) ?? new PlayableInternal(); playable.MediaItems = mediaList; playable.GoFullScreen = playable.GoFullScreen || mediaList.Any(i => i is Song); return(playable); }
protected void OnErrorPlayingItem(PlayableItem playable, string error) { Logger.ReportVerbose("Error playing item: {0}", error); if (!playable.QueueItem) { CurrentPlayableItemId = Guid.Empty; } CurrentPlayableItems.Remove(playable); }
protected override void OnExternalPlayerLaunched(PlayableItem playbackInfo) { base.OnExternalPlayerLaunched(playbackInfo); // If the playstate directory exists, start watching it if (Directory.Exists(PlayStateDirectory)) { StartWatchingStatusFile(); } }
private string GetCommandArguments(PlayableItem playable) { List <string> argsList = GetCommandArgumentsList(playable); string args = string.Join(" ", argsList.ToArray()); args = string.Format(args, GetFilePathCommandArgument(GetFilesToSendToPlayer(playable))); return(args); }
protected void OnErrorPlayingItem(PlayableItem playable, Exception ex) { Logger.ReportException("Error playing item: ", ex); if (!playable.QueueItem) { CurrentPlayableItemId = Guid.Empty; } CurrentPlayableItems.Remove(playable); }
/// <summary> /// Plays Media /// </summary> protected override void PlayMediaInternal(PlayableItem playable) { if (playable.QueueItem) { Application.UIDeferredInvokeIfRequired(() => QueuePlayableItem(playable)); } else { Application.UIDeferredInvokeIfRequired(() => PlayPlayableItem(playable)); } }
/// <summary> /// Gets list of arguments to send to the player /// </summary> protected override List <string> GetCommandArgumentsList(PlayableItem playable) { List <string> args = new List <string>(); if (!string.IsNullOrEmpty(ExternalPlayerConfiguration.Args)) { args.Add(ExternalPlayerConfiguration.Args); } return(args); }
protected virtual void QueuePlayableItem(PlayableItem playable) { if (CurrentMediaCollection == null) { QueuePlayableItemLegacy(playable); } else { QueuePlayableItemIntoMediaCollection(playable); } }
/// <summary> /// Plays Media /// </summary> protected override void PlayMediaInternal(PlayableItem playable) { if (playable.QueueItem) { Microsoft.MediaCenter.UI.Application.DeferredInvoke(_ => QueuePlayableItem(playable)); } else { Microsoft.MediaCenter.UI.Application.DeferredInvoke(_ => PlayPlayableItem(playable)); } }
private void PlayTrack(string path, long startPositionTicks, bool isVideo, BaseItemDto item, MediaSourceInfo mediaSource, string forcedVideoRenderer) { var playableItem = new PlayableItem { MediaSource = mediaSource, PlayablePath = path, OriginalItem = item }; try { InvokeOnPlayerThread(() => { //create a fresh DS Player everytime we want one DisposePlayer(); _mediaPlayer = new DirectShowPlayer(this, _hostForm, _logger, GetConfiguration(), _httpClient); _mediaPlayer.Play(playableItem, forcedVideoRenderer); try { Standby.PreventSleepAndMonitorOff(); } catch { } }, true); } catch { OnPlaybackStopped(playableItem, null, TrackCompletionReason.Failure, null); throw; } if (startPositionTicks > 0) { InvokeOnPlayerThread(() => _mediaPlayer.Seek(startPositionTicks)); } if (playableItem.OriginalItem.IsVideo) { var audioIndex = playableItem.MediaSource.DefaultAudioStreamIndex; var subtitleIndex = playableItem.MediaSource.DefaultSubtitleStreamIndex; if (audioIndex.HasValue && audioIndex.Value != -1) { SetAudioStreamIndex(audioIndex.Value); } SetSubtitleStreamIndex(subtitleIndex ?? -1); } }
protected override void PlayMediaInternal(PlayableItem playable) { // Two different launch methods depending on how the player is configured if (LaunchType == ConfigData.ExternalPlayerLaunchType.WMCNavigate) { PlayUsingWMCNavigation(playable); OnExternalPlayerLaunched(playable); } else { PlayUsingCommandLine(playable); } }
/// <summary> /// Play by launching another WMC app /// </summary> protected void PlayUsingWMCNavigation(PlayableItem playable) { string commandArgs = GetCommandArguments(playable); string url = GetCommandPath(playable); if (!string.IsNullOrEmpty(commandArgs)) { url += "?" + commandArgs; } Logging.Logger.ReportInfo("Navigating within WMC to " + url); AddInHost.Current.MediaCenterEnvironment.NavigateToPage(Microsoft.MediaCenter.PageId.ExtensibilityUrl, url); }
// Launch the external player using the command line private void PlayUsingCommandLine(PlayableItem playable) { string commandPath = GetCommandPath(playable); string commandArgs = GetCommandArguments(playable); Logging.Logger.ReportInfo("Starting command line " + commandPath + " " + commandArgs); CurrentProcessName = Path.GetFileNameWithoutExtension(commandPath); KillProcesses(CurrentProcessName); CurrentProcess = Process.Start(commandPath, commandArgs); Async.Queue("Ext Player Mgmt", () => ManageExtPlayer(CurrentProcess, playable)); }
private void DisposeMount(PlayableItem media) { if (media.IsoMount != null) { try { media.IsoMount.Dispose(); media.IsoMount = null; } catch (Exception ex) { _logger.ErrorException("Error unmounting iso {0}", ex, media.IsoMount.MountedPath); } } }
protected override void PlayMediaInternal(PlayableItem playable) { // Report start to server if (playable.HasMediaItems) Application.CurrentInstance.ReportPlaybackStart(playable.CurrentMedia.ApiId); // Two different launch methods depending on how the player is configured if (LaunchType == CommonConfigData.ExternalPlayerLaunchType.WMCNavigate) { PlayUsingWMCNavigation(playable); OnExternalPlayerLaunched(playable); } else { PlayUsingCommandLine(playable); } }
/// <summary> /// Starts monitoring playstate using the player's Http interface /// </summary> protected override void OnExternalPlayerLaunched(PlayableItem playbackInfo) { base.OnExternalPlayerLaunched(playbackInfo); if (_StatusRequestClient == null) { _StatusRequestClient = new WebClient(); // Start up the thread that will perform the monitoring _StatusRequestThread = new Thread(MonitorStatus); _StatusRequestThread.IsBackground = true; _StatusRequestThread.Start(); } _StatusRequestClient.DownloadStringCompleted -= statusRequestCompleted; _StatusRequestClient.DownloadStringCompleted += statusRequestCompleted; _MonitorPlayback = true; }
protected override void PlayMediaInternal(PlayableItem playable) { // Report start to server var file = (playable.HasMediaItems ? playable.CurrentMedia.Files.FirstOrDefault() : playable.CurrentFile) ?? ""; IsStreaming = file.StartsWith("http://", StringComparison.OrdinalIgnoreCase); if (playable.HasMediaItems) Application.CurrentInstance.ReportPlaybackStart(playable.CurrentMedia.ApiId, IsStreaming); // Two different launch methods depending on how the player is configured if (LaunchType == CommonConfigData.ExternalPlayerLaunchType.WMCNavigate) { PlayUsingWMCNavigation(playable); OnExternalPlayerLaunched(playable); } else { PlayUsingCommandLine(playable); } }
private void ManageExtPlayer(Process player, PlayableItem playable) { //minimize MCE if indicated IntPtr mceWnd = FindWindow(null, "Windows Media Center"); WINDOWPLACEMENT wp = new WINDOWPLACEMENT(); GetWindowPlacement(mceWnd, ref wp); Cursor.Hide(); if (HideTaskbar) { Taskbar.Hide(); } if (ShowSplashScreen) { //throw up a form to cover the desktop if we minimize and we are in the primary monitor if (System.Windows.Forms.Screen.FromHandle(mceWnd).Primary) { ExternalSplashForm.Display(Application.CurrentInstance.ExtSplashBmp); } } if (MinimizeMCE) { Logger.ReportVerbose("Minimizing Windows Media Center"); wp.showCmd = 2; // 1 - Normal; 2 - Minimize; 3 - Maximize; SetWindowPlacement(mceWnd, ref wp); } // async this so it doesn't slow us down if the service isn't responding for some reason Async.Queue("Wait for external player to launch", () => { player.Refresh(); player.WaitForInputIdle(5000); OnExternalPlayerLaunched(playable); }); //and wait for it to exit player.WaitForExit(); player.Dispose(); //now restore MCE wp.showCmd = 1; // 1 - Normal; 2 - Minimize; 3 - Maximize; SetWindowPlacement(mceWnd, ref wp); if (ShowSplashScreen) { ExternalSplashForm.Hide(); } if (HideTaskbar) { Taskbar.Show(); } Cursor.Show(); SetForegroundWindow(mceWnd); OnPlaybackFinished(GetFinishedPlaybackState()); }
private IEnumerable<string> GetFilesToSendToPlayer(PlayableItem playable) { IEnumerable<string> files = playable.FilesFormattedForPlayer; if (playable.StartPlaylistPosition > 0) { files = files.Skip(playable.StartPlaylistPosition); } if (files.Count() > 1) { if (!SupportsMultiFileCommandArguments && SupportsPlaylists) { return new string[] { CreatePlaylistFile(files) }; } } return files; }
/// <summary> /// Gets arguments to be passed to the command line. /// </summary> protected override List<string> GetCommandArgumentsList(PlayableItem playbackInfo) { var args = new List<string> {"uri={0}"}; return args; }
private void QueuePlayableItemIntoMediaCollection(PlayableItem playable) { try { // Create a MediaCollectionItem for each file to play if (playable.HasMediaItems) { PlaybackControllerHelper.PopulateMediaCollectionUsingMediaItems(this, _CurrentMediaCollection, playable); } else { PlaybackControllerHelper.PopulateMediaCollectionUsingFiles(_CurrentMediaCollection, playable); } } catch (Exception ex) { OnErrorPlayingItem(playable, ex); } }
/// <summary> /// Calls PlayMedia /// </summary> private bool CallPlayMediaLegacy(MediaCenterEnvironment mediaCenterEnvironment, PlayableItem playable) { Microsoft.MediaCenter.MediaType type = PlaybackControllerHelper.GetMediaType(playable); bool playedWithPlaylist = false; // Need to create a playlist if (PlaybackControllerHelper.RequiresWPL(playable)) { IEnumerable<string> files = playable.FilesFormattedForPlayer; string playlistFile = PlaybackControllerHelper.CreateWPLPlaylist(playable.Id.ToString(), files, playable.StartPlaylistPosition); if (!PlaybackControllerHelper.CallPlayMedia(mediaCenterEnvironment, type, playlistFile, false)) { return false; } playedWithPlaylist = true; } // If we're playing a dvd and the last item played was a MediaCollection, we need to make sure the MediaCollection has // fully cleared out of the player or there will be quirks such as ff/rew remote buttons not working if (playable.HasMediaItems) { Video video = playable.MediaItems.First() as Video; Microsoft.MediaCenter.Extensibility.MediaType lastMediaType = PlaybackControllerHelper.GetCurrentMediaType(); if (video != null && video.MediaType == Library.MediaType.DVD && (lastMediaType == Microsoft.MediaCenter.Extensibility.MediaType.MediaCollection || lastMediaType == Microsoft.MediaCenter.Extensibility.MediaType.Unknown)) { System.Threading.Thread.Sleep(500); } } if (!playedWithPlaylist) { bool queue = false; foreach (string fileToPlay in playable.FilesFormattedForPlayer) { if (!PlaybackControllerHelper.CallPlayMedia(mediaCenterEnvironment, type, fileToPlay, queue)) { return false; } queue = true; } } return true; }
protected abstract string GetCommandPath(PlayableItem playable);
protected abstract List<string> GetCommandArgumentsList(PlayableItem playable);
/// <summary> /// Gets the path to the player's executable file /// </summary> protected override string GetCommandPath(PlayableItem playable) { return ExternalPlayerConfiguration.Command; }
/// <summary> /// Gets list of arguments to send to the player /// </summary> protected override List<string> GetCommandArgumentsList(PlayableItem playable) { List<string> args = new List<string>(); if (!string.IsNullOrEmpty(ExternalPlayerConfiguration.Args)) { args.Add(ExternalPlayerConfiguration.Args); } return args; }
internal async void OnPlaybackStopped(PlayableItem media, long? positionTicks, TrackCompletionReason reason, int? newTrackIndex) { DisposeMount(media); if (reason == TrackCompletionReason.Ended || reason == TrackCompletionReason.ChangeTrack) { var nextIndex = newTrackIndex ?? (CurrentPlaylistIndex + 1); if (nextIndex < CurrentPlayOptions.Items.Count) { await PlayTrack(nextIndex, null); return; } } DisposePlayer(); try { await _apiClient.StopTranscodingProcesses(_apiClient.DeviceId); } catch { } var args = new PlaybackStopEventArgs { Player = this, Playlist = _playlist, EndingMedia = media.OriginalItem, EndingPositionTicks = positionTicks }; EventHelper.FireEventIfNotNull(PlaybackCompleted, this, args, _logger); _playbackManager.ReportPlaybackCompleted(args); }
/// <summary> /// Calls PlayMedia using either a MediaCollection or a single file /// </summary> private bool CallPlayMediaForPlayableItem(MediaCenterEnvironment mediaCenterEnvironment, PlayableItem playable) { if (PlaybackControllerHelper.UseLegacyApi(playable)) { bool success = CallPlayMediaLegacy(mediaCenterEnvironment, playable); _CurrentMediaCollection = null; return success; } else { return CallPlayMediaUsingMediaCollection(mediaCenterEnvironment, playable); } }
/// <summary> /// Subclasses can use this to execute code after the player has launched /// </summary> protected virtual void OnExternalPlayerLaunched(PlayableItem playable) { }
private bool CallPlayMediaUsingMediaCollection(MediaCenterEnvironment mediaCenterEnvironment, PlayableItem playable) { MediaCollection coll = new MediaCollection(); // Create a MediaCollectionItem for each file to play if (playable.HasMediaItems) { PlaybackControllerHelper.PopulateMediaCollectionUsingMediaItems(this, coll, playable); } else { PlaybackControllerHelper.PopulateMediaCollectionUsingFiles(coll, playable); } // Set starting position if we're resuming if (playable.Resume) { var playstate = playable.MediaItems.First().PlaybackStatus; coll.CurrentIndex = playstate.PlaylistPosition; coll[playstate.PlaylistPosition].Start = new TimeSpan(playstate.PositionTicks); } _CurrentMediaCollection = coll; bool success = PlaybackControllerHelper.CallPlayMedia(mediaCenterEnvironment, MediaType.MediaCollection, _CurrentMediaCollection, false); if (!success) { _CurrentMediaCollection = null; } return success; }
protected virtual void QueuePlayableItem(PlayableItem playable) { if (_CurrentMediaCollection == null) { QueuePlayableItemLegacy(playable); } else { QueuePlayableItemIntoMediaCollection(playable); } }
private void QueuePlayableItemLegacy(PlayableItem playable) { Microsoft.MediaCenter.MediaType type = MediaType.Audio; bool success = true; foreach (string file in playable.FilesFormattedForPlayer) { if (!PlaybackControllerHelper.CallPlayMedia(AddInHost.Current.MediaCenterEnvironment, type, file, true)) { success = false; break; } } if (!success) { OnErrorPlayingItem(playable, "PlayMedia returned false"); } }
private string GetCommandArguments(PlayableItem playable) { List<string> argsList = GetCommandArgumentsList(playable); string args = string.Join(" ", argsList.ToArray()); args = string.Format(args, GetFilePathCommandArgument(GetFilesToSendToPlayer(playable))); return args; }
/// <summary> /// Plays or queues Media /// </summary> protected virtual void PlayPlayableItem(PlayableItem playable) { this.Playable = playable; _HasStartedPlaying = false; // Get this now since we'll be using it frequently MediaCenterEnvironment mediaCenterEnvironment = AddInHost.Current.MediaCenterEnvironment; try { // Attach event handler to MediaCenterEnvironment // We need this because if you press stop on a dvd menu without ever playing, Transport.PropertyChanged will never fire mediaCenterEnvironment.PropertyChanged -= MediaCenterEnvironment_PropertyChanged; mediaCenterEnvironment.PropertyChanged += MediaCenterEnvironment_PropertyChanged; if (!CallPlayMediaForPlayableItem(mediaCenterEnvironment, playable)) { mediaCenterEnvironment.PropertyChanged -= MediaCenterEnvironment_PropertyChanged; OnErrorPlayingItem(playable, "PlayMedia returned false"); return; } MediaExperience exp = mediaCenterEnvironment.MediaExperience ?? PlaybackControllerHelper.GetMediaExperienceUsingReflection(); if (exp != null) { MediaTransport transport = exp.Transport; if (transport != null) { transport.PropertyChanged -= MediaTransport_PropertyChanged; transport.PropertyChanged += MediaTransport_PropertyChanged; // If using the legacy api we have to resume manually if (_CurrentMediaCollection == null) { long startPosition = playable.StartPositionTicks; if (startPosition > 0) { TimeSpan startPos = TimeSpan.FromTicks(startPosition); Logger.ReportVerbose("Seeking to " + startPos.ToString()); transport.Position = startPos; } } } else { Logger.ReportWarning("PlayPlayableItem: MediaTransport is null"); } if (playable.GoFullScreen) { Logger.ReportVerbose("Going fullscreen"); exp.GoToFullScreen(); } } else { Logger.ReportWarning("PlayPlayableItem: MediaExperience is null"); } } catch (Exception ex) { OnErrorPlayingItem(playable, ex); } }
protected override void OnExternalPlayerLaunched(PlayableItem playbackInfo) { base.OnExternalPlayerLaunched(playbackInfo); Async.Queue("Wait for process to exit", WaitForProcessToExit); }