ContentFeatureBuilder.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using System;
  2. namespace MediaBrowser.Model.Dlna
  3. {
  4. public class ContentFeatureBuilder
  5. {
  6. private readonly DeviceProfile _profile;
  7. public ContentFeatureBuilder(DeviceProfile profile)
  8. {
  9. _profile = profile;
  10. }
  11. public string BuildAudioHeader(string container,
  12. string audioCodec,
  13. int? audioBitrate,
  14. int? audioSampleRate,
  15. int? audioChannels,
  16. bool isDirectStream,
  17. long? runtimeTicks,
  18. TranscodeSeekInfo transcodeSeekInfo)
  19. {
  20. // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
  21. var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo);
  22. // 0 = native, 1 = transcoded
  23. var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
  24. var flagValue = DlnaFlags.StreamingTransferMode |
  25. DlnaFlags.BackgroundTransferMode |
  26. DlnaFlags.DlnaV15;
  27. if (isDirectStream)
  28. {
  29. //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK;
  30. }
  31. else if (runtimeTicks.HasValue)
  32. {
  33. //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK;
  34. }
  35. var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}000000000000000000000000",
  36. Enum.Format(typeof(DlnaFlags), flagValue, "x"));
  37. var mediaProfile = _profile.GetAudioMediaProfile(container, audioCodec);
  38. var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn;
  39. if (string.IsNullOrEmpty(orgPn))
  40. {
  41. orgPn = GetAudioOrgPnValue(container, audioBitrate, audioSampleRate, audioChannels);
  42. }
  43. var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
  44. return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
  45. }
  46. public string BuildVideoHeader(string container,
  47. string videoCodec,
  48. string audioCodec,
  49. int? width,
  50. int? height,
  51. int? bitrate,
  52. TransportStreamTimestamp timestamp,
  53. bool isDirectStream,
  54. long? runtimeTicks,
  55. TranscodeSeekInfo transcodeSeekInfo)
  56. {
  57. // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none
  58. var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo);
  59. // 0 = native, 1 = transcoded
  60. var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
  61. var flagValue = DlnaFlags.StreamingTransferMode |
  62. DlnaFlags.BackgroundTransferMode |
  63. DlnaFlags.DlnaV15;
  64. if (isDirectStream)
  65. {
  66. //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK;
  67. }
  68. else if (runtimeTicks.HasValue)
  69. {
  70. //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK;
  71. }
  72. var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}000000000000000000000000",
  73. Enum.Format(typeof(DlnaFlags), flagValue, "x"));
  74. var mediaProfile = _profile.GetVideoMediaProfile(container, audioCodec, videoCodec);
  75. var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn;
  76. if (string.IsNullOrEmpty(orgPn))
  77. {
  78. orgPn = GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, bitrate, timestamp);
  79. }
  80. var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
  81. return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
  82. }
  83. private string GetAudioOrgPnValue(string container, int? audioBitrate, int? audioSampleRate, int? audioChannels)
  84. {
  85. var format = new MediaFormatProfileResolver()
  86. .ResolveAudioFormat(container,
  87. audioBitrate,
  88. audioSampleRate,
  89. audioChannels);
  90. return format.HasValue ? format.Value.ToString() : null;
  91. }
  92. private string GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, int? bitrate, TransportStreamTimestamp timestamp)
  93. {
  94. var videoFormat = new MediaFormatProfileResolver()
  95. .ResolveVideoFormat(container,
  96. videoCodec,
  97. audioCodec,
  98. width,
  99. height,
  100. bitrate,
  101. timestamp);
  102. return videoFormat.HasValue ? videoFormat.Value.ToString() : null;
  103. }
  104. }
  105. }