VideoHlsService.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. using MediaBrowser.Controller;
  2. using MediaBrowser.Controller.Library;
  3. using System;
  4. namespace MediaBrowser.Api.Playback.Hls
  5. {
  6. public class VideoHlsService : BaseHlsService
  7. {
  8. /// <summary>
  9. /// Initializes a new instance of the <see cref="VideoHlsService" /> class.
  10. /// </summary>
  11. /// <param name="appPaths">The app paths.</param>
  12. /// <param name="userManager">The user manager.</param>
  13. public VideoHlsService(IServerApplicationPaths appPaths, IUserManager userManager)
  14. : base(appPaths, userManager)
  15. {
  16. }
  17. /// <summary>
  18. /// Gets the audio arguments.
  19. /// </summary>
  20. /// <param name="state">The state.</param>
  21. /// <returns>System.String.</returns>
  22. protected override string GetAudioArguments(StreamState state)
  23. {
  24. if (!state.Request.AudioCodec.HasValue)
  25. {
  26. return "-codec:a:0 copy";
  27. }
  28. var codec = GetAudioCodec(state.Request);
  29. var args = "-codec:a:0 " + codec;
  30. if (state.AudioStream != null)
  31. {
  32. var channels = GetNumAudioChannelsParam(state.Request, state.AudioStream);
  33. if (channels.HasValue)
  34. {
  35. args += " -ac " + channels.Value;
  36. }
  37. if (state.Request.AudioSampleRate.HasValue)
  38. {
  39. args += " -ar " + state.Request.AudioSampleRate.Value;
  40. }
  41. if (state.Request.AudioBitRate.HasValue)
  42. {
  43. args += " -ab " + state.Request.AudioBitRate.Value;
  44. }
  45. return args;
  46. }
  47. return args;
  48. }
  49. /// <summary>
  50. /// Gets the video arguments.
  51. /// </summary>
  52. /// <param name="state">The state.</param>
  53. /// <returns>System.String.</returns>
  54. protected override string GetVideoArguments(StreamState state)
  55. {
  56. var codec = GetVideoCodec(state.Request);
  57. // Right now all we support is either h264 or copy
  58. if (!codec.Equals("copy", StringComparison.OrdinalIgnoreCase) && !codec.Equals("libx264", StringComparison.OrdinalIgnoreCase))
  59. {
  60. codec = "libx264";
  61. }
  62. // See if we can save come cpu cycles by avoiding encoding
  63. if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase))
  64. {
  65. return IsH264(state.VideoStream) ? "-codec:v:0 copy -bsf h264_mp4toannexb" : "-codec:v:0 copy";
  66. }
  67. var args = "-codec:v:0 " + codec + " -preset superfast";
  68. if (state.Request.VideoBitRate.HasValue)
  69. {
  70. args += string.Format(" -b:v {0}", state.Request.VideoBitRate.Value);
  71. }
  72. // Add resolution params, if specified
  73. if (state.Request.Width.HasValue || state.Request.Height.HasValue || state.Request.MaxHeight.HasValue || state.Request.MaxWidth.HasValue)
  74. {
  75. args += GetOutputSizeParam(state, codec);
  76. }
  77. // Get the output framerate based on the FrameRate param
  78. double framerate = state.Request.Framerate ?? 0;
  79. // We have to supply a framerate for hls, so if it's null, account for that here
  80. if (framerate.Equals(0))
  81. {
  82. framerate = state.VideoStream.AverageFrameRate ?? 0;
  83. }
  84. if (framerate.Equals(0))
  85. {
  86. framerate = state.VideoStream.RealFrameRate ?? 0;
  87. }
  88. if (framerate.Equals(0))
  89. {
  90. framerate = 23.976;
  91. }
  92. args += string.Format(" -r {0}", framerate);
  93. // Needed to ensure segments stay under 10 seconds
  94. args += string.Format(" -g {0}", framerate);
  95. return args;
  96. }
  97. /// <summary>
  98. /// Gets the segment file extension.
  99. /// </summary>
  100. /// <param name="state">The state.</param>
  101. /// <returns>System.String.</returns>
  102. protected override string GetSegmentFileExtension(StreamState state)
  103. {
  104. return ".ts";
  105. }
  106. }
  107. }