From ff6325efc5ae478c68dc140c5adbae089a6f7f4b Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Tue, 26 Feb 2013 23:44:41 -0500 Subject: [PATCH] video streaming --- .../Playback/BaseStreamingService.cs | 63 ++++++++++++++++++- .../Playback/Progressive/AudioService.cs | 12 ++-- .../BaseProgressiveStreamingService.cs | 5 +- .../Playback/Progressive/VideoService.cs | 31 ++++++++- .../HttpServer/BaseRestService.cs | 1 - .../HttpServer}/StreamWriter.cs | 2 +- ...MediaBrowser.Common.Implementations.csproj | 1 + .../MediaBrowser.Common.csproj | 34 ---------- MediaBrowser.Common/Net/IRestfulService.cs | 6 +- MediaBrowser.Common/packages.config | 8 --- 10 files changed, 106 insertions(+), 57 deletions(-) rename {MediaBrowser.Common/Net => MediaBrowser.Common.Implementations/HttpServer}/StreamWriter.cs (95%) delete mode 100644 MediaBrowser.Common/packages.config diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 159106437..b31b9b861 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -610,6 +610,17 @@ namespace MediaBrowser.Api.Playback var media = (IHasMediaStreams)item; + var url = Request.PathInfo; + + if (!request.AudioCodec.HasValue) + { + request.AudioCodec = InferAudioCodec(url); + } + if (!request.VideoCodec.HasValue) + { + request.VideoCodec = InferVideoCodec(url); + } + return new StreamState { Item = item, @@ -617,8 +628,58 @@ namespace MediaBrowser.Api.Playback AudioStream = GetMediaStream(media.MediaStreams, request.AudioStreamIndex, MediaStreamType.Audio, true), VideoStream = GetMediaStream(media.MediaStreams, request.VideoStreamIndex, MediaStreamType.Video, true), SubtitleStream = GetMediaStream(media.MediaStreams, request.SubtitleStreamIndex, MediaStreamType.Subtitle, false), - Url = Request.PathInfo + Url = url }; } + + /// + /// Infers the audio codec based on the url + /// + /// The URL. + /// System.Nullable{AudioCodecs}. + private AudioCodecs? InferAudioCodec(string url) + { + var ext = Path.GetExtension(url); + + if (string.Equals(ext, ".mp3", StringComparison.OrdinalIgnoreCase)) + { + return AudioCodecs.Mp3; + } + if (string.Equals(ext, ".aac", StringComparison.OrdinalIgnoreCase)) + { + return AudioCodecs.Aac; + } + if (string.Equals(ext, ".wam", StringComparison.OrdinalIgnoreCase)) + { + return AudioCodecs.Wma; + } + + return null; + } + + /// + /// Infers the video codec. + /// + /// The URL. + /// System.Nullable{VideoCodecs}. + private VideoCodecs? InferVideoCodec(string url) + { + var ext = Path.GetExtension(url); + + if (string.Equals(ext, ".asf", StringComparison.OrdinalIgnoreCase)) + { + return VideoCodecs.Wmv; + } + if (string.Equals(ext, ".webm", StringComparison.OrdinalIgnoreCase)) + { + return VideoCodecs.Vpx; + } + if (string.Equals(ext, ".ogg", StringComparison.OrdinalIgnoreCase)) + { + return VideoCodecs.Theora; + } + + return null; + } } } diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs index dcb7d96e3..850e8ff3b 100644 --- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs +++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs @@ -7,12 +7,12 @@ namespace MediaBrowser.Api.Playback.Progressive /// /// Class GetAudioStream /// - [Route("/Audio/{Id}.mp3", "GET")] - [Route("/Audio/{Id}.wma", "GET")] - [Route("/Audio/{Id}.aac", "GET")] - [Route("/Audio/{Id}.flac", "GET")] - [Route("/Audio/{Id}.ogg", "GET")] - [Route("/Audio/{Id}", "GET")] + [Route("/Audio/{Id}/stream.mp3", "GET")] + [Route("/Audio/{Id}/stream.wma", "GET")] + [Route("/Audio/{Id}/stream.aac", "GET")] + [Route("/Audio/{Id}/stream.flac", "GET")] + [Route("/Audio/{Id}/stream.ogg", "GET")] + [Route("/Audio/{Id}/stream", "GET")] public class GetAudioStream : StreamRequest { diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index bc2d26bcc..62ca74df9 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Model.Dto; @@ -123,6 +124,8 @@ namespace MediaBrowser.Api.Playback.Progressive // Use the command line args with a dummy playlist path var outputPath = GetOutputFilePath(state); + Response.ContentType = MimeTypes.GetMimeType(outputPath); + if (!File.Exists(outputPath)) { await StartFFMpeg(state, outputPath).ConfigureAwait(false); diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index b43b4bfbc..cb02518d1 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -1,10 +1,29 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.Logging; using System; +using ServiceStack.ServiceHost; namespace MediaBrowser.Api.Playback.Progressive { + /// + /// Class GetAudioStream + /// + [Route("/Videos/{Id}/stream.ts", "GET")] + [Route("/Videos/{Id}/stream.webm", "GET")] + [Route("/Videos/{Id}/stream.asf", "GET")] + [Route("/Videos/{Id}/stream.wmv", "GET")] + [Route("/Videos/{Id}/stream.ogv", "GET")] + [Route("/Videos/{Id}/stream.mp4", "GET")] + [Route("/Videos/{Id}/stream.m4v", "GET")] + [Route("/Videos/{Id}/stream.mkv", "GET")] + [Route("/Videos/{Id}/stream.mpeg", "GET")] + [Route("/Videos/{Id}/stream.avi", "GET")] + [Route("/Videos/{Id}/stream", "GET")] + public class GetVideoStream : StreamRequest + { + + } + /// /// Class VideoService /// @@ -19,6 +38,16 @@ namespace MediaBrowser.Api.Playback.Progressive { } + /// + /// Gets the specified request. + /// + /// The request. + /// System.Object. + public object Get(GetVideoStream request) + { + return ProcessRequest(request); + } + /// /// Gets the command line arguments. /// diff --git a/MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs b/MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs index bcf1dc4a7..65195c52b 100644 --- a/MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs +++ b/MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs @@ -14,7 +14,6 @@ using System.Linq; using System.Net; using System.Threading.Tasks; using MimeTypes = MediaBrowser.Common.Net.MimeTypes; -using StreamWriter = MediaBrowser.Common.Net.StreamWriter; namespace MediaBrowser.Common.Implementations.HttpServer { diff --git a/MediaBrowser.Common/Net/StreamWriter.cs b/MediaBrowser.Common.Implementations/HttpServer/StreamWriter.cs similarity index 95% rename from MediaBrowser.Common/Net/StreamWriter.cs rename to MediaBrowser.Common.Implementations/HttpServer/StreamWriter.cs index 220c52578..c92bfe0b9 100644 --- a/MediaBrowser.Common/Net/StreamWriter.cs +++ b/MediaBrowser.Common.Implementations/HttpServer/StreamWriter.cs @@ -2,7 +2,7 @@ using System.IO; using System.Threading.Tasks; -namespace MediaBrowser.Common.Net +namespace MediaBrowser.Common.Implementations.HttpServer { /// /// Class StreamWriter diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 6f28a6c9a..70d92edb5 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -109,6 +109,7 @@ + diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 7f1f980eb..50ca0e5bc 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -38,38 +38,6 @@ - - False - ..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.dll - - - False - ..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll - - - False - ..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Interfaces.dll - - - False - ..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.dll - - - False - ..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.SqlServer.dll - - - False - ..\packages\ServiceStack.Redis.3.9.37\lib\net35\ServiceStack.Redis.dll - - - False - ..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.ServiceInterface.dll - - - False - ..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll - @@ -107,7 +75,6 @@ - @@ -141,7 +108,6 @@ - diff --git a/MediaBrowser.Common/Net/IRestfulService.cs b/MediaBrowser.Common/Net/IRestfulService.cs index 36055cd8a..d62be4987 100644 --- a/MediaBrowser.Common/Net/IRestfulService.cs +++ b/MediaBrowser.Common/Net/IRestfulService.cs @@ -1,12 +1,10 @@ -using ServiceStack.ServiceHost; -using System; - + namespace MediaBrowser.Common.Net { /// /// Interface IRestfulService /// - public interface IRestfulService : IService, IRequiresRequestContext, IDisposable + public interface IRestfulService { } } diff --git a/MediaBrowser.Common/packages.config b/MediaBrowser.Common/packages.config deleted file mode 100644 index ea25110aa..000000000 --- a/MediaBrowser.Common/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file