PageRenderTime 20ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/MediaPortal/Incubator/MediaServer/ResourceAccess/DlnaResourceAccessUtils.cs

https://github.com/MediaPortal/MediaPortal-2
C# | 248 lines | 196 code | 26 blank | 26 comment | 41 complexity | acebf27618e74bde02c3b2aa453ba104 MD5 | raw file
  1. #region Copyright (C) 2007-2020 Team MediaPortal
  2. /*
  3. Copyright (C) 2007-2020 Team MediaPortal
  4. http://www.team-mediaportal.com
  5. This file is part of MediaPortal 2
  6. MediaPortal 2 is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. MediaPortal 2 is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with MediaPortal 2. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #endregion
  18. using System;
  19. using System.Net;
  20. using System.Net.Sockets;
  21. using System.Text.RegularExpressions;
  22. using MediaPortal.Common;
  23. using MediaPortal.Common.Logging;
  24. using MediaPortal.Common.MediaManagement;
  25. using MediaPortal.Common.ResourceAccess;
  26. using MediaPortal.Common.Services.ResourceAccess.Settings;
  27. using MediaPortal.Common.Settings;
  28. using MediaPortal.Extensions.MediaServer.DLNA;
  29. using MediaPortal.Extensions.MediaServer.Profiles;
  30. using MediaPortal.Utilities.Network;
  31. using MediaPortal.Common.MediaManagement.DefaultItemAspects;
  32. using MediaPortal.Extensions.TranscodingService.Interfaces;
  33. using MediaPortal.Extensions.TranscodingService.Interfaces.Helpers;
  34. using MediaPortal.Extensions.TranscodingService.Interfaces.Transcoding;
  35. using MediaPortal.Common.FanArt;
  36. namespace MediaPortal.Extensions.MediaServer.ResourceAccess
  37. {
  38. public static class DlnaResourceAccessUtils
  39. {
  40. /// <summary>
  41. /// Base HTTP path for resource access, e.g. "/GetDlnaResource".
  42. /// </summary>
  43. public const string RESOURCE_ACCESS_PATH = "/GetDlnaResource";
  44. public const string TV_CHANNEL_RESOURCE = "TV_CHANNEL_";
  45. public const string RADIO_CHANNEL_RESOURCE = "RADIO_CHANNEL_";
  46. /// <summary>
  47. /// Argument name for the resource path argument, e.g. "MediaItem".
  48. /// </summary>
  49. public const string RESOURCE_PATH_ARGUMENT_NAME = "ResourcePath";
  50. public const string SYNTAX = RESOURCE_ACCESS_PATH + "/[media item id]";
  51. public const int DEFAULT_IMAGE_SIZE = 160;
  52. public static string GetResourceUrl(string mediaItem, Guid clientId)
  53. {
  54. return RESOURCE_ACCESS_PATH + "/" + mediaItem + "?id=" + clientId.ToString();
  55. }
  56. public static bool ParseMediaItem(Uri resourceUri, out Guid mediaItemGuid)
  57. {
  58. mediaItemGuid = Guid.Empty;
  59. try
  60. {
  61. var r = Regex.Match(resourceUri.PathAndQuery, RESOURCE_ACCESS_PATH + @"\/([\w-]*)\/?");
  62. var mediaItem = r.Groups[1].Value;
  63. if (mediaItem.Contains("."))
  64. {
  65. mediaItem = mediaItem.Substring(0, mediaItem.IndexOf("."));
  66. }
  67. if (Guid.TryParse(mediaItem, out mediaItemGuid))
  68. {
  69. return true;
  70. }
  71. }
  72. catch (Exception e)
  73. {
  74. ServiceRegistration.Get<ILogger>().Warn("ParseMediaItem: Failed with input url {0}", e, resourceUri.OriginalString);
  75. }
  76. return false;
  77. }
  78. public static bool ParseRadioChannel(Uri resourceUri, out int radioChannel)
  79. {
  80. radioChannel = 0;
  81. try
  82. {
  83. var r = Regex.Match(resourceUri.PathAndQuery, RESOURCE_ACCESS_PATH + $@"\/{RADIO_CHANNEL_RESOURCE}([\w-]*)\/?");
  84. var channel = r.Groups[1].Value;
  85. if (int.TryParse(channel, out radioChannel))
  86. {
  87. return true;
  88. }
  89. }
  90. catch (Exception e)
  91. {
  92. ServiceRegistration.Get<ILogger>().Warn("ParseRadioChannel: Failed with input url {0}", e, resourceUri.OriginalString);
  93. }
  94. return false;
  95. }
  96. public static bool ParseTVChannel(Uri resourceUri, out int tvChannel)
  97. {
  98. tvChannel = 0;
  99. try
  100. {
  101. var r = Regex.Match(resourceUri.PathAndQuery, RESOURCE_ACCESS_PATH + $@"\/{TV_CHANNEL_RESOURCE}([\w-]*)\/?");
  102. var channel = r.Groups[1].Value;
  103. if (int.TryParse(channel, out tvChannel))
  104. {
  105. return true;
  106. }
  107. }
  108. catch (Exception e)
  109. {
  110. ServiceRegistration.Get<ILogger>().Warn("ParseTVChannel: Failed with input url {0}", e, resourceUri.OriginalString);
  111. }
  112. return false;
  113. }
  114. public static bool UseSoftCodedSubtitle(EndPointSettings client, out SubtitleCodec targetCodec, out string targetMime)
  115. {
  116. targetCodec = SubtitleCodec.Unknown;
  117. targetMime = "text/plain";
  118. if (client.Profile.MediaTranscoding?.SubtitleSettings?.SubtitleMode == SubtitleSupport.SoftCoded)
  119. {
  120. targetCodec = client.Profile.MediaTranscoding.SubtitleSettings.SubtitlesSupported[0].Format;
  121. if (string.IsNullOrEmpty(client.Profile.MediaTranscoding.SubtitleSettings.SubtitlesSupported[0].Mime) == false)
  122. targetMime = client.Profile.MediaTranscoding.SubtitleSettings.SubtitlesSupported[0].Mime;
  123. else
  124. targetMime = SubtitleHelper.GetSubtitleMime(targetCodec);
  125. return true;
  126. }
  127. return false;
  128. }
  129. private static IPAddress GetLocalIp()
  130. {
  131. ServerSettings settings = ServiceRegistration.Get<ISettingsManager>().Load<ServerSettings>();
  132. bool useIPv4 = settings.UseIPv4;
  133. bool useIPv6 = settings.UseIPv6;
  134. var host = Dns.GetHostEntry(Dns.GetHostName());
  135. foreach (var ip in host.AddressList)
  136. {
  137. if (IPAddress.IsLoopback(ip))
  138. continue;
  139. if (useIPv4 && ip.AddressFamily == AddressFamily.InterNetwork)
  140. return ip;
  141. if (useIPv6 && ip.AddressFamily == AddressFamily.InterNetworkV6)
  142. return ip;
  143. }
  144. return null;
  145. }
  146. public static bool IsSoftCodedSubtitleAvailable(DlnaMediaItem dlnaItem, EndPointSettings client)
  147. {
  148. if (client.Profile.MediaTranscoding.SubtitleSettings.SubtitleMode != SubtitleSupport.SoftCoded)
  149. {
  150. return false;
  151. }
  152. if (dlnaItem.IsTranscoded && dlnaItem.IsVideo)
  153. {
  154. VideoTranscoding video = (VideoTranscoding)dlnaItem.TranscodingParameter;
  155. return video?.SourceSubtitles.Count > 0;
  156. }
  157. else if (dlnaItem.IsVideo)
  158. {
  159. VideoTranscoding subtitleVideo = (VideoTranscoding)dlnaItem.SubtitleTranscodingParameter;
  160. if (subtitleVideo?.SourceSubtitles.Count > 0)
  161. return true;
  162. return dlnaItem.Subtitles.Count > 0;
  163. }
  164. return false;
  165. }
  166. public static string GetFanArtMediaType(MediaItem item)
  167. {
  168. string mediaType = FanArtMediaTypes.Undefined;
  169. if (item.Aspects.ContainsKey(ImageAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.Image;
  170. else if (item.Aspects.ContainsKey(MovieAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.Movie;
  171. else if (item.Aspects.ContainsKey(MovieCollectionAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.MovieCollection;
  172. else if (item.Aspects.ContainsKey(SeriesAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.Series;
  173. else if (item.Aspects.ContainsKey(SeasonAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.SeriesSeason;
  174. else if (item.Aspects.ContainsKey(AudioAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.Audio;
  175. else if (item.Aspects.ContainsKey(AudioAlbumAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.Album;
  176. else if (item.Aspects.ContainsKey(EpisodeAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.Episode;
  177. else if (item.Aspects.ContainsKey(CharacterAspect.ASPECT_ID)) mediaType = FanArtMediaTypes.Character;
  178. return mediaType;
  179. }
  180. public static string GetThumbnailBaseURL(Guid mediaItemId, EndPointSettings client, string fanartType = null)
  181. {
  182. string mediaType = fanartType ?? FanArtMediaTypes.Undefined;
  183. // Using MP2's FanArtService provides access to all kind of resources, thumbnails from ML and also local fanart from filesystem
  184. string url = string.Format("{0}/FanartService?mediatype={1}&fanarttype={2}&name={3}&width={4}&height={5}",
  185. GetBaseResourceURL(), mediaType, FanArtTypes.Thumbnail, mediaItemId,
  186. client.Profile?.Settings.Thumbnails.MaxWidth ?? DEFAULT_IMAGE_SIZE, client.Profile?.Settings.Thumbnails.MaxHeight ?? DEFAULT_IMAGE_SIZE);
  187. return url;
  188. }
  189. public static string GetChannelLogoBaseURL(string channelName, EndPointSettings client, bool isTV)
  190. {
  191. string mediaType = isTV ? FanArtMediaTypes.ChannelTv : FanArtMediaTypes.ChannelRadio;
  192. string url = string.Format("{0}/FanartService?mediatype={1}&fanarttype={2}l&name={3}&width={4}&height={5}",
  193. GetBaseResourceURL(), mediaType, FanArtTypes.Thumbnail, WebUtility.UrlEncode(channelName),
  194. client.Profile?.Settings.Thumbnails.MaxWidth ?? DEFAULT_IMAGE_SIZE, client.Profile?.Settings.Thumbnails.MaxHeight ?? DEFAULT_IMAGE_SIZE);
  195. return url;
  196. }
  197. public static string GetSubtitleBaseURL(Guid mediaItemId, EndPointSettings client, out string subMime, out string subExtension)
  198. {
  199. SubtitleCodec codec = SubtitleCodec.Unknown;
  200. subMime = null;
  201. subExtension = null;
  202. if (UseSoftCodedSubtitle(client, out codec, out subMime) == true)
  203. {
  204. subExtension = SubtitleHelper.GetSubtitleExtension(codec);
  205. string subType = codec.ToString();
  206. return string.Format(GetBaseResourceURL()
  207. + GetResourceUrl(mediaItemId.ToString(), client.ClientId)
  208. + "&aspect=SUBTITLE&type={0}&file=subtitle.{1}", subType, subExtension);
  209. }
  210. return null;
  211. }
  212. public static string GetBaseResourceURL()
  213. {
  214. var rs = ServiceRegistration.Get<IResourceServer>();
  215. return rs.GetServiceUrl(GetLocalIp());
  216. }
  217. }
  218. }