public static Task <WebItemSupportStatus> ProcessAsync(IOwinContext context, WebMediaType type, int?provider, string itemId, int?offset) { if (itemId == null) { throw new BadRequestException("GetItemSupportStatus: itemId is null"); } ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); ISet <Guid> optionalMIATypes = new HashSet <Guid>(); optionalMIATypes.Add(VideoAspect.ASPECT_ID); optionalMIATypes.Add(MovieAspect.ASPECT_ID); optionalMIATypes.Add(SeriesAspect.ASPECT_ID); optionalMIATypes.Add(AudioAspect.ASPECT_ID); optionalMIATypes.Add(ImageAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, itemId, necessaryMIATypes, optionalMIATypes); bool result = item != null; WebItemSupportStatus webItemSupportStatus = new WebItemSupportStatus { Supported = result, Reason = "" }; return(Task.FromResult(webItemSupportStatus)); }
public static Task <Stream> ProcessAsync(IOwinContext context, WebMediaType mediatype, WebFileType filetype, string id, int offset) { ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, id, necessaryMIATypes, null); if (item == null) { throw new NotFoundException("RetrieveFile: no media item found"); } var files = ResourceAccessUtils.GetResourcePaths(item); var ra = GetResourceAccessor(files[offset]); IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { throw new InternalServerException("RetrieveFile: failed to create IFileSystemResourceAccessor"); } return(fsra.OpenReadAsync()); }
public static Task <IList <string> > ProcessAsync(IOwinContext context, WebMediaType mediatype, WebFileType filetype, string id) { if (id == null) { throw new BadRequestException("GetPathList: id is null"); } ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); ISet <Guid> optionalMIATypes = new HashSet <Guid>(); optionalMIATypes.Add(VideoAspect.ASPECT_ID); optionalMIATypes.Add(MovieAspect.ASPECT_ID); optionalMIATypes.Add(SeriesAspect.ASPECT_ID); optionalMIATypes.Add(AudioAspect.ASPECT_ID); optionalMIATypes.Add(ImageAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), necessaryMIATypes, optionalMIATypes); if (item == null) { throw new NotFoundException(String.Format("GetPathList: No MediaItem found with id: {0}", id)); } var output = ResourceAccessUtils.GetPaths(item); return(System.Threading.Tasks.Task.FromResult(output)); }
/// <summary> /// Checks if an image is already in the cache /// </summary> /// <param name="id">Guid of the media item</param> /// <param name="identifier">identifier from GetIdentifier()</param> /// <param name="width">Width of the finale image</param> /// <param name="height">height of the final image</param> /// <param name="borders">borders of the final image</param> /// <returns>Returns true if the image was added to the cache, false if the image is already in the cache</returns> /// <returns>true if the image is in the cache, otherwise false</returns> internal static bool IsInCache(IOwinContext context, CacheIdentifier identifier) { lock (_lockObject) { string filepath = GetFilePath(identifier); DateTime dateAdded; if (!identifier.IsTvRadio) { ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, identifier.MediaItemId, necessaryMIATypes, null); if (item == null) { return(false); } dateAdded = (DateTime)item.GetAspect(ImporterAspect.Metadata)[ImporterAspect.ATTR_DATEADDED]; } else { dateAdded = DateTime.Now.AddMonths(-1); // refresh image evry month } return(File.Exists(GetFilePath(identifier)) && DateTime.Compare(GetLastModifiedTime(filepath), dateAdded) >= 0); } }
public static async Task <bool> ProcessAsync(IOwinContext context, WebMediaType type, string id) { if (id == null) { throw new BadRequestException("GetImage: id is null"); } ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); necessaryMIATypes.Add(ImageAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, id, necessaryMIATypes, null); var resourcePathStr = item.PrimaryResources[item.ActiveResourceLocatorIndex].GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH); var resourcePath = ResourcePath.Deserialize(resourcePathStr.ToString()); var ra = GetResourceAccessor(resourcePath); IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { throw new InternalServerException("GetImage: failed to create IFileSystemResourceAccessor"); } using (var resourceStream = fsra.OpenRead()) { // HTTP/1.1 RFC2616 section 14.25 'If-Modified-Since' if (!string.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"])) { DateTime lastRequest = DateTime.Parse(context.Request.Headers["If-Modified-Since"]); if (lastRequest.CompareTo(fsra.LastChanged) <= 0) { context.Response.StatusCode = (int)HttpStatusCode.NotModified; } } // HTTP/1.1 RFC2616 section 14.29 'Last-Modified' context.Response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r"); string byteRangesSpecifier = context.Request.Headers["Range"]; IList <Range> ranges = ParseByteRanges(byteRangesSpecifier, resourceStream.Length); bool onlyHeaders = context.Request.Method == "HEAD" || context.Response.StatusCode == (int)HttpStatusCode.NotModified; if (ranges != null && ranges.Count > 0) { // We only support last range await SendRangeAsync(context, resourceStream, ranges[ranges.Count - 1], onlyHeaders); } else { await SendWholeFileAsync(context, resourceStream, onlyHeaders); } } return(true); }
public static Task <WebPictureBasic> ProcessAsync(IOwinContext context, string id) { MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), BasicNecessaryMIATypeIds, BasicOptionalMIATypeIds); if (item == null) { throw new NotFoundException(string.Format("No Image found with id: {0}", id)); } return(Task.FromResult(PictureBasic(item))); }
public static Task <WebTVShowBasic> ProcessAsync(IOwinContext context, string id) { MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), BasicNecessaryMIATypeIds, BasicOptionalMIATypeIds); if (item == null) { throw new NotFoundException(String.Format("GetTVShowDetailedById: No MediaItem found with id: {0}", id)); } return(Task.FromResult(TVShowBasic(context, item))); }
public static Task <WebRecordingBasic> ProcessAsync(IOwinContext context, string id) { if (!ServiceRegistration.IsRegistered <ITvProvider>()) { throw new BadRequestException("GetRecordingById: ITvProvider not found"); } MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), BasicNecessaryMIATypeIds, BasicOptionalMIATypeIds); WebRecordingBasic webRecordingBasic = RecordingBasic(item); return(Task.FromResult(webRecordingBasic)); }
public static Task <WebTVEpisodeDetailed> ProcessAsync(IOwinContext context, string id) { MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), DetailedNecessaryMIATypeIds, DetailedOptionalMIATypeIds); if (item == null) { throw new NotFoundException(String.Format("GetTvEpisodeBasicById: No MediaItem found with id: {0}", id)); } WebTVEpisodeDetailed webTvEpisodeDetailed = EpisodeDetailed(item); return(Task.FromResult(webTvEpisodeDetailed)); }
public static Task <WebMusicTrackDetailed> ProcessAsync(IOwinContext context, string id) { MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), BasicNecessaryMIATypeIds, BasicOptionalMIATypeIds); if (item == null) { throw new NotFoundException(String.Format("GetMusicTrackDetailedById: No MediaItem found with id: {0}", id)); } var track = MusicTrackDetailed(item); AssignArtists(context, new[] { track }); return(Task.FromResult(track)); }
public static Task <WebMusicAlbumBasic> ProcessAsync(IOwinContext context, string id) { if (id == null) { throw new BadRequestException("GetMusicTrackBasicById: id is null"); } MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), BasicNecessaryMIATypeIds, BasicOptionalMIATypeIds); if (item == null) { throw new NotFoundException(String.Format("GetMusicTrackBasicById: No MediaItem found with id: {0}", id)); } return(Task.FromResult(MusicAlbumBasic(item))); }
public static Task <WebBoolResult> ProcessAsync(IOwinContext context, string id) { if (!ServiceRegistration.IsRegistered <ITvProvider>()) { throw new BadRequestException("DeleteRecording: ITvProvider not found"); } MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), BasicNecessaryMIATypeIds, BasicOptionalMIATypeIds); if (item == null) { throw new NotFoundException(String.Format("DeleteRecording: No MediaItem found with id: {0}", id)); } return(System.Threading.Tasks.Task.FromResult(new WebBoolResult { Result = MediaLibraryAccess.Delete(context, item) })); }
public static Task <WebRecordingFileInfo> ProcessAsync(IOwinContext context, string id) { ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); necessaryMIATypes.Add(RecordingAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), necessaryMIATypes, null); if (item == null) { throw new BadRequestException("GetRecordingFileInfo: no media item found"); } var resourcePathStr = item.PrimaryProviderResourcePath(); var resourcePath = ResourcePath.Deserialize(resourcePathStr.ToString()); var ra = GetResourceAccessor(resourcePath); IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { throw new InternalServerException("GetRecordingFileInfo: failed to create IFileSystemResourceAccessor"); } WebRecordingFileInfo webFileInfo = new WebRecordingFileInfo { Exists = fsra.Exists, Extension = fsra.Path.Split('.').Last(), IsLocalFile = true, IsReadOnly = true, LastAccessTime = DateTime.Now, LastModifiedTime = fsra.LastChanged, Name = fsra.ResourceName, OnNetworkDrive = false, Path = resourcePath.FileName, Size = fsra.Size, }; return(Task.FromResult(webFileInfo)); }
public static Task <WebIntResult> ProcessAsync(IOwinContext context, string id) { ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(SeasonAspect.ASPECT_ID); // this is the MediaItem for the season MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), necessaryMIATypes, null); if (item == null) { throw new NotFoundException(String.Format("GetTVEpisodeCountForSeason: No MediaItem found with id: {0}", id)); } int count = item.GetAspect(SeasonAspect.Metadata).GetAttributeValue <int>(SeasonAspect.ATTR_AVAILABLE_EPISODES); return(Task.FromResult(new WebIntResult { Result = count })); }
public static Task <WebFileInfo> ProcessAsync(IOwinContext context, WebMediaType mediatype, WebFileType filetype, string id, int offset) { ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, id, necessaryMIATypes, null); if (item == null) { throw new NotFoundException("GetFileInfo: no media item found"); } var files = ResourceAccessUtils.GetResourcePaths(item); var ra = GetResourceAccessor(files[offset]); IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { throw new InternalServerException("GetFileInfo: failed to create IFileSystemResourceAccessor"); } WebFileInfo webFileInfo = new WebFileInfo { Exists = fsra.Exists, Extension = fsra.Path.Split('.').Last(), IsLocalFile = true, IsReadOnly = true, LastAccessTime = DateTime.Now, LastModifiedTime = fsra.LastChanged, Name = fsra.ResourceName, OnNetworkDrive = false, Path = files[offset].FileName, Size = fsra.Size, }; return(Task.FromResult(webFileInfo)); }
public static Task <WebMediaItem> ProcessAsync(IOwinContext context, string id) { if (id == null) { throw new BadRequestException("GetMediaItem: id is null"); } ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); ISet <Guid> optionalMIATypes = new HashSet <Guid>(); optionalMIATypes.Add(VideoAspect.ASPECT_ID); optionalMIATypes.Add(MovieAspect.ASPECT_ID); optionalMIATypes.Add(EpisodeAspect.ASPECT_ID); optionalMIATypes.Add(AudioAspect.ASPECT_ID); optionalMIATypes.Add(ImageAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), necessaryMIATypes, optionalMIATypes); if (item == null) { throw new NotFoundException(String.Format("GetMediaItem: No MediaItem found with id: {0}", id)); } WebMediaItem webMediaItem = new WebMediaItem(); webMediaItem.Id = item.MediaItemId.ToString(); webMediaItem.Artwork = ResourceAccessUtils.GetWebArtwork(item); webMediaItem.DateAdded = item.GetAspect(ImporterAspect.Metadata).GetAttributeValue <DateTime>(ImporterAspect.ATTR_DATEADDED); webMediaItem.Path = ResourceAccessUtils.GetPaths(item); webMediaItem.Type = ResourceAccessUtils.GetWebMediaType(item); webMediaItem.Title = item.GetAspect(MediaAspect.Metadata).GetAttributeValue <string>(MediaAspect.ATTR_TITLE); return(Task.FromResult(webMediaItem)); }
public static async Task ProcessAsync(IOwinContext context, Guid itemId) { // Grab the media item given in the request. try { Logger.Debug("GetMediaItem: Attempting to load mediaitem {0}", itemId.ToString()); // Attempt to grab the media item from the database. ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); var item = MediaLibraryAccess.GetMediaItemById(context, itemId, necessaryMIATypes, null); if (item == null) { throw new NotFoundException(string.Format("Media item '{0}' not found.", itemId)); } // Grab the mimetype from the media item and set the Content Type header. // TODO: Fix string mimeType = item?.PrimaryResources?.FirstOrDefault()?.GetAttributeValue <string>(ProviderResourceAspect.ATTR_MIME_TYPE) ?? "video/*"; context.Response.ContentType = mimeType; // Grab the resource path for the media item. var resourcePathStr = item.PrimaryResources[item.ActiveResourceLocatorIndex].GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH); var resourcePath = ResourcePath.Deserialize(resourcePathStr.ToString()); var ra = GetResourceAccessor(resourcePath); IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { throw new InternalServerException("GetMediaItem: failed to create IFileSystemResourceAccessor"); } using (var resourceStream = fsra.OpenRead()) { // HTTP/1.1 RFC2616 section 14.25 'If-Modified-Since' if (!string.IsNullOrEmpty(context.Response.Headers["If-Modified-Since"])) { DateTime lastRequest = DateTime.Parse(context.Response.Headers["If-Modified-Since"]); if (lastRequest.CompareTo(fsra.LastChanged) <= 0) { context.Response.StatusCode = (int)HttpStatusCode.NotModified; } } // HTTP/1.1 RFC2616 section 14.29 'Last-Modified' context.Response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r"); string byteRangesSpecifier = context.Request.Headers["Range"]; IList <Range> ranges = ParseByteRanges(byteRangesSpecifier, resourceStream.Length); bool onlyHeaders = context.Request.Method == "HEAD" || context.Response.StatusCode == (int)HttpStatusCode.NotModified; if (ranges != null) { // We only support last range await SendRangeAsync(context, resourceStream, ranges[ranges.Count - 1], onlyHeaders); } else { await SendWholeFileAsync(context, resourceStream, onlyHeaders); } } } catch (FileNotFoundException ex) { throw new InternalServerException(string.Format("Failed to proccess media item '{0}'", itemId), ex); } }
public static Task <WebResolution> ProcessAsync(IOwinContext context, WebMediaType type, int?provider, string itemId, int?offset, string profileName) { if (itemId == null) { throw new BadRequestException("GetStreamSize: itemId is null"); } if (profileName == null) { throw new BadRequestException("GetStreamSize: profileName is null"); } ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); ISet <Guid> optionalMIATypes = new HashSet <Guid>(); optionalMIATypes.Add(VideoAspect.ASPECT_ID); optionalMIATypes.Add(VideoStreamAspect.ASPECT_ID); optionalMIATypes.Add(VideoAudioStreamAspect.ASPECT_ID); optionalMIATypes.Add(ImageAspect.ASPECT_ID); var item = MediaLibraryAccess.GetMediaItemById(context, itemId, necessaryMIATypes, optionalMIATypes); if (item == null) { throw new NotFoundException(String.Format("GetStreamSize: No MediaItem found with id: {0}", itemId)); } EndPointProfile profile = null; List <EndPointProfile> namedProfiles = ProfileManager.Profiles.Where(x => x.Value.Name == profileName).Select(namedProfile => namedProfile.Value).ToList(); if (namedProfiles.Count > 0) { profile = namedProfiles[0]; } else if (ProfileManager.Profiles.ContainsKey(profileName)) { profile = ProfileManager.Profiles[profileName]; } if (profile == null) { throw new BadRequestException(string.Format("GetStreamSize: unknown profile: {0}", profileName)); } var target = new ProfileMediaItem(Guid.NewGuid().ToString(), profile, false); var output = new WebResolution(); if (target.IsImage) { output.Height = target.Image.Height ?? 0; output.Width = target.Image.Width ?? 0; } else if (target.IsVideo) { output.Height = target.Image.Height ?? 0; output.Width = target.Image.Width ?? 0; } return(Task.FromResult(output)); }
internal static IList <FanArtImage> GetFanArtImages(IOwinContext context, string id, bool isTvRadio, bool isRecording, string fanartType, string fanArtMediaType) { ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); ISet <Guid> optionalMIATypes = new HashSet <Guid>(); optionalMIATypes.Add(VideoAspect.ASPECT_ID); optionalMIATypes.Add(MovieAspect.ASPECT_ID); optionalMIATypes.Add(SeriesAspect.ASPECT_ID); optionalMIATypes.Add(SeasonAspect.ASPECT_ID); optionalMIATypes.Add(EpisodeAspect.ASPECT_ID); optionalMIATypes.Add(AudioAspect.ASPECT_ID); optionalMIATypes.Add(ImageAspect.ASPECT_ID); MediaItem item = null; if (!isTvRadio) { item = MediaLibraryAccess.GetMediaItemById(context, id, necessaryMIATypes, optionalMIATypes); } if (item == null && !isTvRadio) { throw new BadRequestException(String.Format("GetFanArtImages: No MediaItem found with id: {0}", id)); } string name = id; if (isTvRadio) { IChannelAndGroupInfoAsync channelAndGroupInfo = ServiceRegistration.Get <ITvProvider>(false) as IChannelAndGroupInfoAsync; if (channelAndGroupInfo != null) { int idInt = int.Parse(id); var channel = channelAndGroupInfo.GetChannelAsync(idInt).Result; if (channel.Success) { name = channel.Result.Name; } else { throw new BadRequestException(String.Format("GetFanArtImages: No Channel found with id: {0}", id)); } } } IList <FanArtImage> fanart = ServiceRegistration.Get <IFanArtService>().GetFanArt(fanArtMediaType, fanartType, name, 0, 0, false); if (fanart == null || fanart.Count == 0) { Logger.Debug("GetFanArtImages: no fanart found - fanArtMediaType: {0}, fanartType: {1}, name: {2}", fanArtMediaType, fanartType, name); // We return a transparent image instead of throwing an exception Bitmap newImage = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Graphics graphic = Graphics.FromImage(newImage); graphic.Clear(Color.Transparent); MemoryStream ms = new MemoryStream(); newImage.Save(ms, ImageFormat.Png); return(new List <FanArtImage> { new FanArtImage { Name = NO_FANART_IMAGE_NAME, BinaryData = ms.ToArray() } }); } return(fanart); }
public static async Task <WebMediaInfo> ProcessAsync(IOwinContext context, string itemId, WebMediaType type) { if (itemId == null) { throw new BadRequestException("GetMediaInfo: itemId is null"); } Guid mediaItemId; MediaItem item; long duration = 0; string container = string.Empty; MetadataContainer info; List <WebVideoStream> webVideoStreams = new List <WebVideoStream>(); List <WebAudioStream> webAudioStreams = new List <WebAudioStream>(); List <WebSubtitleStream> webSubtitleStreams = new List <WebSubtitleStream>(); if (type == WebMediaType.TV || type == WebMediaType.Radio) { int channelIdInt; if (int.TryParse(itemId, out channelIdInt)) { item = new LiveTvMediaItem(Guid.Empty); info = MediaAnalyzer.ParseChannelStreamAsync(channelIdInt, (LiveTvMediaItem)item).Result; if (info == null) { throw new BadRequestException(String.Format("GetMediaInfo: Channel {0} stream not available", itemId)); } } else { throw new BadRequestException(String.Format("GetMediaInfo: Channel {0} not found", itemId)); } } else if (Guid.TryParse(itemId, out mediaItemId) == true) { ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); ISet <Guid> optionalMIATypes = new HashSet <Guid>(); optionalMIATypes.Add(VideoAspect.ASPECT_ID); optionalMIATypes.Add(VideoStreamAspect.ASPECT_ID); optionalMIATypes.Add(VideoAudioStreamAspect.ASPECT_ID); optionalMIATypes.Add(AudioAspect.ASPECT_ID); optionalMIATypes.Add(ImageAspect.ASPECT_ID); item = MediaLibraryAccess.GetMediaItemById(context, itemId, necessaryMIATypes, optionalMIATypes); if (item == null) { throw new BadRequestException(String.Format("GetMediaInfo: No MediaItem found with id: {0}", itemId)); } } else { throw new BadRequestException(String.Format("GetMediaInfo: Media not found with id: {0}", itemId)); } // decide which type of media item we have info = await MediaAnalyzer.ParseMediaItemAsync(item); if (item.Aspects.ContainsKey(VideoAspect.ASPECT_ID)) { var videoAspect = item.GetAspect(VideoAspect.Metadata); var videoStreamAspect = item.GetAspect(VideoStreamAspect.Metadata); duration = Convert.ToInt64(videoStreamAspect.GetAttributeValue <long?>(VideoStreamAspect.ATTR_DURATION) ?? 0); bool interlaced = (videoStreamAspect.GetAttributeValue <string>(VideoStreamAspect.ATTR_VIDEO_TYPE) ?? "").ToLowerInvariant().Contains("interlaced"); foreach (var data in info.Metadata) { int edition = data.Key; int editionOffset = 0; if (edition >= 0) { editionOffset = (edition + 1) * ProfileMediaItem.EDITION_OFFSET; } if (info.IsVideo(edition)) { // Video WebVideoStream webVideoStream = new WebVideoStream(); webVideoStream.Codec = Convert.ToString(info.Video[edition].Codec); webVideoStream.DisplayAspectRatio = Convert.ToDecimal(info.Video[edition].AspectRatio ?? 0); webVideoStream.DisplayAspectRatioString = AspectRatioHelper.AspectRatioToString(Convert.ToDecimal(info.Video[edition].AspectRatio ?? 0)); webVideoStream.Height = Convert.ToInt32(info.Video[edition].Height ?? 0); webVideoStream.Width = Convert.ToInt32(info.Video[edition].Width ?? 0); webVideoStreams.Add(webVideoStream); webVideoStream.ID = info.Video[edition].StreamIndex + editionOffset; webVideoStream.Index = 0; webVideoStream.Interlaced = interlaced; container = info.Metadata[edition].VideoContainerType.ToString(); // Audio for (int i = 0; i < info.Audio[edition].Count; i++) { WebAudioStream webAudioStream = new WebAudioStream(); if (info.Audio[edition][i].Channels != null) { webAudioStream.Channels = info.Audio[edition][i].Channels.Value; } webAudioStream.Codec = info.Audio[edition][i].Codec.ToString(); webAudioStream.ID = info.Audio[edition][i].StreamIndex + editionOffset; webAudioStream.Index = i; if (info.Audio[edition][i].Language != null) { string language = info.Audio[edition][i].Language == string.Empty ? UNDEFINED : info.Audio[edition][i].Language; webAudioStream.Language = language; if (language != UNDEFINED) { webAudioStream.LanguageFull = new CultureInfo(language).EnglishName; if (item.HasEditions && item.Editions.Any(e => e.Value.SetNo == edition)) { webAudioStream.Title = item.Editions.First(e => e.Key == edition).Value.Name; } else if (item.GetPlayData(out var mime, out var mediaName)) { webAudioStream.Title = mediaName; } else { webAudioStream.Title = "?"; } if (string.IsNullOrEmpty(webAudioStream.Codec) == false) { webAudioStream.Title += webAudioStream.Title?.Length > 0 ? $" ({webAudioStream.Codec.ToUpperInvariant()})" : webAudioStream.Codec.ToUpperInvariant(); } } } webAudioStreams.Add(webAudioStream); } // Subtitles if (info.Subtitles[edition].Any()) { int firstMediaIdx = info.Subtitles[edition].Keys.First(); for (int i = 0; i < info.Subtitles[edition][firstMediaIdx].Count; i++) { WebSubtitleStream webSubtitleStream = new WebSubtitleStream(); webSubtitleStream.Filename = info.Subtitles[edition][firstMediaIdx][i].IsEmbedded ? "Embedded" : info.Subtitles[edition][firstMediaIdx][i].SourcePath; webSubtitleStream.ID = info.Subtitles[edition][firstMediaIdx][i].StreamIndex + editionOffset; webSubtitleStream.Index = i; if (info.Subtitles[edition][firstMediaIdx][i].Language != null) { string language = info.Subtitles[edition][firstMediaIdx][i].Language == string.Empty ? UNDEFINED : info.Subtitles[edition][firstMediaIdx][i].Language; webSubtitleStream.Language = language; webSubtitleStream.LanguageFull = language; if (language != UNDEFINED) { webSubtitleStream.LanguageFull = new CultureInfo(language).EnglishName; } } webSubtitleStreams.Add(webSubtitleStream); } } } } } else if (item.Aspects.ContainsKey(AudioAspect.ASPECT_ID)) { int edition = info.Metadata.Min(d => d.Key); if (info.IsAudio(edition)) { var audioAspect = item.GetAspect(AudioAspect.Metadata); duration = (long)audioAspect[AudioAspect.ATTR_DURATION]; container = info.Metadata[edition].AudioContainerType.ToString(); } } else if (item.Aspects.ContainsKey(ImageAspect.ASPECT_ID)) { int edition = info.Metadata.Min(d => d.Key); if (info.IsImage(edition)) { container = info.Metadata[edition].ImageContainerType.ToString(); } } WebMediaInfo webMediaInfo = new WebMediaInfo { Duration = duration * 1000, Container = container, VideoStreams = webVideoStreams, AudioStreams = webAudioStreams, SubtitleStreams = webSubtitleStreams }; return(webMediaInfo); }
public static async Task <WebBoolResult> ProcessAsync(IOwinContext context, string itemId, string clientDescription, string identifier, WebMediaType type, int?idleTimeout) { if (itemId == null) { throw new BadRequestException("InitStream: itemId is null"); } if (clientDescription == null) { throw new BadRequestException("InitStream: clientDescription is null"); } if (identifier == null) { throw new BadRequestException("InitStream: identifier is null"); } StreamItem streamItem = new StreamItem { ItemType = type, ClientDescription = clientDescription, IdleTimeout = idleTimeout ?? -1, ClientIp = context.Request.RemoteIpAddress }; MediaItem mediaItem = new LiveTvMediaItem(Guid.Empty); if (streamItem.ItemType == WebMediaType.TV || streamItem.ItemType == WebMediaType.Radio) { int channelIdInt; if (!int.TryParse(itemId, out channelIdInt)) { throw new BadRequestException(string.Format("InitStream: Couldn't convert channelId to int: {0}", itemId)); } streamItem.Title = "Live TV"; if (streamItem.ItemType == WebMediaType.Radio) { streamItem.Title = "Live Radio"; } streamItem.LiveChannelId = channelIdInt; var info = await MediaAnalyzer.ParseChannelStreamAsync(channelIdInt, (LiveTvMediaItem)mediaItem); if (info == null) { throw new BadRequestException(string.Format("InitStream: Couldn't parse channel stream: {0}", channelIdInt)); } } else { Guid itemGuid; if (!Guid.TryParse(itemId, out itemGuid)) { throw new BadRequestException(string.Format("InitStream: Couldn't parse itemId: {0}", itemId)); } ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); ISet <Guid> optionalMIATypes = new HashSet <Guid>(); optionalMIATypes.Add(VideoAspect.ASPECT_ID); optionalMIATypes.Add(AudioAspect.ASPECT_ID); optionalMIATypes.Add(ImageAspect.ASPECT_ID); mediaItem = MediaLibraryAccess.GetMediaItemById(context, itemGuid, necessaryMIATypes, optionalMIATypes); if (mediaItem == null) { throw new NotFoundException(string.Format("InitStream: Couldn't init stream! No MediaItem found with id: {0}", itemId)); } streamItem.Title = mediaItem[MediaAspect.Metadata.AspectId][0].GetAttributeValue <string>(MediaAspect.ATTR_TITLE); } streamItem.RequestedMediaItem = mediaItem; // Add the stream to the stream controller bool result = await StreamControl.AddStreamItemAsync(identifier, streamItem); return(new WebBoolResult { Result = result }); }
public static async Task ProcessAsync(IOwinContext context, WebMediaType type, string id, int maxWidth, int maxHeight, string borders = null) { if (id == null) { throw new BadRequestException("GetImageResized: id is null"); } if (maxWidth == 0) { throw new BadRequestException("GetImageResized: maxWidth is null"); } if (maxHeight == 0) { throw new BadRequestException("GetImageResized: maxHeight is null"); } Guid idGuid; if (!Guid.TryParse(id, out idGuid)) { throw new BadRequestException(String.Format("GetImageResized: Couldn't parse if '{0}' to Guid", id)); } ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); necessaryMIATypes.Add(ImporterAspect.ASPECT_ID); necessaryMIATypes.Add(ImageAspect.ASPECT_ID); MediaItem item = MediaLibraryAccess.GetMediaItemById(context, idGuid, necessaryMIATypes, null); var resourcePathStr = item.PrimaryResources[item.ActiveResourceLocatorIndex].GetAttributeValue(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH); var resourcePath = ResourcePath.Deserialize(resourcePathStr.ToString()); var ra = GetResourceAccessor(resourcePath); IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor; if (fsra == null) { throw new InternalServerException("GetImage: failed to create IFileSystemResourceAccessor"); } // Resize ImageCache.CacheIdentifier identifier = ImageCache.GetIdentifier(idGuid, false, maxWidth, maxHeight, borders, 0, FanArtTypes.Undefined, FanArtMediaTypes.Image); byte[] resizedImage; if (ImageCache.TryGetImageFromCache(context, identifier, out resizedImage)) { Logger.Info("GetImageResized: Got image from cache"); } else { using (var resourceStream = fsra.OpenRead()) { byte[] buffer = new byte[resourceStream.Length]; resourceStream.Read(buffer, 0, Convert.ToInt32(resourceStream.Length)); resizedImage = Plugins.MP2Extended.WSS.Images.ResizeImage(buffer, maxWidth, maxHeight, borders); } // Add to cache if (ImageCache.AddImageToCache(context, resizedImage, identifier)) { Logger.Info("GetImageResized: Added image to cache"); } } using (var resourceStream = new MemoryStream(resizedImage)) { // HTTP/1.1 RFC2616 section 14.25 'If-Modified-Since' if (!string.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"])) { DateTime lastRequest = DateTime.Parse(context.Request.Headers["If-Modified-Since"]); if (lastRequest.CompareTo(fsra.LastChanged) <= 0) { context.Response.StatusCode = (int)HttpStatusCode.NotModified; } } // HTTP/1.1 RFC2616 section 14.29 'Last-Modified' context.Response.Headers["Last-Modified"] = fsra.LastChanged.ToUniversalTime().ToString("r"); string byteRangesSpecifier = context.Request.Headers["Range"]; IList <Range> ranges = ParseByteRanges(byteRangesSpecifier, resourceStream.Length); bool onlyHeaders = context.Request.Method == "HEAD" || context.Response.StatusCode == (int)HttpStatusCode.NotModified; if (ranges != null && ranges.Count > 0) { // We only support last range await SendRangeAsync(context, resourceStream, ranges[ranges.Count - 1], onlyHeaders); } else { await SendWholeFileAsync(context, resourceStream, onlyHeaders); } } }