diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index e0a67ecf1..bebb4c94a 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -84,6 +84,9 @@
+
+
+
@@ -95,8 +98,6 @@
-
-
@@ -105,9 +106,6 @@
-
-
-
@@ -139,9 +137,7 @@
-
-
-
+
xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.ServerApplication\CorePlugins\" /y
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index b7d299afe..d0388ed32 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -144,7 +144,7 @@ namespace MediaBrowser.Api.Playback
///
/// The state.
/// System.String.
- protected string GetMapArgs(StreamState state)
+ protected virtual string GetMapArgs(StreamState state)
{
var args = string.Empty;
diff --git a/MediaBrowser.Api/Playback/Hls/AudioHlsService.cs b/MediaBrowser.Api/Playback/Hls/AudioHlsService.cs
new file mode 100644
index 000000000..cfd8767af
--- /dev/null
+++ b/MediaBrowser.Api/Playback/Hls/AudioHlsService.cs
@@ -0,0 +1,94 @@
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Dto;
+using System;
+
+namespace MediaBrowser.Api.Playback.Hls
+{
+ ///
+ /// Class AudioHlsService
+ ///
+ public class AudioHlsService : BaseHlsService
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The app paths.
+ /// The user manager.
+ public AudioHlsService(IServerApplicationPaths appPaths, IUserManager userManager) : base(appPaths, userManager)
+ {
+ }
+
+ ///
+ /// Gets the audio arguments.
+ ///
+ /// The state.
+ /// System.String.
+ protected override string GetAudioArguments(StreamState state)
+ {
+ var codec = GetAudioCodec(state.Request);
+
+ var args = "-codec:a " + codec;
+
+ var channels = GetNumAudioChannelsParam(state.Request, state.AudioStream);
+
+ if (channels.HasValue)
+ {
+ args += " -ac " + channels.Value;
+ }
+
+ if (state.Request.AudioSampleRate.HasValue)
+ {
+ args += " -ar " + state.Request.AudioSampleRate.Value;
+ }
+
+ if (state.Request.AudioBitRate.HasValue)
+ {
+ args += " -ab " + state.Request.AudioBitRate.Value;
+ }
+
+ return args;
+ }
+
+ ///
+ /// Gets the video arguments.
+ ///
+ /// The state.
+ /// System.String.
+ protected override string GetVideoArguments(StreamState state)
+ {
+ // No video
+ return string.Empty;
+ }
+
+ ///
+ /// Gets the segment file extension.
+ ///
+ /// The state.
+ /// System.String.
+ /// Only aac and mp3 audio codecs are supported.
+ protected override string GetSegmentFileExtension(StreamState state)
+ {
+ if (state.Request.AudioCodec == AudioCodecs.Aac)
+ {
+ return ".aac";
+ }
+ if (state.Request.AudioCodec == AudioCodecs.Mp3)
+ {
+ return ".mp3";
+ }
+
+ throw new InvalidOperationException("Only aac and mp3 audio codecs are supported.");
+ }
+
+ ///
+ /// Gets the map args.
+ ///
+ /// The state.
+ /// System.String.
+ protected override string GetMapArgs(StreamState state)
+ {
+ return string.Format("-map 0:{0}", state.AudioStream.Index);
+ }
+ }
+}
diff --git a/MediaBrowser.Api/Streaming/BaseHlsPlaylistHandler.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
similarity index 66%
rename from MediaBrowser.Api/Streaming/BaseHlsPlaylistHandler.cs
rename to MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 5cb8b7e07..955b7159b 100644
--- a/MediaBrowser.Api/Streaming/BaseHlsPlaylistHandler.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -1,36 +1,45 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Net.Handlers;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Library;
using System;
using System.IO;
using System.Linq;
-using System.Net;
using System.Text;
using System.Threading.Tasks;
-namespace MediaBrowser.Api.Streaming
+namespace MediaBrowser.Api.Playback.Hls
{
- ///
- /// Class BaseHlsPlaylistHandler
- ///
- /// The type of the T base item type.
- public abstract class BaseHlsPlaylistHandler : BaseStreamingHandler
- where TBaseItemType : BaseItem, IHasMediaStreams, new()
+ public abstract class BaseHlsService : BaseStreamingService
{
+ ///
+ /// The segment file prefix
+ ///
+ public const string SegmentFilePrefix = "segment-";
+
+ protected BaseHlsService(IServerApplicationPaths appPaths, IUserManager userManager)
+ : base(appPaths, userManager)
+ {
+ }
+
///
/// Gets the audio arguments.
///
/// System.String.
- protected abstract string GetAudioArguments();
+ protected abstract string GetAudioArguments(StreamState state);
///
/// Gets the video arguments.
///
/// System.String.
- protected abstract string GetVideoArguments();
+ protected abstract string GetVideoArguments(StreamState state);
+ ///
+ /// Gets the segment file extension.
+ ///
+ /// The state.
+ /// System.String.
+ protected abstract string GetSegmentFileExtension(StreamState state);
+
///
/// Gets the type of the transcoding job.
///
@@ -41,41 +50,30 @@ namespace MediaBrowser.Api.Streaming
}
///
- /// This isn't needed because we're going to override the whole flow using ProcessRequest
+ /// Processes the request.
///
- /// The stream.
- /// The response info.
- /// Length of the content.
- /// Task.
- ///
- protected override Task WriteResponseToOutputStream(Stream stream, ResponseInfo responseInfo, long? contentLength)
+ /// The state.
+ /// System.Object.
+ protected object ProcessRequest(StreamState state)
{
- throw new NotImplementedException();
+ return ProcessRequestAsync(state).Result;
}
///
- /// Gets the segment file extension.
+ /// Processes the request async.
///
- /// The segment file extension.
- protected abstract string SegmentFileExtension { get; }
-
- ///
- /// Processes the request.
- ///
- /// The CTX.
- /// Task.
- public override async Task ProcessRequest(HttpListenerContext ctx)
+ /// The state.
+ /// Task{System.Object}.
+ public async Task