aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/ApiService.cs92
-rw-r--r--MediaBrowser.Api/HttpHandlers/AudioHandler.cs77
-rw-r--r--MediaBrowser.Api/HttpHandlers/VideoHandler.cs31
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj4
-rw-r--r--MediaBrowser.Controller/Kernel.cs3
-rw-r--r--MediaBrowser.sln3
6 files changed, 120 insertions, 90 deletions
diff --git a/MediaBrowser.Api/ApiService.cs b/MediaBrowser.Api/ApiService.cs
index 852c4e7db..c14705be6 100644
--- a/MediaBrowser.Api/ApiService.cs
+++ b/MediaBrowser.Api/ApiService.cs
@@ -13,45 +13,6 @@ namespace MediaBrowser.Api
/// </summary>
public static class ApiService
{
- private static string _FFMpegDirectory = null;
- /// <summary>
- /// Gets the folder path to ffmpeg
- /// </summary>
- public static string FFMpegDirectory
- {
- get
- {
- if (_FFMpegDirectory == null)
- {
- _FFMpegDirectory = System.IO.Path.Combine(ApplicationPaths.ProgramDataPath, "ffmpeg");
-
- if (!Directory.Exists(_FFMpegDirectory))
- {
- Directory.CreateDirectory(_FFMpegDirectory);
-
- // Extract ffmpeg
- using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.Api.ffmpeg.ffmpeg.exe"))
- {
- using (FileStream fileStream = new FileStream(FFMpegPath, FileMode.Create))
- {
- stream.CopyTo(fileStream);
- }
- }
- }
- }
-
- return _FFMpegDirectory;
- }
- }
-
- public static string FFMpegPath
- {
- get
- {
- return System.IO.Path.Combine(FFMpegDirectory, "ffmpeg.exe");
- }
- }
-
public static BaseItem GetItemById(string id)
{
Guid guid = string.IsNullOrEmpty(id) ? Guid.Empty : new Guid(id);
@@ -138,5 +99,58 @@ namespace MediaBrowser.Api
return null;
}
+
+ private static string _FFMpegDirectory = null;
+ /// <summary>
+ /// Gets the folder path to ffmpeg
+ /// </summary>
+ public static string FFMpegDirectory
+ {
+ get
+ {
+ if (_FFMpegDirectory == null)
+ {
+ _FFMpegDirectory = System.IO.Path.Combine(ApplicationPaths.ProgramDataPath, "ffmpeg");
+
+ if (!Directory.Exists(_FFMpegDirectory))
+ {
+ Directory.CreateDirectory(_FFMpegDirectory);
+ }
+ }
+
+ return _FFMpegDirectory;
+ }
+ }
+
+ private static string _FFMpegPath = null;
+ /// <summary>
+ /// Gets the path to ffmpeg.exe
+ /// </summary>
+ public static string FFMpegPath
+ {
+ get
+ {
+ if (_FFMpegPath == null)
+ {
+ string filename = "ffmpeg.exe";
+
+ _FFMpegPath = Path.Combine(FFMpegDirectory, filename);
+
+ if (!File.Exists(_FFMpegPath))
+ {
+ // Extract ffprobe
+ using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.Api.FFMpeg." + filename))
+ {
+ using (FileStream fileStream = new FileStream(_FFMpegPath, FileMode.Create))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+ }
+ }
+
+ return _FFMpegPath;
+ }
+ }
}
}
diff --git a/MediaBrowser.Api/HttpHandlers/AudioHandler.cs b/MediaBrowser.Api/HttpHandlers/AudioHandler.cs
index f3839a892..294a5b7af 100644
--- a/MediaBrowser.Api/HttpHandlers/AudioHandler.cs
+++ b/MediaBrowser.Api/HttpHandlers/AudioHandler.cs
@@ -105,7 +105,7 @@ namespace MediaBrowser.Api.HttpHandlers
/// <summary>
/// Creates arguments to pass to ffmpeg
/// </summary>
- private string GetAudioArguments()
+ protected override string GetCommandLineArguments()
{
List<string> audioTranscodeParams = new List<string>();
@@ -132,40 +132,6 @@ namespace MediaBrowser.Api.HttpHandlers
return "-i \"" + LibraryItem.Path + "\" -vn " + string.Join(" ", audioTranscodeParams.ToArray()) + " -";
}
-
- protected async override Task WriteResponseToOutputStream(Stream stream)
- {
- ProcessStartInfo startInfo = new ProcessStartInfo();
-
- startInfo.CreateNoWindow = true;
-
- startInfo.UseShellExecute = false;
- startInfo.RedirectStandardOutput = true;
-
- startInfo.FileName = ApiService.FFMpegPath;
- startInfo.WorkingDirectory = ApiService.FFMpegDirectory;
- startInfo.Arguments = GetAudioArguments();
-
- Logger.LogInfo(startInfo.FileName + " " + startInfo.Arguments);
-
- Process process = new Process();
- process.StartInfo = startInfo;
-
- try
- {
- process.Start();
-
- await process.StandardOutput.BaseStream.CopyToAsync(stream);
- }
- catch (Exception ex)
- {
- Logger.LogException(ex);
- }
- finally
- {
- process.Dispose();
- }
- }
}
public abstract class BaseMediaHandler<T> : BaseHandler
@@ -252,7 +218,48 @@ namespace MediaBrowser.Api.HttpHandlers
base.ProcessRequest(ctx);
}
+ protected abstract string GetCommandLineArguments();
protected abstract string GetOutputFormat();
protected abstract bool RequiresConversion();
+
+ protected async override Task WriteResponseToOutputStream(Stream stream)
+ {
+ ProcessStartInfo startInfo = new ProcessStartInfo();
+
+ startInfo.CreateNoWindow = true;
+
+ startInfo.UseShellExecute = false;
+ startInfo.RedirectStandardOutput = true;
+ startInfo.RedirectStandardError = true;
+
+ startInfo.FileName = ApiService.FFMpegPath;
+ startInfo.WorkingDirectory = ApiService.FFMpegDirectory;
+ startInfo.Arguments = GetCommandLineArguments();
+
+ Logger.LogInfo(startInfo.FileName + " " + startInfo.Arguments);
+
+ Process process = new Process();
+ process.StartInfo = startInfo;
+
+ try
+ {
+ process.Start();
+
+ // MUST read both stdout and stderr asynchronously or a deadlock may occurr
+ process.BeginErrorReadLine();
+
+ await process.StandardOutput.BaseStream.CopyToAsync(stream);
+
+ process.WaitForExit();
+ }
+ catch (Exception ex)
+ {
+ Logger.LogException(ex);
+ }
+ finally
+ {
+ process.Dispose();
+ }
+ }
}
}
diff --git a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs
index f94b8fc31..1b5c50c38 100644
--- a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs
+++ b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs
@@ -1,20 +1,14 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
using System.Linq;
-using System.Net;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Logging;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Net.Handlers;
-using MediaBrowser.Controller;
using MediaBrowser.Model.Entities;
namespace MediaBrowser.Api.HttpHandlers
{
class VideoHandler : BaseMediaHandler<Video>
{
+ private IEnumerable<string> UnsupportedOutputFormats = new string[] { "mp4" };
+
public IEnumerable<string> VideoFormats
{
get
@@ -28,17 +22,23 @@ namespace MediaBrowser.Api.HttpHandlers
/// </summary>
protected override string GetOutputFormat()
{
- return VideoFormats.First();
+ return VideoFormats.First(f => !UnsupportedOutputFormats.Any(s => s.Equals(f, StringComparison.OrdinalIgnoreCase)));
}
protected override bool RequiresConversion()
{
+ // If it's not in a format we can output to, return true
+ if (UnsupportedOutputFormats.Any(f => LibraryItem.Path.EndsWith(f, StringComparison.OrdinalIgnoreCase)))
+ {
+ return true;
+ }
+
// If it's not in a format the consumer accepts, return true
if (!VideoFormats.Any(f => LibraryItem.Path.EndsWith(f, StringComparison.OrdinalIgnoreCase)))
{
return true;
}
-
+
AudioStream audio = LibraryItem.AudioStreams.FirstOrDefault();
if (audio != null)
@@ -54,9 +54,16 @@ namespace MediaBrowser.Api.HttpHandlers
return false;
}
- protected override Task WriteResponseToOutputStream(Stream stream)
+ /// <summary>
+ /// Creates arguments to pass to ffmpeg
+ /// </summary>
+ protected override string GetCommandLineArguments()
{
- throw new NotImplementedException();
+ List<string> audioTranscodeParams = new List<string>();
+
+ string outputFormat = GetOutputFormat();
+ outputFormat = "matroska";
+ return "-i \"" + LibraryItem.Path + "\" -vcodec copy -acodec copy -f " + outputFormat + " -";
}
}
}
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index c628d01d9..dafce9510 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -86,10 +86,10 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
- <EmbeddedResource Include="ffmpeg\ffmpeg.exe" />
+ <EmbeddedResource Include="FFMpeg\ffmpeg.exe" />
</ItemGroup>
<ItemGroup>
- <Content Include="ffmpeg\readme.txt" />
+ <Content Include="FFMpeg\readme.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs
index 7841a2a5e..8eed678ba 100644
--- a/MediaBrowser.Controller/Kernel.cs
+++ b/MediaBrowser.Controller/Kernel.cs
@@ -5,7 +5,6 @@ using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
-using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Kernel;
using MediaBrowser.Controller.Configuration;
@@ -15,8 +14,8 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Users;
using MediaBrowser.Model.Progress;
+using MediaBrowser.Model.Users;
namespace MediaBrowser.Controller
{
diff --git a/MediaBrowser.sln b/MediaBrowser.sln
index 228deb5e5..424515748 100644
--- a/MediaBrowser.sln
+++ b/MediaBrowser.sln
@@ -77,4 +77,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(Performance) = preSolution
+ HasPerformanceSessions = true
+ EndGlobalSection
EndGlobal