/// <summary> /// This method handles two cases: /// <list type="bullet"> /// <item>No player available to play the resource</item> /// <item>The resouce to play is broken</item> /// </list> /// </summary> /// <param name="item"></param> /// <param name="exceptions"></param> protected void HandleUnableToPlay(MediaItem item, ICollection <Exception> exceptions) { INotificationService notificationService = ServiceRegistration.Get <INotificationService>(); // Start a heuristics to find a proper error message for the user IResourceLocator locator = item.GetResourceLocator(); if (locator == null) { ServiceRegistration.Get <ILogger>().Warn("PlayerSlotController: Could not play media item '{0}', resource locator could not be built", item); return; } if (exceptions.Count != 0) // This is the indicator that at least one player builder tried to open the resource but threw an exception { // 1) Check if resource is present IResourceAccessor ra = null; try { bool exists; try { ra = locator.CreateAccessor(); IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; exists = fsra != null && fsra.Exists; } catch (Exception) { exists = false; } notificationService.EnqueueNotification( NotificationType.UserInteractionRequired, RES_ERROR_PLAYING_MEDIA_ITEM_TITLE, exists ? LocalizationHelper.Translate(RES_UNABLE_TO_PLAY_MEDIA_ITEM_TEXT, ra.ResourceName) : LocalizationHelper.Translate(RES_RESOURCE_NOT_FOUND_TEXT, locator.NativeResourcePath.FileName), true); } finally { if (ra != null) { ra.Dispose(); } } } else { using (IResourceAccessor ra = locator.CreateAccessor()) notificationService.EnqueueNotification(NotificationType.UserInteractionRequired, RES_NO_PLAYER_AVAILABLE_NOTIFICATION_TITLE, LocalizationHelper.Translate(RES_NO_PLAYER_AVAILABLE_NOTIFICATION_TEXT, ra.ResourceName), true); } }
private void ExtractLocalImages(IDictionary <Guid, IList <MediaItemAspect> > aspects, Guid?albumMediaItemId, IDictionary <Guid, string> artistMediaItems, string albumTitle) { if (BaseInfo.IsVirtualResource(aspects)) { return; } IResourceLocator mediaItemLocater = GetResourceLocator(aspects); if (mediaItemLocater == null) { return; } ExtractFolderImages(mediaItemLocater, albumMediaItemId, artistMediaItems, albumTitle); using (IResourceAccessor mediaItemAccessor = mediaItemLocater.CreateAccessor()) { using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor)) { using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess()) { ExtractFileImages(rah.LocalFsResourceAccessor, albumMediaItemId, albumTitle); } } } }
private void ExtractLocalImages(IDictionary <Guid, IList <MediaItemAspect> > aspects, Guid?movieMediaItemId, Guid?collectionMediaItemId, string movieName, string collectionName, IDictionary <Guid, string> actorMediaItems) { if (BaseInfo.IsVirtualResource(aspects)) { return; } IResourceLocator mediaItemLocater = GetResourceLocator(aspects); if (mediaItemLocater == null) { return; } ExtractFolderImages(mediaItemLocater, movieMediaItemId, collectionMediaItemId, movieName, collectionName, actorMediaItems); using (IResourceAccessor mediaItemAccessor = mediaItemLocater.CreateAccessor()) { using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor)) { using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess()) { ExtractMkvImages(rah.LocalFsResourceAccessor, movieMediaItemId, movieName); } } } }
/// <summary> /// Creates an <see cref="IInputSource"/> object for a given mediaitem. /// </summary> /// <param name="resourceLocator">Locator instance to the media item to create the input source for.</param> /// <param name="mimeType">Mime type of the media item, if present. May be <c>null</c>.</param> /// <returns>Input source object for the given <paramref name="resourceLocator"/> or <c>null</c>, if no input source /// could be created.</returns> public IInputSource CreateInputSource(IResourceLocator resourceLocator, string mimeType) { if (!CanPlay(resourceLocator, mimeType)) return null; IResourceAccessor accessor = resourceLocator.CreateAccessor(); IInputSource result; AudioCDResourceAccessor acdra = accessor as AudioCDResourceAccessor; if (acdra != null) result = BassCDTrackInputSource.Create(acdra.Drive, acdra.TrackNo); else { string filePath = accessor.ResourcePathName; if (URLUtils.IsCDDA(filePath)) { ILocalFsResourceAccessor lfra = accessor as ILocalFsResourceAccessor; if (lfra == null) return null; result = BassFsCDTrackInputSource.Create(lfra.LocalFileSystemPath); } else if (URLUtils.IsMODFile(filePath)) result = BassMODFileInputSource.Create(accessor); else result = BassAudioFileInputSource.Create(accessor); // TODO: Handle web streams when we have resource accessors for web URLs: BassWebStreamInputSource.Create(...); } accessor.PrepareStreamAccess(); Log.Debug("InputSourceFactory: Creating input source for media resource '{0}' of type '{1}'", accessor, result.GetType()); return result; }
private void ExtractLocalImages(IDictionary <Guid, IList <MediaItemAspect> > aspects, Guid?episodeMediaItemId, Guid?seriesMediaItemId, Guid?seasonMediaItemId, EpisodeInfo episode, SeriesInfo series, SeasonInfo season, IDictionary <Guid, string> actorMediaItems) { if (BaseInfo.IsVirtualResource(aspects)) { return; } IResourceLocator mediaItemLocater = GetResourceLocator(aspects); if (mediaItemLocater == null) { return; } ExtractFolderImages(mediaItemLocater, episodeMediaItemId, seriesMediaItemId, seasonMediaItemId, episode, series, season, actorMediaItems); using (IResourceAccessor mediaItemAccessor = mediaItemLocater.CreateAccessor()) { using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor)) { using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess()) { ExtractMkvImages(rah.LocalFsResourceAccessor, seriesMediaItemId, series); } } } }
public void SetMediaItem(IResourceLocator locator, string mediaItemTitle) { // free previous opened resource FilterGraphTools.TryDispose(ref _resourceAccessor); FilterGraphTools.TryDispose(ref _rot); _state = PlayerState.Active; _isPaused = true; try { _resourceLocator = locator; _mediaItemTitle = mediaItemTitle; _resourceAccessor = _resourceLocator.CreateAccessor(); // Create a DirectShow FilterGraph CreateGraphBuilder(); // Add it in ROT (Running Object Table) for debug purpose, it allows to view the Graph from outside (i.e. graphedit) _rot = new DsROTEntry(_graphBuilder); // Add a notification handler (see WndProc) _instancePtr = Marshal.AllocCoTaskMem(4); IMediaEventEx mee = _graphBuilder as IMediaEventEx; if (mee != null) { mee.SetNotifyWindow(SkinContext.Form.Handle, WM_GRAPHNOTIFY, _instancePtr); } // Create the Allocator / Presenter object AddPresenter(); ServiceRegistration.Get <ILogger>().Debug("{0}: Adding audio renderer", PlayerTitle); AddAudioRenderer(); ServiceRegistration.Get <ILogger>().Debug("{0}: Adding preferred codecs", PlayerTitle); AddPreferredCodecs(); ServiceRegistration.Get <ILogger>().Debug("{0}: Adding source filter", PlayerTitle); AddSourceFilter(); ServiceRegistration.Get <ILogger>().Debug("{0}: Run graph", PlayerTitle); //This needs to be done here before we check if the evr pins are connected //since this method gives players the chance to render the last bits of the graph OnBeforeGraphRunning(); // Now run the graph, i.e. the DVD player needs a running graph before getting informations from dvd filter. IMediaControl mc = (IMediaControl)_graphBuilder; int hr = mc.Run(); new HRESULT(hr).Throw(); _initialized = true; OnGraphRunning(); } catch (Exception) { Shutdown(); throw; } }
/// <summary> /// Sets the data of the new image to be played. /// </summary> /// <param name="locator">Resource locator of the image item.</param> /// <param name="mediaItemTitle">Title of the image item.</param> /// <param name="rotation">Rotation of the image.</param> /// <param name="flipX">Flipping in horizontal direction.</param> /// <param name="flipY">Flipping in vertical direction.</param> public void SetMediaItemData(IResourceLocator locator, string mediaItemTitle, RightAngledRotation rotation, bool flipX, bool flipY) { if (locator == null) { lock (_syncObj) { DisposeTexture(); _currentLocator = null; return; } } Texture texture; ImageInformation imageInformation; using (IResourceAccessor ra = locator.CreateAccessor()) { IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { return; } using (Stream stream = fsra.OpenRead()) using (Stream tmpImageStream = ImageUtilities.ResizeImage(stream, ImageFormat.MemoryBmp, MAX_TEXTURE_DIMENSION, MAX_TEXTURE_DIMENSION)) texture = Texture.FromStream(SkinContext.Device, tmpImageStream, (int)tmpImageStream.Length, 0, 0, 1, Usage.None, Format.A8R8G8B8, Pool.Default, Filter.None, Filter.None, 0, out imageInformation); } lock (_syncObj) { ReloadSettings(); _state = PlayerState.Active; DisposeTexture(); _currentLocator = locator; _mediaItemTitle = mediaItemTitle; _texture = texture; _rotation = rotation; _flipX = flipX; _flipY = flipY; SurfaceDescription desc = _texture.GetLevelDescription(0); _textureMaxUV = new SizeF(imageInformation.Width / (float)desc.Width, imageInformation.Height / (float)desc.Height); // Reset animation _animator.Initialize(); if (_slideShowTimer != null) { _slideShowTimer.Change(_slideShowImageDuration, TS_INFINITE); } else { CheckTimer(); } _playbackStartTime = DateTime.Now; if (_pauseTime.HasValue) { _pauseTime = _playbackStartTime; } } }
/// <summary> /// Reads all tag images and caches them in the <see cref="IFanArtCache"/> service. /// </summary> /// <param name="mediaItemLocator"><see cref="IResourceLocator>"/> that points to the file.</param> /// <param name="mediaItemId">Id of the media item.</param> /// <param name="title">Title of the media item.</param> /// <returns><see cref="Task"/> that completes when the images have been cached.</returns> protected async Task ExtractFanArt(IResourceLocator mediaItemLocator, Guid mediaItemId, string title, IDictionary <Guid, IList <MediaItemAspect> > aspects) { try { //File based access using (IResourceAccessor mediaItemAccessor = mediaItemLocator.CreateAccessor()) using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor)) using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess()) { if (MKV_EXTENSIONS.Contains(ResourcePathHelper.GetExtension(mediaItemLocator.NativeResourcePath.FileName))) { await ExtractMkvFanArt(rah.LocalFsResourceAccessor, mediaItemId, title).ConfigureAwait(false); } if (MP4_EXTENSIONS.Contains(ResourcePathHelper.GetExtension(mediaItemLocator.NativeResourcePath.FileName))) { await ExtractTagFanArt(rah.LocalFsResourceAccessor, mediaItemId, title).ConfigureAwait(false); } //Don't create thumbs if they already exist or if it is a movie (they use posters) var thumbs = ServiceRegistration.Get <IFanArtCache>().GetFanArtFiles(mediaItemId, FanArtTypes.Thumbnail); if (!thumbs.Any() && !aspects.ContainsKey(ThumbnailLargeAspect.ASPECT_ID) && !aspects.ContainsKey(MovieAspect.ASPECT_ID)) { await ExtractThumbnailFanArt(rah.LocalFsResourceAccessor, mediaItemId, title, aspects); } } } catch (Exception ex) { Logger.Warn("VideoFanArtHandler: Exception while reading MKV tag images for '{0}'", ex, mediaItemLocator.NativeResourcePath); } }
/// <summary> /// Creates an <see cref="IInputSource"/> object for a given mediaitem. /// </summary> /// <param name="resourceLocator">Locator instance to the media item to create the input source for.</param> /// <param name="mimeType">Mime type of the media item, if present. May be <c>null</c>.</param> /// <returns>Input source object for the given <paramref name="resourceLocator"/> or <c>null</c>, if no input source /// could be created.</returns> public IInputSource CreateInputSource(IResourceLocator resourceLocator, string mimeType) { if (!CanPlay(resourceLocator, mimeType)) { return(null); } IInputSource result; _accessor = resourceLocator.CreateAccessor(); AudioCDResourceAccessor acdra = _accessor as AudioCDResourceAccessor; if (acdra != null) { result = BassCDTrackInputSource.Create(acdra.Drive, acdra.TrackNo); } else { string filePath = _accessor.ResourcePathName; // Network streams INetworkResourceAccessor netra = _accessor as INetworkResourceAccessor; if (netra != null) { result = BassWebStreamInputSource.Create(netra.URL); } // CDDA else if (URLUtils.IsCDDA(filePath)) { ILocalFsResourceAccessor lfra = _accessor as ILocalFsResourceAccessor; if (lfra == null) { return(null); } using (lfra.EnsureLocalFileSystemAccess()) result = BassFsCDTrackInputSource.Create(lfra.LocalFileSystemPath); } else { // Filesystem resources IFileSystemResourceAccessor fsra = _accessor as IFileSystemResourceAccessor; if (fsra == null) { return(null); } if (URLUtils.IsMODFile(filePath)) { result = BassMODFileInputSource.Create(fsra); } else { result = BassAudioFileInputSource.Create(fsra); } } } Log.Debug("InputSourceFactory: Creating input source for media resource '{0}' of type '{1}'", _accessor, result.GetType()); return(result); }
/// <summary> /// Loads an ImageSource and allows control of thumbnail use. /// Morpheus_xx, 2011-12-13: For fallback sources no thumbnails should be used, because ALL thumbs are created as JPG. This currenly causes an issue: /// Source -> no thumbnail created -> FallbackSource (PNG) -> creates a JPG thumbnail, so Alpha-Channel of FallbackSource is lost. /// TODO: Image class and thumbnail handling should be refactored to allow more control about image formats and thumbs usage. /// </summary> /// <param name="source">Source</param> /// <param name="allowThumbs">True to allow building a thumbnail of given source</param> /// <returns>ImageSource or null</returns> protected ImageSource LoadImageSource(object source, bool allowThumbs) { ImageSource result; bool thumbnail = allowThumbs && Thumbnail; _invalidateImageSourceOnResize = false; if (source is MediaItem) { result = MediaItemsHelper.CreateThumbnailImageSource((MediaItem)source, (int)Math.Max(Width, Height)); _invalidateImageSourceOnResize = true; } else if (source is IResourceLocator) { IResourceLocator resourceLocator = (IResourceLocator)source; result = new ResourceAccessorTextureImageSource(resourceLocator.CreateAccessor(), RightAngledRotation.Zero); } else { result = source as ImageSource; } if (result == null) { string uriSource = source as string; if (!string.IsNullOrEmpty(uriSource)) { // Remember to adapt list of supported extensions for image player plugin... if (IsValidSource(uriSource)) { BitmapImageSource bmi = new BitmapImageSource { UriSource = uriSource, Thumbnail = thumbnail }; if (thumbnail) { // Set the requested thumbnail dimension, to use the best matching format. bmi.ThumbnailDimension = (int)Math.Max(Width, Height); } result = bmi; } // TODO: More image types else { if (_formerWarnURI != uriSource) { ServiceRegistration.Get <ILogger>().Warn("Image: Image source '{0}' is not supported", uriSource); // Remember if we already wrote a warning to the log to avoid log flooding _formerWarnURI = uriSource; } } } } return(result); }
/// <summary> /// Creates an <see cref="IInputSource"/> object for a given mediaitem. /// </summary> /// <param name="resourceLocator">Locator instance to the media item to create the input source for.</param> /// <param name="mimeType">Mime type of the media item, if present. May be <c>null</c>.</param> /// <returns>Input source object for the given <paramref name="resourceLocator"/> or <c>null</c>, if no input source /// could be created.</returns> public IInputSource CreateInputSource(IResourceLocator resourceLocator, string mimeType) { if (!CanPlay(resourceLocator, mimeType)) { return(null); } IInputSource result; using (IResourceAccessor accessor = resourceLocator.CreateAccessor()) { AudioCDResourceAccessor acdra = accessor as AudioCDResourceAccessor; if (acdra != null) { result = BassCDTrackInputSource.Create(acdra.Drive, acdra.TrackNo); } else { string filePath = accessor.ResourcePathName; if (URLUtils.IsCDDA(filePath)) { ILocalFsResourceAccessor lfra = accessor as ILocalFsResourceAccessor; if (lfra == null) { return(null); } result = BassFsCDTrackInputSource.Create(lfra.LocalFileSystemPath); } else { IFileSystemResourceAccessor fsra = accessor as ILocalFsResourceAccessor; if (fsra == null) { return(null); } if (URLUtils.IsMODFile(filePath)) { result = BassMODFileInputSource.Create(fsra); } else { result = BassAudioFileInputSource.Create(fsra); } } // TODO: Handle web streams when we have resource accessors for web URLs: BassWebStreamInputSource.Create(...); } Log.Debug("InputSourceFactory: Creating input source for media resource '{0}' of type '{1}'", accessor, result.GetType()); } return(result); }
/// <summary> /// Reads all tag images and caches them in the <see cref="IFanArtCache"/> service. /// </summary> /// <param name="mediaItemLocator"><see cref="IResourceLocator>"/> that points to the file.</param> /// <param name="mediaItemId">Id of the media item.</param> /// <param name="title">Title of the media item.</param> /// <returns><see cref="Task"/> that completes when the images have been cached.</returns> protected async Task ExtractTagFanArt(IResourceLocator mediaItemLocator, Guid mediaItemId, string title) { try { //File based access using (IResourceAccessor mediaItemAccessor = mediaItemLocator.CreateAccessor()) using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor)) using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess()) await ExtractTagFanArt(rah.LocalFsResourceAccessor, mediaItemId, title).ConfigureAwait(false); } catch (Exception ex) { Logger.Warn("AudioFanArtHandler: Exception while reading MKV tag images for '{0}'", ex, mediaItemLocator.NativeResourcePath); } }
public static bool CanPlay(IResourceLocator locator, string mimeType) { // First check the mime type if (!string.IsNullOrEmpty(mimeType) && !mimeType.StartsWith("image")) { return(false); } IResourceAccessor accessor = locator.CreateAccessor(); string ext = StringUtils.TrimToEmpty(DosPathHelper.GetExtension(accessor.ResourcePathName)).ToLowerInvariant(); ImagePlayerSettings settings = ServiceRegistration.Get <ISettingsManager>().Load <ImagePlayerSettings>(); return(settings.SupportedExtensions.IndexOf(ext) > -1); }
/// <summary> /// Creates an <see cref="IInputSource"/> object for a given mediaitem. /// </summary> /// <param name="resourceLocator">Locator instance to the media item to create the input source for.</param> /// <param name="mimeType">Mime type of the media item, if present. May be <c>null</c>.</param> /// <returns>Input source object for the given <paramref name="resourceLocator"/> or <c>null</c>, if no input source /// could be created.</returns> public IInputSource CreateInputSource(IResourceLocator resourceLocator, string mimeType) { if (!CanPlay(resourceLocator, mimeType)) return null; IInputSource result; _accessor = resourceLocator.CreateAccessor(); AudioCDResourceAccessor acdra = _accessor as AudioCDResourceAccessor; if (acdra != null) result = BassCDTrackInputSource.Create(acdra.Drive, acdra.TrackNo); else { string filePath = _accessor.ResourcePathName; // Network streams INetworkResourceAccessor netra = _accessor as INetworkResourceAccessor; if (netra != null) { result = BassWebStreamInputSource.Create(netra.URL); } // CDDA else if (URLUtils.IsCDDA(filePath)) { ILocalFsResourceAccessor lfra = _accessor as ILocalFsResourceAccessor; if (lfra == null) return null; using (lfra.EnsureLocalFileSystemAccess()) result = BassFsCDTrackInputSource.Create(lfra.LocalFileSystemPath); } else { // Filesystem resources IFileSystemResourceAccessor fsra = _accessor as IFileSystemResourceAccessor; if (fsra == null) return null; if (URLUtils.IsMODFile(filePath)) result = BassMODFileInputSource.Create(fsra); else result = BassAudioFileInputSource.Create(fsra); } } Log.Debug("InputSourceFactory: Creating input source for media resource '{0}' of type '{1}'", _accessor, result.GetType()); return result; }
public static bool CanPlay(IResourceLocator locator, string mimeType) { // First check the Mime Type if (!string.IsNullOrEmpty(mimeType) && !mimeType.StartsWith("audio")) { return(false); } using (IResourceAccessor accessor = locator.CreateAccessor()) { if (accessor is AudioCDResourceAccessor || accessor is INetworkResourceAccessor) { return(true); } string ext = DosPathHelper.GetExtension(accessor.ResourcePathName).ToLowerInvariant(); BassPlayerSettings settings = ServiceRegistration.Get <ISettingsManager>().Load <BassPlayerSettings>(); return(settings.SupportedExtensions.IndexOf(ext) > -1); } }
/// <summary> /// Loads an image from filesystem an returns a new <see cref="FanArtImage"/>. /// </summary> /// <param name="resourceLocator">Resource to load</param> /// <param name="maxWidth">Maximum width for image. <c>0</c> returns image in original size.</param> /// <param name="maxHeight">Maximum height for image. <c>0</c> returns image in original size.</param> /// <param name="mediaType">MediaType</param> /// <param name="fanArtType">FanArtType</param> /// <param name="fanArtName">Fanart name</param> /// <returns>FanArtImage or <c>null</c>.</returns> public static FanArtImage FromResource(IResourceLocator resourceLocator, int maxWidth, int maxHeight, FanArtConstants.FanArtMediaType mediaType, FanArtConstants.FanArtType fanArtType, string fanArtName) { try { using (var ra = resourceLocator.CreateAccessor()) { ILocalFsResourceAccessor fsra = ra as ILocalFsResourceAccessor; if (fsra != null) { fsra.PrepareStreamAccess(); using (var fileStream = fsra.OpenRead()) return(FromStream(fileStream, maxWidth, maxHeight, mediaType, fanArtType, fanArtName, fsra.LocalFileSystemPath)); } } } catch { } return(null); }
/// <summary> /// Loads an image from filesystem an returns a new <see cref="FanArtImage"/>. /// </summary> /// <param name="resourceLocator">Resource to load</param> /// <param name="maxWidth">Maximum width for image. <c>0</c> returns image in original size.</param> /// <param name="maxHeight">Maximum height for image. <c>0</c> returns image in original size.</param> /// <param name="mediaType">MediaType</param> /// <param name="fanArtType">FanArtType</param> /// <param name="fanArtName">Fanart name</param> /// <returns>FanArtImage or <c>null</c>.</returns> public static FanArtImage FromResource(IResourceLocator resourceLocator, int maxWidth, int maxHeight) { try { using (var ra = resourceLocator.CreateAccessor()) { ILocalFsResourceAccessor fsra = ra as ILocalFsResourceAccessor; if (fsra != null) { fsra.PrepareStreamAccess(); using (var fileStream = fsra.OpenRead()) // Calling EnsureLocalFileSystemAccess not necessary; only string operation return(FromStream(fileStream, maxWidth, maxHeight, fsra.LocalFileSystemPath)); } } } catch { } return(null); }
public static ImageSource ResourceLocatorSource(object source, int width, int height) { IResourceLocator locator = source as IResourceLocator; if (locator == null) { return(null); } IResourceLocator resourceLocator = locator; IResourceAccessor ra = resourceLocator.CreateAccessor(); IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { ra.Dispose(); } else { return(new ResourceAccessorTextureImageSource(fsra, RightAngledRotation.Zero)); } return(null); }
/// <summary> /// Reads all tag images and caches them in the <see cref="IFanArtCache"/> service. /// </summary> /// <param name="mediaItemLocator"><see cref="IResourceLocator>"/> that points to the file.</param> /// <param name="mediaItemId">Id of the media item.</param> /// <param name="title">Title of the media item.</param> /// <returns><see cref="Task"/> that completes when the images have been cached.</returns> protected async Task ExtractFanArt(IResourceLocator mediaItemLocator, Guid mediaItemId, string title) { try { //File based access using (IResourceAccessor mediaItemAccessor = mediaItemLocator.CreateAccessor()) using (LocalFsResourceAccessorHelper rah = new LocalFsResourceAccessorHelper(mediaItemAccessor)) using (rah.LocalFsResourceAccessor.EnsureLocalFileSystemAccess()) { if (MKV_EXTENSIONS.Contains(ResourcePathHelper.GetExtension(mediaItemLocator.NativeResourcePath.FileName))) { await ExtractMkvFanArt(rah.LocalFsResourceAccessor, mediaItemId, title).ConfigureAwait(false); } if (MP4_EXTENSIONS.Contains(ResourcePathHelper.GetExtension(mediaItemLocator.NativeResourcePath.FileName))) { await ExtractTagFanArt(rah.LocalFsResourceAccessor, mediaItemId, title).ConfigureAwait(false); } } } catch (Exception ex) { Logger.Warn("VideoFanArtHandler: Exception while reading MKV tag images for '{0}'", ex, mediaItemLocator.NativeResourcePath); } }
/// <summary> /// Sets the data of the new image to be played. /// </summary> /// <param name="locator">Resource locator of the image item.</param> /// <param name="mediaItemTitle">Title of the image item.</param> /// <param name="rotation">Rotation of the image.</param> /// <param name="flipX">Flipping in horizontal direction.</param> /// <param name="flipY">Flipping in vertical direction.</param> public void SetMediaItemData(IResourceLocator locator, string mediaItemTitle, RightAngledRotation rotation, bool flipX, bool flipY) { if (locator == null) { lock (_syncObj) { _currentLocator = null; return; } } using (IResourceAccessor ra = locator.CreateAccessor()) { IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { return; } using (Stream stream = fsra.OpenRead()) { string key = fsra.CanonicalLocalResourcePath.Serialize(); _texture = ContentManager.Instance.GetTexture(stream, key, true); if (_texture == null) { return; } if (!_texture.IsAllocated) { _texture.Allocate(); } if (!_texture.IsAllocated) { return; } } } lock (_syncObj) { ReloadSettings(); _state = PlayerState.Active; _currentLocator = locator; _mediaItemTitle = mediaItemTitle; _rotation = rotation; _flipX = flipX; _flipY = flipY; SurfaceDescription desc = _texture.Texture.GetLevelDescription(0); _textureMaxUV = new SizeF(_texture.Width / (float)desc.Width, _texture.Height / (float)desc.Height); // Reset animation _animator.Initialize(); if (_slideShowTimer != null) { _slideShowTimer.Change(_slideShowImageDuration, TS_INFINITE); } else { CheckTimer(); } _playbackStartTime = DateTime.Now; if (_pauseTime.HasValue) { _pauseTime = _playbackStartTime; } } }
/// <summary> /// Sets the data of the new image to be played. /// </summary> /// <param name="locator">Resource locator of the image item.</param> /// <param name="mediaItemTitle">Title of the image item.</param> /// <param name="rotation">Rotation of the image.</param> /// <param name="flipX">Flipping in horizontal direction.</param> /// <param name="flipY">Flipping in vertical direction.</param> public void SetMediaItemData(IResourceLocator locator, string mediaItemTitle, RightAngledRotation rotation, bool flipX, bool flipY) { if (locator == null) lock (_syncObj) { DisposeTexture(); _currentLocator = null; return; } Texture texture; ImageInformation imageInformation; using (IResourceAccessor ra = locator.CreateAccessor()) using (Stream stream = ra.OpenRead()) texture = Texture.FromStream(SkinContext.Device, stream, (int) stream.Length, 0, 0, 1, Usage.None, Format.A8R8G8B8, Pool.Default, Filter.None, Filter.None, 0, out imageInformation); lock (_syncObj) { ReloadSettings(); _state = PlayerState.Active; DisposeTexture(); _currentLocator = locator; _mediaItemTitle = mediaItemTitle; _texture = texture; _rotation = rotation; _flipX = flipX; _flipY = flipY; SurfaceDescription desc = _texture.GetLevelDescription(0); _textureMaxUV = new SizeF(imageInformation.Width / (float) desc.Width, imageInformation.Height / (float) desc.Height); // Reset animation _animator.Initialize(); if (_slideShowTimer != null) _slideShowTimer.Change(_slideShowImageDuration, TS_INFINITE); else CheckTimer(); _playbackStartTime = DateTime.Now; if (_pauseTime.HasValue) _pauseTime = _playbackStartTime; } }
public static async Task <bool> ParseAsync(JObject message, SocketServer server, AsyncSocket sender) { string imagePath = GetMessageValue <string>(message, "ImagePath"); string userTag = GetMessageValue <string>(message, "UserTag"); int maxWidth = GetMessageValue <int>(message, "MaximumWidth"); int maxHeight = GetMessageValue <int>(message, "MaximumHeight"); string id = GetMessageValue <string>(message, "ImageId"); var client = sender.GetRemoteClient(); ServiceRegistration.Get <ILogger>().Debug("WifiRemote: Get Image: UserTag: {0}, ImageId: {1}, ImagePath: {2}, MaximumWidth: {3}, MaximumHeight: {4}", userTag, id, imagePath, maxWidth, maxHeight); if (!string.IsNullOrEmpty(imagePath) && string.IsNullOrEmpty(id)) { var item = await Helper.GetMediaItemByFileNameAsync(client.UserId, imagePath); id = item?.MediaItemId.ToString(); } if (!Guid.TryParse(id, out Guid mediaItemGuid)) { ServiceRegistration.Get <ILogger>().Error("WifiRemote: Get Image: Couldn't convert ImageId {0} to Guid", id); return(false); } MessageImage msg = new MessageImage(); var mediaItem = await Helper.GetMediaItemByIdAsync(client.UserId, mediaItemGuid); Image image = null; IResourceLocator locator = mediaItem.GetResourceLocator(); using (IResourceAccessor ra = locator.CreateAccessor()) { IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { ServiceRegistration.Get <ILogger>().Error("WifiRemote: Get Image: Couldn't read image {0}", id); return(false); } using (Stream stream = fsra.OpenRead()) { image = Image.FromStream(stream); } } if ((maxWidth > 0 && image.Width > maxWidth) || (maxHeight > 0 && image.Height > maxHeight)) { int height = image.Height; int width = image.Width; if (maxHeight > 0 && height > maxHeight) { float ratio = (float)height / (float)maxHeight; width = Convert.ToInt32((float)width / ratio); } if (maxWidth > 0 && width > maxWidth) { width = maxWidth; } var newImage = ImageHelper.ResizedImage(image, width); image.Dispose(); image = newImage; } byte[] data = ImageHelper.ImageToByteArray(image, System.Drawing.Imaging.ImageFormat.Jpeg); image?.Dispose(); msg.ImagePath = mediaItem.ToString(); msg.UserTag = userTag; msg.Image = Convert.ToBase64String(data); SendMessageToClient.Send(msg, sender); return(true); }
public override async Task CollectFanArtAsync(Guid mediaItemId, IDictionary <Guid, IList <MediaItemAspect> > aspects) { IResourceLocator mediaItemLocator = null; if (!BaseInfo.IsVirtualResource(aspects)) { mediaItemLocator = GetResourceLocator(aspects); } if (!aspects.ContainsKey(AudioAspect.ASPECT_ID) || mediaItemLocator == null) { return; } IFanArtCache fanArtCache = ServiceRegistration.Get <IFanArtCache>(); using (IResourceAccessor mediaItemAccessor = mediaItemLocator.CreateAccessor()) { //Album fanart if (RelationshipExtractorUtils.TryGetLinkedId(AudioAlbumAspect.ROLE_ALBUM, aspects, out Guid albumMediaItemId) && AddToCache(albumMediaItemId)) { var existingCovers = fanArtCache.GetFanArtFiles(albumMediaItemId, FanArtTypes.Cover); if (!existingCovers.Any()) //Only get album cover if needed for better performance { NfoAlbumReader albumNfoReader = await AUDIO_EXTRACTOR.TryGetNfoAlbumReaderAsync(mediaItemAccessor, true).ConfigureAwait(false); if (albumNfoReader != null) { var stubs = albumNfoReader.GetAlbumStubs(); var mainStub = stubs?.FirstOrDefault(); if (mainStub?.Thumb != null) { await fanArtCache.TrySaveFanArt(albumMediaItemId, mainStub.Title, FanArtTypes.Cover, p => TrySaveFileImage(mainStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false); } } } } //Artist fanart IList <Tuple <Guid, string> > artists = GetArtists(aspects); if (artists?.Count > 0) { foreach (var artist in artists) { var existingThumbs = fanArtCache.GetFanArtFiles(artist.Item1, FanArtTypes.Thumbnail); if (!existingThumbs.Any() && AddToCache(artist.Item1)) //Only get artist thumbnail if needed for better performance { NfoArtistReader artistReader = await AUDIO_EXTRACTOR.TryGetNfoArtistReaderAsync(mediaItemAccessor, artist.Item2, true).ConfigureAwait(false); if (artistReader != null) { var stubs = artistReader.GetArtistStubs(); var mainStub = stubs?.FirstOrDefault(); if (string.Equals(mainStub?.Name, artist.Item2, StringComparison.InvariantCultureIgnoreCase)) { if (mainStub?.Thumb != null) { await fanArtCache.TrySaveFanArt(artist.Item1, artist.Item2, FanArtTypes.Thumbnail, p => TrySaveFileImage(mainStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false); } } } } } } } }
public override async Task CollectFanArtAsync(Guid mediaItemId, IDictionary <Guid, IList <MediaItemAspect> > aspects) { IResourceLocator mediaItemLocator = null; if (!BaseInfo.IsVirtualResource(aspects)) { mediaItemLocator = GetResourceLocator(aspects); } if (!aspects.ContainsKey(EpisodeAspect.ASPECT_ID) || mediaItemLocator == null) { return; } IFanArtCache fanArtCache = ServiceRegistration.Get <IFanArtCache>(); using (IResourceAccessor mediaItemAccessor = mediaItemLocator.CreateAccessor()) { EpisodeInfo episodeInfo = new EpisodeInfo(); if (!episodeInfo.FromMetadata(aspects)) { return; } //Episode fanart if (AddToCache(mediaItemId)) { var existingThumbs = fanArtCache.GetFanArtFiles(mediaItemId, FanArtTypes.Thumbnail); int?season = episodeInfo.SeasonNumber; int?episode = episodeInfo.EpisodeNumbers != null && episodeInfo.EpisodeNumbers.Any() ? episodeInfo.EpisodeNumbers.First() : (int?)null; if (!existingThumbs.Any()) //Only get thumb if needed for better performance { NfoSeriesEpisodeReader episodeReader = await SERIES_EXTRACTOR.TryGetNfoSeriesEpisodeReaderAsync(mediaItemAccessor, season, episode, true).ConfigureAwait(false); if (episodeReader != null) { var stubs = episodeReader.GetEpisodeStubs(); var mainStub = stubs?.FirstOrDefault(); if (mainStub?.Thumb != null) { await fanArtCache.TrySaveFanArt(mediaItemId, episodeInfo.ToString(), FanArtTypes.Thumbnail, p => TrySaveFileImage(mainStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false); } } } } //Series fanart if (RelationshipExtractorUtils.TryGetLinkedId(SeriesAspect.ROLE_SERIES, aspects, out Guid seriesMediaItemId)) { IList <Tuple <Guid, string> > actors = GetActors(aspects); RelationshipExtractorUtils.TryGetLinkedId(SeasonAspect.ROLE_SEASON, aspects, out Guid seasonMediaItemId); //Check if loading nfo is needed if ((actors?.All(a => IsInCache(a.Item1)) ?? true) && IsInCache(seriesMediaItemId) && (seasonMediaItemId == Guid.Empty || IsInCache(seasonMediaItemId))) { return; //Everything was already saved } NfoSeriesReader seriesNfoReader = await SERIES_EXTRACTOR.TryGetNfoSeriesReaderAsync(mediaItemAccessor, true).ConfigureAwait(false); if (seriesNfoReader != null) { var stubs = seriesNfoReader.GetSeriesStubs(); var mainStub = stubs?.FirstOrDefault(); if (AddToCache(seriesMediaItemId)) { var series = episodeInfo.CloneBasicInstance <SeriesInfo>(); if (mainStub?.Thumbs?.Count > 0) { await TrySaveThumbStubs(fanArtCache, mainStub.Thumbs, null, seriesMediaItemId, series.ToString()); } } if (seasonMediaItemId != Guid.Empty && episodeInfo.SeasonNumber.HasValue && AddToCache(seasonMediaItemId)) { var season = episodeInfo.CloneBasicInstance <SeasonInfo>(); if (mainStub?.Thumbs?.Count > 0) { await TrySaveThumbStubs(fanArtCache, mainStub.Thumbs, episodeInfo.SeasonNumber, seasonMediaItemId, season.ToString()); } } //Actor fanart //We only want the series actors because thumb loading is disabled on episode actors for performance reasons, so we might need to //load the series nfo multiple time before we have all actors depending on what actors are in the episode foreach (var actor in actors) { if (!IsInCache(actor.Item1)) { var existingThumbs = fanArtCache.GetFanArtFiles(actor.Item1, FanArtTypes.Thumbnail); var actorStub = mainStub?.Actors?.FirstOrDefault(a => string.Equals(a?.Name, actor.Item2, StringComparison.InvariantCultureIgnoreCase)); if (actorStub != null || existingThumbs.Any()) //We have a thumb already or no thumb is available, so no need to check again { AddToCache(actor.Item1); } if (actorStub?.Thumb != null) { await fanArtCache.TrySaveFanArt(actor.Item1, actor.Item2, FanArtTypes.Thumbnail, p => TrySaveFileImage(actorStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false); } } } } } } }
public override async Task CollectFanArtAsync(Guid mediaItemId, IDictionary <Guid, IList <MediaItemAspect> > aspects) { IResourceLocator mediaItemLocator = null; if (!BaseInfo.IsVirtualResource(aspects)) { mediaItemLocator = GetResourceLocator(aspects); } if (!aspects.ContainsKey(MovieAspect.ASPECT_ID) || mediaItemLocator == null) { return; } IFanArtCache fanArtCache = ServiceRegistration.Get <IFanArtCache>(); using (IResourceAccessor mediaItemAccessor = mediaItemLocator.CreateAccessor()) { IList <Tuple <Guid, string> > actors = GetActors(aspects); //Check if loading nfo is needed if ((actors?.All(a => IsInCache(a.Item1)) ?? true) && IsInCache(mediaItemId)) { return; //Everything was already saved } NfoMovieReader movieNfoReader = await MOVIE_EXTRACTOR.TryGetNfoMovieReaderAsync(mediaItemAccessor, true).ConfigureAwait(false); if (movieNfoReader != null) { //Movie fanart var stubs = movieNfoReader.GetMovieStubs(); var mainStub = stubs?.FirstOrDefault(); if (AddToCache(mediaItemId)) { if (mainStub?.Thumb != null) { await fanArtCache.TrySaveFanArt(mediaItemId, mainStub.Title, FanArtTypes.Poster, p => TrySaveFileImage(mainStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false); } await TrySaveFanArt(fanArtCache, FanArtTypes.FanArt, "FanArt", mainStub?.FanArt, mediaItemId, mainStub?.Title).ConfigureAwait(false); await TrySaveFanArt(fanArtCache, FanArtTypes.DiscArt, "DiscArt", mainStub?.DiscArt, mediaItemId, mainStub?.Title).ConfigureAwait(false); await TrySaveFanArt(fanArtCache, FanArtTypes.Logo, "Logo", mainStub?.Logos, mediaItemId, mainStub?.Title).ConfigureAwait(false); await TrySaveFanArt(fanArtCache, FanArtTypes.ClearArt, "ClearArt", mainStub?.ClearArt, mediaItemId, mainStub?.Title).ConfigureAwait(false); await TrySaveFanArt(fanArtCache, FanArtTypes.Banner, "Banner", mainStub?.Banners, mediaItemId, mainStub?.Title).ConfigureAwait(false); await TrySaveFanArt(fanArtCache, FanArtTypes.Thumbnail, "Landscape", mainStub?.Landscape, mediaItemId, mainStub?.Title).ConfigureAwait(false); } //Actor fanart if (actors != null) { foreach (var actor in actors) { if (!IsInCache(actor.Item1)) { var existingThumbs = fanArtCache.GetFanArtFiles(actor.Item1, FanArtTypes.Thumbnail); var actorStub = mainStub?.Actors?.FirstOrDefault(a => string.Equals(a?.Name, actor.Item2, StringComparison.InvariantCultureIgnoreCase)); if (actorStub != null || existingThumbs.Any()) //We have a thumb already or no thumb is available, so no need to check again { AddToCache(actor.Item1); } if (actorStub?.Thumb != null) { await fanArtCache.TrySaveFanArt(actor.Item1, actor.Item2, FanArtTypes.Thumbnail, p => TrySaveFileImage(actorStub.Thumb, p, "Thumb", "Nfo.")).ConfigureAwait(false); } } } } } } }
/// <summary> /// Sets the data of the new image to be played. /// </summary> /// <param name="locator">Resource locator of the image item.</param> /// <param name="mediaItemTitle">Title of the image item.</param> /// <param name="rotation">Rotation of the image.</param> /// <param name="flipX">Flipping in horizontal direction.</param> /// <param name="flipY">Flipping in vertical direction.</param> public void SetMediaItemData(IResourceLocator locator, string mediaItemTitle, RightAngledRotation rotation, bool flipX, bool flipY) { if (locator == null) lock (_syncObj) { _currentLocator = null; return; } using (IResourceAccessor ra = locator.CreateAccessor()) { IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) return; using (Stream stream = fsra.OpenRead()) { string key = fsra.CanonicalLocalResourcePath.Serialize(); _texture = ContentManager.Instance.GetTexture(stream, key, true); if (_texture == null) return; if (!_texture.IsAllocated) _texture.Allocate(); if (!_texture.IsAllocated) return; } } lock (_syncObj) { ReloadSettings(); _state = PlayerState.Active; _currentLocator = locator; _mediaItemTitle = mediaItemTitle; _rotation = rotation; _flipX = flipX; _flipY = flipY; SurfaceDescription desc = _texture.Texture.GetLevelDescription(0); _textureMaxUV = new SizeF(_texture.Width / (float) desc.Width, _texture.Height / (float) desc.Height); // Reset animation _animator.Initialize(); if (_slideShowTimer != null) _slideShowTimer.Change(_slideShowImageDuration, TS_INFINITE); else CheckTimer(); _playbackStartTime = DateTime.Now; if (_pauseTime.HasValue) _pauseTime = _playbackStartTime; } }
public static bool CanPlay(IResourceLocator locator, string mimeType) { // First check the mime type if (!string.IsNullOrEmpty(mimeType) && !mimeType.StartsWith("image")) return false; using (IResourceAccessor accessor = locator.CreateAccessor()) { if (!(accessor is IFileSystemResourceAccessor)) return false; string ext = StringUtils.TrimToEmpty(DosPathHelper.GetExtension(accessor.ResourcePathName)).ToLowerInvariant(); ImagePlayerSettings settings = ServiceRegistration.Get<ISettingsManager>().Load<ImagePlayerSettings>(); return settings.SupportedExtensions.IndexOf(ext) > -1; } }
/// <summary> /// Loads an image from filesystem an returns a new <see cref="FanArtImage"/>. /// </summary> /// <param name="resourceLocator">Resource to load</param> /// <param name="maxWidth">Maximum width for image. <c>0</c> returns image in original size.</param> /// <param name="maxHeight">Maximum height for image. <c>0</c> returns image in original size.</param> /// <param name="mediaType">MediaType</param> /// <param name="fanArtType">FanArtType</param> /// <param name="fanArtName">Fanart name</param> /// <returns>FanArtImage or <c>null</c>.</returns> public static FanArtImage FromResource(IResourceLocator resourceLocator, int maxWidth, int maxHeight, FanArtConstants.FanArtMediaType mediaType, FanArtConstants.FanArtType fanArtType, string fanArtName) { try { using (var ra = resourceLocator.CreateAccessor()) { ILocalFsResourceAccessor fsra = ra as ILocalFsResourceAccessor; if (fsra != null) { fsra.PrepareStreamAccess(); using (var fileStream = fsra.OpenRead()) // Calling EnsureLocalFileSystemAccess not necessary; only string operation return FromStream(fileStream, maxWidth, maxHeight, mediaType, fanArtType, fanArtName, fsra.LocalFileSystemPath); } } } catch { } return null; }
public void SetMediaItem(IResourceLocator locator, string mediaItemTitle) { // free previous opened resource FilterGraphTools.TryDispose(ref _resourceAccessor); FilterGraphTools.TryDispose(ref _rot); _state = PlayerState.Active; _isPaused = true; try { _resourceLocator = locator; _mediaItemTitle = mediaItemTitle; if (_resourceLocator.NativeResourcePath.IsNetworkResource) { _resourceAccessor = _resourceLocator.CreateAccessor() as INetworkResourceAccessor; if (_resourceAccessor == null) throw new IllegalCallException("The VideoPlayer can only play network resources of type INetworkResourceAccessor"); ServiceRegistration.Get<ILogger>().Debug("{0}: Initializing for network media item '{1}'", PlayerTitle, SourcePathOrUrl); } else { ILocalFsResourceAccessor lfsr; if (!_resourceLocator.TryCreateLocalFsAccessor(out lfsr)) throw new IllegalCallException("The VideoPlayer can only play local file system resources"); _resourceAccessor = lfsr; ServiceRegistration.Get<ILogger>().Debug("{0}: Initializing for media item '{1}'", PlayerTitle, SourcePathOrUrl); } // Create a DirectShow FilterGraph CreateGraphBuilder(); // Add it in ROT (Running Object Table) for debug purpose, it allows to view the Graph from outside (i.e. graphedit) _rot = new DsROTEntry(_graphBuilder); // Add a notification handler (see WndProc) _instancePtr = Marshal.AllocCoTaskMem(4); IMediaEventEx mee = _graphBuilder as IMediaEventEx; if (mee != null) mee.SetNotifyWindow(SkinContext.Form.Handle, WM_GRAPHNOTIFY, _instancePtr); // Create the Allocator / Presenter object AddPresenter(); ServiceRegistration.Get<ILogger>().Debug("{0}: Adding audio renderer", PlayerTitle); AddAudioRenderer(); ServiceRegistration.Get<ILogger>().Debug("{0}: Adding preferred codecs", PlayerTitle); AddPreferredCodecs(); ServiceRegistration.Get<ILogger>().Debug("{0}: Adding file source", PlayerTitle); AddFileSource(); ServiceRegistration.Get<ILogger>().Debug("{0}: Run graph", PlayerTitle); //This needs to be done here before we check if the evr pins are connected //since this method gives players the chance to render the last bits of the graph OnBeforeGraphRunning(); // Now run the graph, i.e. the DVD player needs a running graph before getting informations from dvd filter. IMediaControl mc = (IMediaControl) _graphBuilder; int hr = mc.Run(); DsError.ThrowExceptionForHR(hr); _initialized = true; OnGraphRunning(); } catch (Exception) { Shutdown(); throw; } }
public static bool CanPlay(IResourceLocator locator, string mimeType) { // First check the Mime Type if (!string.IsNullOrEmpty(mimeType) && !mimeType.StartsWith("audio")) return false; using (IResourceAccessor accessor = locator.CreateAccessor()) { if (accessor is AudioCDResourceAccessor || accessor is INetworkResourceAccessor) return true; string ext = DosPathHelper.GetExtension(accessor.ResourcePathName).ToLowerInvariant(); BassPlayerSettings settings = ServiceRegistration.Get<ISettingsManager>().Load<BassPlayerSettings>(); return settings.SupportedExtensions.IndexOf(ext) > -1; } }
/// <summary> /// Creates _resourceAccessor from the _resourceLocator which can be used by the specific player. /// </summary> protected virtual void CreateResourceAccessor() { _resourceAccessor = _resourceLocator.CreateAccessor(); }