Răsfoiți Sursa

video streaming

LukePulverenti 12 ani în urmă
părinte
comite
ff6325efc5

+ 62 - 1
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
             };
         }
+
+        /// <summary>
+        /// Infers the audio codec based on the url
+        /// </summary>
+        /// <param name="url">The URL.</param>
+        /// <returns>System.Nullable{AudioCodecs}.</returns>
+        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;
+        }
+
+        /// <summary>
+        /// Infers the video codec.
+        /// </summary>
+        /// <param name="url">The URL.</param>
+        /// <returns>System.Nullable{VideoCodecs}.</returns>
+        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;
+        }
     }
 }

+ 6 - 6
MediaBrowser.Api/Playback/Progressive/AudioService.cs

@@ -7,12 +7,12 @@ namespace MediaBrowser.Api.Playback.Progressive
     /// <summary>
     /// Class GetAudioStream
     /// </summary>
-    [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
     {
 

+ 4 - 1
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);

+ 30 - 1
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
 {
+    /// <summary>
+    /// Class GetAudioStream
+    /// </summary>
+    [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
+    {
+
+    }
+    
     /// <summary>
     /// Class VideoService
     /// </summary>
@@ -19,6 +38,16 @@ namespace MediaBrowser.Api.Playback.Progressive
         {
         }
 
+        /// <summary>
+        /// Gets the specified request.
+        /// </summary>
+        /// <param name="request">The request.</param>
+        /// <returns>System.Object.</returns>
+        public object Get(GetVideoStream request)
+        {
+            return ProcessRequest(request);
+        }
+        
         /// <summary>
         /// Gets the command line arguments.
         /// </summary>

+ 0 - 1
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
 {

+ 1 - 1
MediaBrowser.Common/Net/StreamWriter.cs → 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
 {
     /// <summary>
     /// Class StreamWriter

+ 1 - 0
MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj

@@ -109,6 +109,7 @@
     <Compile Include="HttpServer\HttpServer.cs" />
     <Compile Include="HttpServer\NativeWebSocket.cs" />
     <Compile Include="HttpServer\ServerFactory.cs" />
+    <Compile Include="HttpServer\StreamWriter.cs" />
     <Compile Include="Logging\LogHelper.cs" />
     <Compile Include="Logging\NLogger.cs" />
     <Compile Include="Logging\NlogManager.cs" />

+ 0 - 34
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -38,38 +38,6 @@
     </ApplicationIcon>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ServiceStack, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.dll</HintPath>
-    </Reference>
-    <Reference Include="ServiceStack.Common, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll</HintPath>
-    </Reference>
-    <Reference Include="ServiceStack.Interfaces, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Interfaces.dll</HintPath>
-    </Reference>
-    <Reference Include="ServiceStack.OrmLite, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.dll</HintPath>
-    </Reference>
-    <Reference Include="ServiceStack.OrmLite.SqlServer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.SqlServer.dll</HintPath>
-    </Reference>
-    <Reference Include="ServiceStack.Redis, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Redis.3.9.37\lib\net35\ServiceStack.Redis.dll</HintPath>
-    </Reference>
-    <Reference Include="ServiceStack.ServiceInterface, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
-    </Reference>
-    <Reference Include="ServiceStack.Text, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Web" />
@@ -107,7 +75,6 @@
     <Compile Include="Net\IWebSocketConnection.cs" />
     <Compile Include="Net\IWebSocketServer.cs" />
     <Compile Include="Net\MimeTypes.cs" />
-    <Compile Include="Net\StreamWriter.cs" />
     <Compile Include="Net\UdpMessageReceivedEventArgs.cs" />
     <Compile Include="Net\WebSocketConnectEventArgs.cs" />
     <Compile Include="Net\WebSocketMessageType.cs" />
@@ -141,7 +108,6 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
-    <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">

+ 2 - 4
MediaBrowser.Common/Net/IRestfulService.cs

@@ -1,12 +1,10 @@
-using ServiceStack.ServiceHost;
-using System;
-
+
 namespace MediaBrowser.Common.Net
 {
     /// <summary>
     /// Interface IRestfulService
     /// </summary>
-    public interface IRestfulService : IService, IRequiresRequestContext, IDisposable
+    public interface IRestfulService
     {
     }
 }

+ 0 - 8
MediaBrowser.Common/packages.config

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="ServiceStack" version="3.9.37" targetFramework="net45" />
-  <package id="ServiceStack.Common" version="3.9.37" targetFramework="net45" />
-  <package id="ServiceStack.OrmLite.SqlServer" version="3.9.37" targetFramework="net45" />
-  <package id="ServiceStack.Redis" version="3.9.37" targetFramework="net45" />
-  <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" />
-</packages>