AudioHlsService.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. using MediaBrowser.Common.MediaInfo;
  2. using MediaBrowser.Controller;
  3. using MediaBrowser.Controller.Dto;
  4. using MediaBrowser.Controller.Library;
  5. using MediaBrowser.Model.Dto;
  6. using MediaBrowser.Model.IO;
  7. using ServiceStack.ServiceHost;
  8. using System;
  9. using System.IO;
  10. namespace MediaBrowser.Api.Playback.Hls
  11. {
  12. /// <summary>
  13. /// Class GetHlsAudioStream
  14. /// </summary>
  15. [Route("/Audio/{Id}/stream.m3u8", "GET")]
  16. [Api(Description = "Gets an audio stream using HTTP live streaming.")]
  17. public class GetHlsAudioStream : StreamRequest
  18. {
  19. }
  20. /// <summary>
  21. /// Class GetHlsAudioSegment
  22. /// </summary>
  23. [Route("/Audio/{Id}/hls/{SegmentId}/stream.mp3", "GET")]
  24. [Route("/Audio/{Id}/hls/{SegmentId}/stream.aac", "GET")]
  25. [Api(Description = "Gets an Http live streaming segment file. Internal use only.")]
  26. public class GetHlsAudioSegment
  27. {
  28. /// <summary>
  29. /// Gets or sets the id.
  30. /// </summary>
  31. /// <value>The id.</value>
  32. public string Id { get; set; }
  33. /// <summary>
  34. /// Gets or sets the segment id.
  35. /// </summary>
  36. /// <value>The segment id.</value>
  37. public string SegmentId { get; set; }
  38. }
  39. /// <summary>
  40. /// Class AudioHlsService
  41. /// </summary>
  42. public class AudioHlsService : BaseHlsService
  43. {
  44. /// <summary>
  45. /// Initializes a new instance of the <see cref="AudioHlsService" /> class.
  46. /// </summary>
  47. /// <param name="appPaths">The app paths.</param>
  48. /// <param name="userManager">The user manager.</param>
  49. /// <param name="libraryManager">The library manager.</param>
  50. /// <param name="isoManager">The iso manager.</param>
  51. /// <param name="mediaEncoder">The media encoder.</param>
  52. public AudioHlsService(IServerApplicationPaths appPaths, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService)
  53. : base(appPaths, userManager, libraryManager, isoManager, mediaEncoder, dtoService)
  54. {
  55. }
  56. /// <summary>
  57. /// Gets the specified request.
  58. /// </summary>
  59. /// <param name="request">The request.</param>
  60. /// <returns>System.Object.</returns>
  61. public object Get(GetHlsAudioSegment request)
  62. {
  63. var file = request.SegmentId + Path.GetExtension(RequestContext.PathInfo);
  64. file = Path.Combine(ApplicationPaths.EncodedMediaCachePath, file);
  65. return ResultFactory.GetStaticFileResult(RequestContext, file, FileShare.ReadWrite);
  66. }
  67. /// <summary>
  68. /// Gets the specified request.
  69. /// </summary>
  70. /// <param name="request">The request.</param>
  71. /// <returns>System.Object.</returns>
  72. public object Get(GetHlsAudioStream request)
  73. {
  74. return ProcessRequest(request);
  75. }
  76. /// <summary>
  77. /// Gets the audio arguments.
  78. /// </summary>
  79. /// <param name="state">The state.</param>
  80. /// <returns>System.String.</returns>
  81. protected override string GetAudioArguments(StreamState state)
  82. {
  83. var codec = GetAudioCodec(state.Request);
  84. var args = "-codec:a " + codec;
  85. var channels = GetNumAudioChannelsParam(state.Request, state.AudioStream);
  86. if (channels.HasValue)
  87. {
  88. args += " -ac " + channels.Value;
  89. }
  90. if (state.Request.AudioSampleRate.HasValue)
  91. {
  92. args += " -ar " + state.Request.AudioSampleRate.Value;
  93. }
  94. if (state.Request.AudioBitRate.HasValue)
  95. {
  96. args += " -ab " + state.Request.AudioBitRate.Value;
  97. }
  98. return args;
  99. }
  100. /// <summary>
  101. /// Gets the video arguments.
  102. /// </summary>
  103. /// <param name="state">The state.</param>
  104. /// <param name="performSubtitleConversion">if set to <c>true</c> [perform subtitle conversion].</param>
  105. /// <returns>System.String.</returns>
  106. protected override string GetVideoArguments(StreamState state, bool performSubtitleConversion)
  107. {
  108. // No video
  109. return string.Empty;
  110. }
  111. /// <summary>
  112. /// Gets the segment file extension.
  113. /// </summary>
  114. /// <param name="state">The state.</param>
  115. /// <returns>System.String.</returns>
  116. /// <exception cref="System.ArgumentException">Must specify either aac or mp3 audio codec.</exception>
  117. /// <exception cref="System.InvalidOperationException">Only aac and mp3 audio codecs are supported.</exception>
  118. protected override string GetSegmentFileExtension(StreamState state)
  119. {
  120. if (state.Request.AudioCodec == AudioCodecs.Aac)
  121. {
  122. return ".aac";
  123. }
  124. if (state.Request.AudioCodec == AudioCodecs.Mp3)
  125. {
  126. return ".mp3";
  127. }
  128. throw new ArgumentException("Must specify either aac or mp3 audio codec.");
  129. }
  130. /// <summary>
  131. /// Gets the map args.
  132. /// </summary>
  133. /// <param name="state">The state.</param>
  134. /// <returns>System.String.</returns>
  135. protected override string GetMapArgs(StreamState state)
  136. {
  137. return string.Format("-map 0:{0}", state.AudioStream.Index);
  138. }
  139. }
  140. }