public async Task Initialize(Guid?userId, MediaItem item, int?edition, int?audioId = null, int?subtitleId = null) { MediaItemId = item.MediaItemId; var info = await MediaAnalyzer.ParseMediaItemAsync(item); if (info == null) { Logger.Warn("MP2Extended: Mediaitem {0} couldn't be analyzed", item.MediaItemId); return; } int? audioStreamId = null; List <string> preferredAudioLang = new List <string>(); List <string> preferredSubtitleLang = new List <string>(); await ResourceAccessUtils.AddPreferredLanguagesAsync(userId, preferredAudioLang, preferredSubtitleLang); if (audioId.HasValue) { if (audioId.Value >= EDITION_OFFSET) { edition = (audioId.Value / EDITION_OFFSET) - 1; audioStreamId = audioId.Value - ((audioId.Value / EDITION_OFFSET) * EDITION_OFFSET); } else { audioStreamId = audioId; } } if (item.HasEditions && !edition.HasValue) { //Find edition with best matching audio that doesn't require transcoding int currentPriority = -1; bool currentRequiresTranscoding = false; foreach (var checkEdition in info.Metadata.Keys) { for (int idx = 0; idx < info.Audio[checkEdition].Count; idx++) { VideoTranscoding video = TranscodeProfileManager.GetVideoTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID, info, checkEdition, preferredAudioLang, IsLive, ""); bool requiresTranscoding = video != null; for (int priority = 0; priority < preferredAudioLang.Count; priority++) { if (preferredAudioLang[priority].Equals(info.Audio[checkEdition][idx].Language, StringComparison.InvariantCultureIgnoreCase) == true) { if (currentPriority == -1 || priority < currentPriority || (!requiresTranscoding && currentRequiresTranscoding && priority == currentPriority)) { currentPriority = priority; currentRequiresTranscoding = requiresTranscoding; audioStreamId = info.Audio[checkEdition][idx].StreamIndex; _edition = checkEdition; } } } } } } else { //Assign first edition _edition = info.Metadata.Min(m => m.Key); } if (item.Aspects.ContainsKey(AudioAspect.ASPECT_ID)) { IsAudio = true; } else if (item.Aspects.ContainsKey(ImageAspect.ASPECT_ID)) { IsImage = true; } else if (item.Aspects.ContainsKey(VideoAspect.ASPECT_ID)) { IsVideo = true; } else { Logger.Warn("MP2Extended: Mediaitem {0} contains no required aspect information", item.MediaItemId); return; } string transcodeId = item.MediaItemId.ToString() + "_" + Profile.ID; if (IsLive) { transcodeId = Guid.NewGuid().ToString() + "_" + Profile.ID; } if (MP2Extended.Settings.TranscodingAllowed) { if (IsAudio) { AudioTranscoding audio = TranscodeProfileManager.GetAudioTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID, info, _edition, IsLive, transcodeId); TranscodingParameter = audio; } else if (IsImage) { ImageTranscoding image = TranscodeProfileManager.GetImageTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID, info, _edition, transcodeId); TranscodingParameter = image; } else if (IsVideo) { VideoTranscoding video; if (audioStreamId.HasValue) { video = TranscodeProfileManager.GetVideoTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID, info, _edition, audioStreamId.Value, subtitleId, IsLive, transcodeId); } else { video = TranscodeProfileManager.GetVideoTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID, info, _edition, preferredAudioLang, IsLive, transcodeId); } if (video != null) { if (video.TargetVideoContainer == VideoContainer.Hls) { IsSegmented = true; } if (MP2Extended.Settings.HardcodedSubtitlesAllowed == false) { video.TargetSubtitleSupport = SubtitleSupport.None; } } TranscodingParameter = video; } } if (TranscodingParameter == null) { if (IsLive) { if (IsVideo) { if (audioStreamId.HasValue) { TranscodingParameter = TranscodeProfileManager.GetLiveVideoTranscoding(info, audioStreamId.Value, transcodeId); } else { TranscodingParameter = TranscodeProfileManager.GetLiveVideoTranscoding(info, preferredAudioLang, transcodeId); } } else if (IsAudio) { TranscodingParameter = TranscodeProfileManager.GetLiveAudioTranscoding(info, transcodeId); } } else if (IsVideo) { VideoTranscoding video = TranscodeProfileManager.GetVideoSubtitleTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID, info, _edition, IsLive, transcodeId); if (video != null) { if (video.TargetVideoContainer == VideoContainer.Hls) { IsSegmented = true; } if (MP2Extended.Settings.HardcodedSubtitlesAllowed == false) { video.TargetSubtitleSupport = SubtitleSupport.None; } } TranscodingParameter = video; } } AssignWebMetadata(info, _edition); }
public async Task Initialize(MediaItem item, int?edition = null) { IsLive = false; MediaItemId = item.MediaItemId; if (MediaItemAspect.TryGetAttribute(item.Aspects, MediaAspect.ATTR_TITLE, out string title)) { MediaItemTitle = title; } else { MediaItemTitle = "?"; } var info = await MediaAnalyzer.ParseMediaItemAsync(item, edition); if (info == null) { Logger.Warn("MediaServer: Mediaitem {0} couldn't be analyzed", item.MediaItemId); return; } if (item.Aspects.ContainsKey(AudioAspect.ASPECT_ID)) { IsAudio = true; } else if (item.Aspects.ContainsKey(ImageAspect.ASPECT_ID)) { IsImage = true; } else if (item.Aspects.ContainsKey(VideoAspect.ASPECT_ID)) { IsVideo = true; } else { Logger.Warn("MediaServer: Mediaitem {0} contains no required aspect information", item.MediaItemId); return; } if (item.HasEditions && !edition.HasValue) { //Find edition with best matching audio that doesn't require transcoding int currentPriority = -1; bool currentRequiresTranscoding = false; var preferredAudioLang = Client.PreferredAudioLanguages.ToList(); foreach (var checkEdition in info.Metadata.Keys) { for (int idx = 0; idx < info.Audio[checkEdition].Count; idx++) { VideoTranscoding video = TranscodeProfileManager.GetVideoTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Client.Profile.ID, info, checkEdition, Client.PreferredAudioLanguages, IsLive, ""); bool requiresTranscoding = video != null; for (int priority = 0; priority < preferredAudioLang.Count; priority++) { if (preferredAudioLang[priority].Equals(info.Audio[checkEdition][idx].Language, StringComparison.InvariantCultureIgnoreCase) == true) { if (currentPriority == -1 || priority < currentPriority || (!requiresTranscoding && currentRequiresTranscoding && priority == currentPriority)) { currentPriority = priority; currentRequiresTranscoding = requiresTranscoding; edition = checkEdition; } } } } } } if (!edition.HasValue) { //Assign first edition _edition = info.Metadata.Min(m => m.Key); } else { _edition = edition.Value; } string transcodeId = item.MediaItemId.ToString() + "_" + Client.Profile.ID; if (MediaServerPlugin.Settings.TranscodingAllowed) { if (IsAudio) { AudioTranscoding audio = TranscodeProfileManager.GetAudioTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Client.Profile.ID, info, _edition, IsLive, transcodeId); TranscodingParameter = audio; } else if (IsImage) { ImageTranscoding image = TranscodeProfileManager.GetImageTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Client.Profile.ID, info, _edition, transcodeId); TranscodingParameter = image; } else if (IsVideo) { VideoTranscoding video = TranscodeProfileManager.GetVideoTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Client.Profile.ID, info, _edition, Client.PreferredAudioLanguages, IsLive, transcodeId); if (video != null) { if (video.TargetVideoContainer == VideoContainer.Hls) { IsSegmented = true; } if (MediaServerPlugin.Settings.HardcodedSubtitlesAllowed == false) { video.TargetSubtitleSupport = SubtitleSupport.None; } } TranscodingParameter = video; } } if (TranscodingParameter == null) { if (IsVideo) { VideoTranscoding video = TranscodeProfileManager.GetVideoSubtitleTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Client.Profile.ID, info, _edition, IsLive, transcodeId); if (video != null) { if (video.TargetVideoContainer == VideoContainer.Hls) { IsSegmented = true; } if (MediaServerPlugin.Settings.HardcodedSubtitlesAllowed == false) { video.TargetSubtitleSupport = SubtitleSupport.None; } } SubtitleTranscodingParameter = video; } } //Assign some extra meta data DateTime?aspectDate; if (MediaItemAspect.TryGetAttribute(item.Aspects, ImporterAspect.ATTR_DATEADDED, out aspectDate)) { MediaItemAddedDate = aspectDate; } if (MediaItemAspect.TryGetAttribute(item.Aspects, MediaAspect.ATTR_RECORDINGTIME, out aspectDate)) { MediaItemRecordingDate = aspectDate; } if (IsVideo) { if (MediaItemAspect.TryGetAspects(item.Aspects, VideoStreamAspect.Metadata, out var videoStreamAspects)) { MediaItemWidth = videoStreamAspects.FirstOrDefault()?.GetAttributeValue <int?>(VideoStreamAspect.ATTR_WIDTH); MediaItemHeight = videoStreamAspects.FirstOrDefault()?.GetAttributeValue <int?>(VideoStreamAspect.ATTR_HEIGHT); } } else if (IsImage) { if (MediaItemAspect.TryGetAspect(item.Aspects, ImageAspect.Metadata, out var imageAspect)) { MediaItemImageMake = imageAspect?.GetAttributeValue <string>(ImageAspect.ATTR_MAKE); MediaItemImageMake = imageAspect?.GetAttributeValue <string>(ImageAspect.ATTR_MODEL); MediaItemImageMake = imageAspect?.GetAttributeValue <string>(ImageAspect.ATTR_FNUMBER); MediaItemImageMake = imageAspect?.GetAttributeValue <string>(ImageAspect.ATTR_ISO_SPEED); MediaItemImageMake = imageAspect?.GetAttributeValue <string>(ImageAspect.ATTR_EXPOSURE_TIME); MediaItemImageOrientation = imageAspect?.GetAttributeValue <int?>(ImageAspect.ATTR_ORIENTATION); MediaItemWidth = imageAspect?.GetAttributeValue <int?>(ImageAspect.ATTR_WIDTH); MediaItemHeight = imageAspect?.GetAttributeValue <int?>(ImageAspect.ATTR_HEIGHT); } } AssignDlnaMetadata(info, _edition); }
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); }