LegacyStreamInfo.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using Jellyfin.Data.Enums;
  6. using Jellyfin.Extensions;
  7. using MediaBrowser.Model.Dlna;
  8. using MediaBrowser.Model.Dto;
  9. namespace Jellyfin.Model.Tests.Dlna;
  10. public class LegacyStreamInfo : StreamInfo
  11. {
  12. public LegacyStreamInfo(Guid itemId, DlnaProfileType mediaType)
  13. {
  14. ItemId = itemId;
  15. MediaType = mediaType;
  16. }
  17. /// <summary>
  18. /// The 10.6 ToUrl code from StreamInfo.cs with which to compare new version.
  19. /// </summary>
  20. /// <param name="baseUrl">The base url to use.</param>
  21. /// <param name="accessToken">The Access token.</param>
  22. /// <returns>A url.</returns>
  23. public string ToUrl_Original(string baseUrl, string? accessToken)
  24. {
  25. ArgumentException.ThrowIfNullOrEmpty(baseUrl);
  26. var list = new List<string>();
  27. foreach (NameValuePair pair in BuildParams(this, accessToken))
  28. {
  29. if (string.IsNullOrEmpty(pair.Value))
  30. {
  31. continue;
  32. }
  33. // Try to keep the url clean by omitting defaults
  34. if (string.Equals(pair.Name, "StartTimeTicks", StringComparison.OrdinalIgnoreCase)
  35. && string.Equals(pair.Value, "0", StringComparison.OrdinalIgnoreCase))
  36. {
  37. continue;
  38. }
  39. if (string.Equals(pair.Name, "SubtitleStreamIndex", StringComparison.OrdinalIgnoreCase)
  40. && string.Equals(pair.Value, "-1", StringComparison.OrdinalIgnoreCase))
  41. {
  42. continue;
  43. }
  44. if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase)
  45. && string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase))
  46. {
  47. continue;
  48. }
  49. var encodedValue = pair.Value.Replace(" ", "%20", StringComparison.Ordinal);
  50. list.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", pair.Name, encodedValue));
  51. }
  52. string queryString = string.Join('&', list);
  53. return GetUrl(baseUrl, queryString);
  54. }
  55. private string GetUrl(string baseUrl, string queryString)
  56. {
  57. ArgumentException.ThrowIfNullOrEmpty(baseUrl);
  58. string extension = string.IsNullOrEmpty(Container) ? string.Empty : "." + Container;
  59. baseUrl = baseUrl.TrimEnd('/');
  60. if (MediaType == DlnaProfileType.Audio)
  61. {
  62. if (SubProtocol == MediaStreamProtocol.hls)
  63. {
  64. return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
  65. }
  66. return string.Format(CultureInfo.InvariantCulture, "{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
  67. }
  68. if (SubProtocol == MediaStreamProtocol.hls)
  69. {
  70. return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, queryString);
  71. }
  72. return string.Format(CultureInfo.InvariantCulture, "{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, queryString);
  73. }
  74. private static List<NameValuePair> BuildParams(StreamInfo item, string? accessToken)
  75. {
  76. List<NameValuePair> list = [];
  77. string audioCodecs = item.AudioCodecs.Count == 0 ?
  78. string.Empty :
  79. string.Join(',', item.AudioCodecs);
  80. string videoCodecs = item.VideoCodecs.Count == 0 ?
  81. string.Empty :
  82. string.Join(',', item.VideoCodecs);
  83. list.Add(new NameValuePair("DeviceProfileId", item.DeviceProfileId ?? string.Empty));
  84. list.Add(new NameValuePair("DeviceId", item.DeviceId ?? string.Empty));
  85. list.Add(new NameValuePair("MediaSourceId", item.MediaSourceId ?? string.Empty));
  86. list.Add(new NameValuePair("Static", item.IsDirectStream.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
  87. list.Add(new NameValuePair("VideoCodec", videoCodecs));
  88. list.Add(new NameValuePair("AudioCodec", audioCodecs));
  89. list.Add(new NameValuePair("AudioStreamIndex", item.AudioStreamIndex.HasValue ? item.AudioStreamIndex.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  90. list.Add(new NameValuePair("SubtitleStreamIndex", item.SubtitleStreamIndex.HasValue && (item.AlwaysBurnInSubtitleWhenTranscoding || item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External) ? item.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  91. list.Add(new NameValuePair("VideoBitrate", item.VideoBitrate.HasValue ? item.VideoBitrate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  92. list.Add(new NameValuePair("AudioBitrate", item.AudioBitrate.HasValue ? item.AudioBitrate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  93. list.Add(new NameValuePair("AudioSampleRate", item.AudioSampleRate.HasValue ? item.AudioSampleRate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  94. list.Add(new NameValuePair("MaxFramerate", item.MaxFramerate.HasValue ? item.MaxFramerate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  95. list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? item.MaxWidth.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  96. list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? item.MaxHeight.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  97. long startPositionTicks = item.StartPositionTicks;
  98. if (item.SubProtocol == MediaStreamProtocol.hls)
  99. {
  100. list.Add(new NameValuePair("StartTimeTicks", string.Empty));
  101. list.Add(new NameValuePair("SegmentContainer", item.Container ?? string.Empty));
  102. if (item.SegmentLength.HasValue)
  103. {
  104. list.Add(new NameValuePair("SegmentLength", item.SegmentLength.Value.ToString(CultureInfo.InvariantCulture)));
  105. }
  106. if (item.MinSegments.HasValue)
  107. {
  108. list.Add(new NameValuePair("MinSegments", item.MinSegments.Value.ToString(CultureInfo.InvariantCulture)));
  109. }
  110. list.Add(new NameValuePair("BreakOnNonKeyFrames", item.BreakOnNonKeyFrames.ToString(CultureInfo.InvariantCulture)));
  111. }
  112. else
  113. {
  114. list.Add(new NameValuePair("StartTimeTicks", startPositionTicks.ToString(CultureInfo.InvariantCulture)));
  115. }
  116. list.Add(new NameValuePair("PlaySessionId", item.PlaySessionId ?? string.Empty));
  117. list.Add(new NameValuePair("ApiKey", accessToken ?? string.Empty));
  118. string? liveStreamId = item.MediaSource?.LiveStreamId;
  119. list.Add(new NameValuePair("LiveStreamId", liveStreamId ?? string.Empty));
  120. if (!item.IsDirectStream)
  121. {
  122. if (item.RequireNonAnamorphic)
  123. {
  124. list.Add(new NameValuePair("RequireNonAnamorphic", item.RequireNonAnamorphic.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
  125. }
  126. list.Add(new NameValuePair("TranscodingMaxAudioChannels", item.TranscodingMaxAudioChannels.HasValue ? item.TranscodingMaxAudioChannels.Value.ToString(CultureInfo.InvariantCulture) : string.Empty));
  127. if (item.EnableSubtitlesInManifest)
  128. {
  129. list.Add(new NameValuePair("EnableSubtitlesInManifest", item.EnableSubtitlesInManifest.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
  130. }
  131. if (item.EnableMpegtsM2TsMode)
  132. {
  133. list.Add(new NameValuePair("EnableMpegtsM2TsMode", item.EnableMpegtsM2TsMode.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
  134. }
  135. if (item.EstimateContentLength)
  136. {
  137. list.Add(new NameValuePair("EstimateContentLength", item.EstimateContentLength.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
  138. }
  139. if (item.TranscodeSeekInfo != TranscodeSeekInfo.Auto)
  140. {
  141. list.Add(new NameValuePair("TranscodeSeekInfo", item.TranscodeSeekInfo.ToString().ToLowerInvariant()));
  142. }
  143. if (item.CopyTimestamps)
  144. {
  145. list.Add(new NameValuePair("CopyTimestamps", item.CopyTimestamps.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
  146. }
  147. list.Add(new NameValuePair("RequireAvc", item.RequireAvc.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
  148. list.Add(new NameValuePair("EnableAudioVbrEncoding", item.EnableAudioVbrEncoding.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
  149. }
  150. list.Add(new NameValuePair("Tag", item.MediaSource?.ETag ?? string.Empty));
  151. string subtitleCodecs = item.SubtitleCodecs.Count == 0 ? string.Empty : string.Join(",", item.SubtitleCodecs);
  152. list.Add(new NameValuePair("SubtitleCodec", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Embed ? subtitleCodecs : string.Empty));
  153. list.Add(new NameValuePair("SubtitleMethod", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleDeliveryMethod.ToString() : string.Empty));
  154. foreach (var pair in item.StreamOptions)
  155. {
  156. if (string.IsNullOrEmpty(pair.Value))
  157. {
  158. continue;
  159. }
  160. // strip spaces to avoid having to encode h264 profile names
  161. list.Add(new NameValuePair(pair.Key, pair.Value.Replace(" ", string.Empty, StringComparison.Ordinal)));
  162. }
  163. var transcodeReasonsValues = item.TranscodeReasons.GetUniqueFlags().ToArray();
  164. if (!item.IsDirectStream && transcodeReasonsValues.Length > 0)
  165. {
  166. list.Add(new NameValuePair("TranscodeReasons", item.TranscodeReasons.ToString()));
  167. }
  168. return list;
  169. }
  170. }