VideoHlsService.cs 5.5 KB

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