MediaStream.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. using System;
  2. using System.Collections.Generic;
  3. using MediaBrowser.Model.Dlna;
  4. using MediaBrowser.Model.Extensions;
  5. using System.Diagnostics;
  6. using MediaBrowser.Model.MediaInfo;
  7. namespace MediaBrowser.Model.Entities
  8. {
  9. /// <summary>
  10. /// Class MediaStream
  11. /// </summary>
  12. [DebuggerDisplay("StreamType = {Type}")]
  13. public class MediaStream
  14. {
  15. /// <summary>
  16. /// Gets or sets the codec.
  17. /// </summary>
  18. /// <value>The codec.</value>
  19. public string Codec { get; set; }
  20. /// <summary>
  21. /// Gets or sets the codec tag.
  22. /// </summary>
  23. /// <value>The codec tag.</value>
  24. public string CodecTag { get; set; }
  25. /// <summary>
  26. /// Gets or sets the language.
  27. /// </summary>
  28. /// <value>The language.</value>
  29. public string Language { get; set; }
  30. /// <summary>
  31. /// Gets or sets the comment.
  32. /// </summary>
  33. /// <value>The comment.</value>
  34. public string Comment { get; set; }
  35. public string TimeBase { get; set; }
  36. public string CodecTimeBase { get; set; }
  37. public string Title { get; set; }
  38. public string DisplayTitle
  39. {
  40. get
  41. {
  42. if (Type == MediaStreamType.Audio)
  43. {
  44. if (!string.IsNullOrEmpty(Title))
  45. {
  46. return AddLanguageIfNeeded(Title);
  47. }
  48. List<string> attributes = new List<string>();
  49. if (!string.IsNullOrEmpty(Language))
  50. {
  51. attributes.Add(StringHelper.FirstToUpper(Language));
  52. }
  53. if (!string.IsNullOrEmpty(Codec) && !StringHelper.EqualsIgnoreCase(Codec, "dca"))
  54. {
  55. attributes.Add(AudioCodec.GetFriendlyName(Codec));
  56. }
  57. else if (!string.IsNullOrEmpty(Profile) && !StringHelper.EqualsIgnoreCase(Profile, "lc"))
  58. {
  59. attributes.Add(Profile);
  60. }
  61. if (!string.IsNullOrEmpty(ChannelLayout))
  62. {
  63. attributes.Add(ChannelLayout);
  64. }
  65. else if (Channels.HasValue)
  66. {
  67. attributes.Add(StringHelper.ToStringCultureInvariant(Channels.Value) + " ch");
  68. }
  69. if (IsDefault)
  70. {
  71. attributes.Add("Default");
  72. }
  73. return string.Join(" ", attributes.ToArray(attributes.Count));
  74. }
  75. if (Type == MediaStreamType.Video)
  76. {
  77. List<string> attributes = new List<string>();
  78. var resolutionText = GetResolutionText();
  79. if (!string.IsNullOrEmpty(resolutionText))
  80. {
  81. attributes.Add(resolutionText);
  82. }
  83. if (!string.IsNullOrEmpty(Codec))
  84. {
  85. attributes.Add(Codec.ToUpper());
  86. }
  87. return string.Join(" ", attributes.ToArray(attributes.Count));
  88. }
  89. if (Type == MediaStreamType.Subtitle)
  90. {
  91. if (!string.IsNullOrEmpty(Title))
  92. {
  93. return AddLanguageIfNeeded(Title);
  94. }
  95. List<string> attributes = new List<string>();
  96. if (!string.IsNullOrEmpty(Language))
  97. {
  98. attributes.Add(StringHelper.FirstToUpper(Language));
  99. }
  100. else
  101. {
  102. attributes.Add("Und");
  103. }
  104. if (IsDefault)
  105. {
  106. attributes.Add("Default");
  107. }
  108. if (IsForced)
  109. {
  110. attributes.Add("Forced");
  111. }
  112. string name = string.Join(" ", attributes.ToArray(attributes.Count));
  113. return name;
  114. }
  115. if (Type == MediaStreamType.Video)
  116. {
  117. }
  118. return null;
  119. }
  120. }
  121. private string GetResolutionText()
  122. {
  123. var i = this;
  124. if (i.Width.HasValue)
  125. {
  126. if (i.Width >= 3800)
  127. {
  128. return "4K";
  129. }
  130. if (i.Width >= 2500)
  131. {
  132. if (i.IsInterlaced)
  133. {
  134. return "1440I";
  135. }
  136. return "1440P";
  137. }
  138. if (i.Width >= 1900)
  139. {
  140. if (i.IsInterlaced)
  141. {
  142. return "1080I";
  143. }
  144. return "1080P";
  145. }
  146. if (i.Width >= 1260)
  147. {
  148. if (i.IsInterlaced)
  149. {
  150. return "720I";
  151. }
  152. return "720P";
  153. }
  154. if (i.Width >= 700)
  155. {
  156. if (i.IsInterlaced)
  157. {
  158. return "480I";
  159. }
  160. return "480P";
  161. }
  162. }
  163. return null;
  164. }
  165. private string AddLanguageIfNeeded(string title)
  166. {
  167. if (!string.IsNullOrEmpty(Language) &&
  168. !string.Equals(Language, "und", StringComparison.OrdinalIgnoreCase) &&
  169. !IsLanguageInTitle(title, Language))
  170. {
  171. title = StringHelper.FirstToUpper(Language) + " " + title;
  172. }
  173. return title;
  174. }
  175. private bool IsLanguageInTitle(string title, string language)
  176. {
  177. if (title.IndexOf(Language, StringComparison.OrdinalIgnoreCase) != -1)
  178. {
  179. return true;
  180. }
  181. return false;
  182. }
  183. public string NalLengthSize { get; set; }
  184. /// <summary>
  185. /// Gets or sets a value indicating whether this instance is interlaced.
  186. /// </summary>
  187. /// <value><c>true</c> if this instance is interlaced; otherwise, <c>false</c>.</value>
  188. public bool IsInterlaced { get; set; }
  189. public bool? IsAVC { get; set; }
  190. /// <summary>
  191. /// Gets or sets the channel layout.
  192. /// </summary>
  193. /// <value>The channel layout.</value>
  194. public string ChannelLayout { get; set; }
  195. /// <summary>
  196. /// Gets or sets the bit rate.
  197. /// </summary>
  198. /// <value>The bit rate.</value>
  199. public int? BitRate { get; set; }
  200. /// <summary>
  201. /// Gets or sets the bit depth.
  202. /// </summary>
  203. /// <value>The bit depth.</value>
  204. public int? BitDepth { get; set; }
  205. /// <summary>
  206. /// Gets or sets the reference frames.
  207. /// </summary>
  208. /// <value>The reference frames.</value>
  209. public int? RefFrames { get; set; }
  210. /// <summary>
  211. /// Gets or sets the length of the packet.
  212. /// </summary>
  213. /// <value>The length of the packet.</value>
  214. public int? PacketLength { get; set; }
  215. /// <summary>
  216. /// Gets or sets the channels.
  217. /// </summary>
  218. /// <value>The channels.</value>
  219. public int? Channels { get; set; }
  220. /// <summary>
  221. /// Gets or sets the sample rate.
  222. /// </summary>
  223. /// <value>The sample rate.</value>
  224. public int? SampleRate { get; set; }
  225. /// <summary>
  226. /// Gets or sets a value indicating whether this instance is default.
  227. /// </summary>
  228. /// <value><c>true</c> if this instance is default; otherwise, <c>false</c>.</value>
  229. public bool IsDefault { get; set; }
  230. /// <summary>
  231. /// Gets or sets a value indicating whether this instance is forced.
  232. /// </summary>
  233. /// <value><c>true</c> if this instance is forced; otherwise, <c>false</c>.</value>
  234. public bool IsForced { get; set; }
  235. /// <summary>
  236. /// Gets or sets the height.
  237. /// </summary>
  238. /// <value>The height.</value>
  239. public int? Height { get; set; }
  240. /// <summary>
  241. /// Gets or sets the width.
  242. /// </summary>
  243. /// <value>The width.</value>
  244. public int? Width { get; set; }
  245. /// <summary>
  246. /// Gets or sets the average frame rate.
  247. /// </summary>
  248. /// <value>The average frame rate.</value>
  249. public float? AverageFrameRate { get; set; }
  250. /// <summary>
  251. /// Gets or sets the real frame rate.
  252. /// </summary>
  253. /// <value>The real frame rate.</value>
  254. public float? RealFrameRate { get; set; }
  255. /// <summary>
  256. /// Gets or sets the profile.
  257. /// </summary>
  258. /// <value>The profile.</value>
  259. public string Profile { get; set; }
  260. /// <summary>
  261. /// Gets or sets the type.
  262. /// </summary>
  263. /// <value>The type.</value>
  264. public MediaStreamType Type { get; set; }
  265. /// <summary>
  266. /// Gets or sets the aspect ratio.
  267. /// </summary>
  268. /// <value>The aspect ratio.</value>
  269. public string AspectRatio { get; set; }
  270. /// <summary>
  271. /// Gets or sets the index.
  272. /// </summary>
  273. /// <value>The index.</value>
  274. public int Index { get; set; }
  275. /// <summary>
  276. /// Gets or sets the score.
  277. /// </summary>
  278. /// <value>The score.</value>
  279. public int? Score { get; set; }
  280. /// <summary>
  281. /// Gets or sets a value indicating whether this instance is external.
  282. /// </summary>
  283. /// <value><c>true</c> if this instance is external; otherwise, <c>false</c>.</value>
  284. public bool IsExternal { get; set; }
  285. /// <summary>
  286. /// Gets or sets the method.
  287. /// </summary>
  288. /// <value>The method.</value>
  289. public SubtitleDeliveryMethod? DeliveryMethod { get; set; }
  290. /// <summary>
  291. /// Gets or sets the delivery URL.
  292. /// </summary>
  293. /// <value>The delivery URL.</value>
  294. public string DeliveryUrl { get; set; }
  295. /// <summary>
  296. /// Gets or sets a value indicating whether this instance is external URL.
  297. /// </summary>
  298. /// <value><c>null</c> if [is external URL] contains no value, <c>true</c> if [is external URL]; otherwise, <c>false</c>.</value>
  299. public bool? IsExternalUrl { get; set; }
  300. public bool IsTextSubtitleStream
  301. {
  302. get
  303. {
  304. if (Type != MediaStreamType.Subtitle) return false;
  305. if (string.IsNullOrEmpty(Codec) && !IsExternal)
  306. {
  307. return false;
  308. }
  309. return IsTextFormat(Codec);
  310. }
  311. }
  312. public static bool IsTextFormat(string format)
  313. {
  314. string codec = format ?? string.Empty;
  315. // sub = external .sub file
  316. return StringHelper.IndexOfIgnoreCase(codec, "pgs") == -1 &&
  317. StringHelper.IndexOfIgnoreCase(codec, "dvd") == -1 &&
  318. StringHelper.IndexOfIgnoreCase(codec, "dvbsub") == -1 &&
  319. !StringHelper.EqualsIgnoreCase(codec, "sub") &&
  320. !StringHelper.EqualsIgnoreCase(codec, "dvb_subtitle");
  321. }
  322. public bool SupportsSubtitleConversionTo(string toCodec)
  323. {
  324. if (!IsTextSubtitleStream)
  325. {
  326. return false;
  327. }
  328. var fromCodec = Codec;
  329. // Can't convert from this
  330. if (StringHelper.EqualsIgnoreCase(fromCodec, "ass"))
  331. {
  332. return false;
  333. }
  334. if (StringHelper.EqualsIgnoreCase(fromCodec, "ssa"))
  335. {
  336. return false;
  337. }
  338. // Can't convert to this
  339. if (StringHelper.EqualsIgnoreCase(toCodec, "ass"))
  340. {
  341. return false;
  342. }
  343. if (StringHelper.EqualsIgnoreCase(toCodec, "ssa"))
  344. {
  345. return false;
  346. }
  347. return true;
  348. }
  349. /// <summary>
  350. /// Gets or sets a value indicating whether [supports external stream].
  351. /// </summary>
  352. /// <value><c>true</c> if [supports external stream]; otherwise, <c>false</c>.</value>
  353. public bool SupportsExternalStream { get; set; }
  354. /// <summary>
  355. /// Gets or sets the filename.
  356. /// </summary>
  357. /// <value>The filename.</value>
  358. public string Path { get; set; }
  359. /// <summary>
  360. /// Gets or sets the external identifier.
  361. /// </summary>
  362. /// <value>The external identifier.</value>
  363. public string ExternalId { get; set; }
  364. /// <summary>
  365. /// Gets or sets the pixel format.
  366. /// </summary>
  367. /// <value>The pixel format.</value>
  368. public string PixelFormat { get; set; }
  369. /// <summary>
  370. /// Gets or sets the level.
  371. /// </summary>
  372. /// <value>The level.</value>
  373. public double? Level { get; set; }
  374. /// <summary>
  375. /// Gets a value indicating whether this instance is anamorphic.
  376. /// </summary>
  377. /// <value><c>true</c> if this instance is anamorphic; otherwise, <c>false</c>.</value>
  378. public bool? IsAnamorphic { get; set; }
  379. }
  380. }