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 async Task <LiveTvMediaItem> InitializeChannel(int channelId) { IsLive = true; MediaItemId = Guid.Empty; MediaItemTitle = "Channel " + channelId; LiveTvMediaItem item = new LiveTvMediaItem(Guid.Empty); var info = await MediaAnalyzer.ParseChannelStreamAsync(channelId, item); if (info == null) { Logger.Warn("MediaServer: Channel {0} couldn't be analyzed", channelId); return(null); } if (item.Aspects.ContainsKey(AudioAspect.ASPECT_ID)) { IsAudio = true; } else if (item.Aspects.ContainsKey(VideoAspect.ASPECT_ID)) { IsVideo = true; } else { Logger.Warn("MediaServer: Channel {0} contains no required aspect information", channelId); return(null); } if (MediaItemAspect.TryGetAttribute(item.Aspects, MediaAspect.ATTR_TITLE, out string title)) { MediaItemTitle = title; } _edition = info.Metadata.Min(m => m.Key); string transcodeId = Guid.NewGuid().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 (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) { TranscodingParameter = TranscodeProfileManager.GetLiveVideoTranscoding(info, Client.PreferredAudioLanguages, transcodeId); } else if (IsAudio) { TranscodingParameter = TranscodeProfileManager.GetLiveAudioTranscoding(info, transcodeId); } } AssignDlnaMetadata(info, _edition); return(item); }
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); }