VideoHlsService.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System;
  2. using System.Globalization;
  3. using System.Threading.Tasks;
  4. using MediaBrowser.Controller.Configuration;
  5. using MediaBrowser.Controller.Devices;
  6. using MediaBrowser.Controller.Dlna;
  7. using MediaBrowser.Controller.Library;
  8. using MediaBrowser.Controller.MediaEncoding;
  9. using MediaBrowser.Controller.Net;
  10. using MediaBrowser.Model.Configuration;
  11. using MediaBrowser.Model.Dlna;
  12. using MediaBrowser.Model.IO;
  13. using MediaBrowser.Model.Serialization;
  14. using MediaBrowser.Model.Services;
  15. using Microsoft.Extensions.Logging;
  16. namespace MediaBrowser.Api.Playback.Hls
  17. {
  18. [Route("/Videos/{Id}/live.m3u8", "GET")]
  19. public class GetLiveHlsStream : VideoStreamRequest
  20. {
  21. }
  22. /// <summary>
  23. /// Class VideoHlsService.
  24. /// </summary>
  25. [Authenticated]
  26. public class VideoHlsService : BaseHlsService
  27. {
  28. public VideoHlsService(
  29. ILogger<VideoHlsService> logger,
  30. IServerConfigurationManager serverConfigurationManager,
  31. IHttpResultFactory httpResultFactory,
  32. IUserManager userManager,
  33. ILibraryManager libraryManager,
  34. IIsoManager isoManager,
  35. IMediaEncoder mediaEncoder,
  36. IFileSystem fileSystem,
  37. IDlnaManager dlnaManager,
  38. IDeviceManager deviceManager,
  39. IMediaSourceManager mediaSourceManager,
  40. IJsonSerializer jsonSerializer,
  41. IAuthorizationContext authorizationContext,
  42. EncodingHelper encodingHelper)
  43. : base(
  44. logger,
  45. serverConfigurationManager,
  46. httpResultFactory,
  47. userManager,
  48. libraryManager,
  49. isoManager,
  50. mediaEncoder,
  51. fileSystem,
  52. dlnaManager,
  53. deviceManager,
  54. mediaSourceManager,
  55. jsonSerializer,
  56. authorizationContext,
  57. encodingHelper)
  58. {
  59. }
  60. public Task<object> Get(GetLiveHlsStream request)
  61. {
  62. return ProcessRequestAsync(request, true);
  63. }
  64. /// <summary>
  65. /// Gets the audio arguments.
  66. /// </summary>
  67. protected override string GetAudioArguments(StreamState state, EncodingOptions encodingOptions)
  68. {
  69. var codec = EncodingHelper.GetAudioEncoder(state);
  70. if (EncodingHelper.IsCopyCodec(codec))
  71. {
  72. return "-codec:a:0 copy";
  73. }
  74. var args = "-codec:a:0 " + codec;
  75. var channels = state.OutputAudioChannels;
  76. if (channels.HasValue)
  77. {
  78. args += " -ac " + channels.Value;
  79. }
  80. var bitrate = state.OutputAudioBitrate;
  81. if (bitrate.HasValue)
  82. {
  83. args += " -ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture);
  84. }
  85. if (state.OutputAudioSampleRate.HasValue)
  86. {
  87. args += " -ar " + state.OutputAudioSampleRate.Value.ToString(CultureInfo.InvariantCulture);
  88. }
  89. args += " " + EncodingHelper.GetAudioFilterParam(state, encodingOptions, true);
  90. return args;
  91. }
  92. /// <summary>
  93. /// Gets the video arguments.
  94. /// </summary>
  95. protected override string GetVideoArguments(StreamState state, EncodingOptions encodingOptions)
  96. {
  97. if (!state.IsOutputVideo)
  98. {
  99. return string.Empty;
  100. }
  101. var codec = EncodingHelper.GetVideoEncoder(state, encodingOptions);
  102. var args = "-codec:v:0 " + codec;
  103. // if (state.EnableMpegtsM2TsMode)
  104. // {
  105. // args += " -mpegts_m2ts_mode 1";
  106. // }
  107. // See if we can save come cpu cycles by avoiding encoding
  108. if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
  109. {
  110. // if h264_mp4toannexb is ever added, do not use it for live tv
  111. if (state.VideoStream != null &&
  112. !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
  113. {
  114. string bitStreamArgs = EncodingHelper.GetBitStreamArgs(state.VideoStream);
  115. if (!string.IsNullOrEmpty(bitStreamArgs))
  116. {
  117. args += " " + bitStreamArgs;
  118. }
  119. }
  120. }
  121. else
  122. {
  123. var keyFrameArg = string.Format(" -force_key_frames \"expr:gte(t,n_forced*{0})\"",
  124. state.SegmentLength.ToString(CultureInfo.InvariantCulture));
  125. var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
  126. args += " " + EncodingHelper.GetVideoQualityParam(state, codec, encodingOptions, GetDefaultEncoderPreset()) + keyFrameArg;
  127. // Add resolution params, if specified
  128. if (!hasGraphicalSubs)
  129. {
  130. args += EncodingHelper.GetOutputSizeParam(state, encodingOptions, codec);
  131. }
  132. // This is for internal graphical subs
  133. if (hasGraphicalSubs)
  134. {
  135. args += EncodingHelper.GetGraphicalSubtitleParam(state, encodingOptions, codec);
  136. }
  137. }
  138. args += " -flags -global_header";
  139. if (!string.IsNullOrEmpty(state.OutputVideoSync))
  140. {
  141. args += " -vsync " + state.OutputVideoSync;
  142. }
  143. args += EncodingHelper.GetOutputFFlags(state);
  144. return args;
  145. }
  146. }
  147. }