Example #1
0
        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);
                    }
                }
            }
        }
Example #5
0
        internal async void OnPlaybackStopped(PlayableItem media, long?positionTicks, TrackCompletionReason reason, int?newTrackIndex)
        {
            DisposeMount(media);

            // TODO
            // Notify
        }
Example #6
0
        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;
        }
Example #11
0
        /// <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);
        }
Example #13
0
 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);
        }
Example #17
0
        /// <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);
        }
Example #21
0
        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 override void OnExternalPlayerLaunched(PlayableItem playbackInfo)
        {
            base.OnExternalPlayerLaunched(playbackInfo);

            // If the playstate directory exists, start watching it
            if (Directory.Exists(PlayStateDirectory))
            {
                StartWatchingStatusFile();
            }
        }
        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));
     }
 }
Example #26
0
        /// <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);
        }
Example #27
0
 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));
     }
 }
Example #29
0
 /// <summary>
 /// Plays Media
 /// </summary>
 protected override void PlayMediaInternal(PlayableItem playable)
 {
     if (playable.QueueItem)
     {
         Application.UIDeferredInvokeIfRequired(() => QueuePlayableItem(playable));
     }
     else
     {
         Application.UIDeferredInvokeIfRequired(() => PlayPlayableItem(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));
     }
 }
Example #31
0
        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);
            }
        }
Example #32
0
        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));
        }
Example #35
0
 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);
            }

        }
        // 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 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);
        }
 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);
         }
     }
 }
 /// <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 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);
            }
        }
 protected virtual void QueuePlayableItem(PlayableItem playable)
 {
     if (_CurrentMediaCollection == null)
     {
         QueuePlayableItemLegacy(playable);
     }
     else
     {
         QueuePlayableItemIntoMediaCollection(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);
        }
        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);
        }