public void Play(PlayableItem item, string forcedVideoRenderer)
        {
            try
            {
                _logger.Info("Playing {0}. Audio Renderer: {1}, Madvr: {2}, xySubFilter: {3}, ParentID: {4}", item.OriginalItem.Name,
                    _config.AudioConfig.Renderer, _config.VideoConfig.EnableMadvr,
                    _config.SubtitleConfig.EnableXySubFilter,
                    item.OriginalItem.ParentId);
                _logger.Info("Playing Path {0}", item.PlayablePath);

                var mediaSource = item.MediaSource;

                _item = item;
                _isInExclusiveMode = false;
                TimeSpan itemDuration = TimeSpan.MaxValue;

                if (mediaSource.RunTimeTicks.HasValue && mediaSource.RunTimeTicks.Value > 0)
                    itemDuration = TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value);

                _iVideoScaling = (VideoScalingScheme)_config.VideoConfig.ScalingMode;

                if (item.IsVideo
                    && IsFullScreen
                    && !string.IsNullOrWhiteSpace(item.OriginalItem.ParentId)
                    && _config.VideoConfig.AutoChangeRefreshRate
                    && _config.VideoConfig.MinRefreshRateMin < itemDuration.TotalMinutes
                    )
                {
                    if (item.MediaStreams == null)
                    {
                        _logger.Warn("item.MediaStreams is null, cannot detect framerate");
                    }
                    else
                    {
                        //find the video stream (assume that the first one is the main one)
                        foreach (var ms in item.MediaStreams)
                        {
                            if (ms.Type == MediaStreamType.Video)
                            {
                                _startResolution = Display.GetCurrentResolution();
                                if (ms.RealFrameRate.HasValue && !ms.IsInterlaced)
                                {
                                    int videoRate = (int)ms.RealFrameRate;

                                    if (videoRate == 25 || videoRate == 29 || videoRate == 30)
                                    {
                                        //Every display/GPU should be able to display @2x FPS and it's quite likely that 2x is the rendered FPS anyway
                                        videoRate = (int)(ms.RealFrameRate * 2);
                                    }

                                    _logger.Info("RealFrameRate: {0} videoRate: {1} startRate: {2}", ms.RealFrameRate, videoRate, _startResolution);

                                    if (videoRate != _startResolution.Rate)
                                    {
                                        Resolution desiredRes = new Resolution(_startResolution.ToString());
                                        desiredRes.Rate = videoRate;
                                        if (Display.ChangeResolution(desiredRes, false))
                                            _logger.Info("Changed resolution from {0} to {1}", _startResolution, desiredRes);
                                        else
                                        {
                                            _logger.Info("Couldn't change resolution from {0} to {1}", _startResolution, desiredRes);
                                            _startResolution = null;
                                        }
                                    }
                                    else
                                        _startResolution = null;

                                    break;
                                }
                            }
                            else
                                _startResolution = null;
                        }
                    }
                }

                var isDvd = ((item.MediaSource.VideoType ?? VideoType.VideoFile) == VideoType.Dvd ||
                             (item.MediaSource.IsoType ?? IsoType.BluRay) == IsoType.Dvd);

                Initialize(item.PlayablePath, _isDvd, forcedVideoRenderer);

                //_hiddenWindow.OnWMGRAPHNOTIFY = HandleGraphEvent;
                //_hiddenWindow.OnDVDEVENT = HandleDvdEvent;

                //pre-roll the graph
                _logger.Debug("pre-roll the graph");
                var hr = _mediaControl.Pause();
                DsError.ThrowExceptionForHR(hr);

                _logger.Debug("run the graph");
                hr = _mediaControl.Run();
                DsError.ThrowExceptionForHR(hr);

                PlayState = PlayState.Playing;
                _currentPlaybackRate = 1.0;

                _streams = GetStreams();

                _logger.Debug("DSPlayer Done in play");
            }
            catch (Exception ex)
            {
                CloseInterfaces();
                throw ex;
            }
        }
 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);
         }
     }
 }
        internal async void OnPlaybackStopped(PlayableItem media, long? positionTicks, TrackCompletionReason reason, int? newTrackIndex)
        {
            DisposeMount(media);

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

                }, 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);
            }
        }