aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.ServerApplication
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-05-06 22:28:19 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-05-06 22:28:19 -0400
commit0d025f7fb620bf2a24ca9aa4e5994f132e02e7c0 (patch)
tree76137f5f868ed81725d29bbdc6ac0e3b57c304d8 /MediaBrowser.ServerApplication
parente1dd361c7bf05af49d9210ab679e85fa00870990 (diff)
beginning remote subtitle downloading
Diffstat (limited to 'MediaBrowser.ServerApplication')
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs11
-rw-r--r--MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs81
-rw-r--r--MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs135
-rw-r--r--MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs2
4 files changed, 135 insertions, 94 deletions
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index af400f850..c79d84e5a 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -31,11 +31,11 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Session;
using MediaBrowser.Controller.Sorting;
+using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Controller.Themes;
using MediaBrowser.Dlna;
using MediaBrowser.Dlna.Eventing;
using MediaBrowser.Dlna.Main;
-using MediaBrowser.Dlna.PlayTo;
using MediaBrowser.Dlna.Server;
using MediaBrowser.MediaEncoding.BdInfo;
using MediaBrowser.MediaEncoding.Encoder;
@@ -44,6 +44,7 @@ using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Updates;
using MediaBrowser.Providers.Manager;
+using MediaBrowser.Providers.Subtitles;
using MediaBrowser.Server.Implementations;
using MediaBrowser.Server.Implementations.Channels;
using MediaBrowser.Server.Implementations.Collections;
@@ -193,6 +194,7 @@ namespace MediaBrowser.ServerApplication
private IProviderRepository ProviderRepository { get; set; }
private INotificationManager NotificationManager { get; set; }
+ private ISubtitleManager SubtitleManager { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ApplicationHost"/> class.
@@ -531,6 +533,9 @@ namespace MediaBrowser.ServerApplication
NotificationManager = new NotificationManager(LogManager, UserManager, ServerConfigurationManager);
RegisterSingleInstance(NotificationManager);
+ SubtitleManager = new SubtitleManager(LogManager.GetLogger("SubtitleManager"), FileSystemManager, LibraryMonitor);
+ RegisterSingleInstance(SubtitleManager);
+
var displayPreferencesTask = Task.Run(async () => await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false));
var itemsTask = Task.Run(async () => await ConfigureItemRepositories().ConfigureAwait(false));
var userdataTask = Task.Run(async () => await ConfigureUserDataRepositories().ConfigureAwait(false));
@@ -566,7 +571,7 @@ namespace MediaBrowser.ServerApplication
{
var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager).GetFFMpegInfo(progress).ConfigureAwait(false);
- MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ApplicationPaths, JsonSerializer, info.Path, info.ProbePath, info.Version, FileSystemManager);
+ MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ApplicationPaths, JsonSerializer, info.EncoderPath, info.ProbePath, info.Version, FileSystemManager);
RegisterSingleInstance(MediaEncoder);
}
@@ -710,6 +715,8 @@ namespace MediaBrowser.ServerApplication
LiveTvManager.AddParts(GetExports<ILiveTvService>());
+ SubtitleManager.AddParts(GetExports<ISubtitleProvider>());
+
SessionManager.AddParts(GetExports<ISessionControllerFactory>());
ChannelManager.AddParts(GetExports<IChannel>(), GetExports<IChannelFactory>());
diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs
index c4f529754..19aa7a684 100644
--- a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs
+++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs
@@ -4,6 +4,8 @@ using Mono.Unix.Native;
using System.Text.RegularExpressions;
using System.IO;
#endif
+using System.IO;
+using System.Text.RegularExpressions;
namespace MediaBrowser.ServerApplication.FFMpeg
{
@@ -32,7 +34,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
switch (arg)
{
case "Version":
- return "20140304";
+ return "20140506";
case "FFMpegFilename":
return "ffmpeg.exe";
case "FFProbeFilename":
@@ -42,7 +44,6 @@ namespace MediaBrowser.ServerApplication.FFMpeg
}
break;
- #if __MonoCS__
case PlatformID.Unix:
if (PlatformDetection.IsMac)
{
@@ -69,7 +70,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
switch (arg)
{
case "Version":
- return "20140304";
+ return "20140506";
case "FFMpegFilename":
return "ffmpeg";
case "FFProbeFilename":
@@ -85,7 +86,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
switch (arg)
{
case "Version":
- return "20140304";
+ return "20140505";
case "FFMpegFilename":
return "ffmpeg";
case "FFProbeFilename":
@@ -98,7 +99,6 @@ namespace MediaBrowser.ServerApplication.FFMpeg
}
// Unsupported Unix platform
return "";
-#endif
}
return "";
}
@@ -106,18 +106,17 @@ namespace MediaBrowser.ServerApplication.FFMpeg
private static string[] GetDownloadUrls()
{
var pid = Environment.OSVersion.Platform;
-
+
switch (pid)
{
case PlatformID.Win32NT:
return new[]
{
- "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20140304-git-f34cceb-win32-static.7z",
- "https://www.dropbox.com/s/6brdetuzbld93jk/ffmpeg-20140304-git-f34cceb-win32-static.7z?dl=1"
+ "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20140506-git-2baf1c8-win32-static.7z",
+ "https://www.dropbox.com/s/lxlzxs0r83iatsv/ffmpeg-20140506-git-2baf1c8-win32-static.7z?dl=1"
};
-
- #if __MonoCS__
- case PlatformID.Unix:
+
+ case PlatformID.Unix:
if (PlatformDetection.IsMac && PlatformDetection.IsX86_64)
{
return new[]
@@ -132,8 +131,8 @@ namespace MediaBrowser.ServerApplication.FFMpeg
{
return new[]
{
- "http://ffmpeg.gusari.org/static/32bit/ffmpeg.static.32bit.2014-03-04.tar.gz",
- "https://www.dropbox.com/s/0l76mcauqqkta31/ffmpeg.static.32bit.2014-03-04.tar.gz?dl=1"
+ "http://ffmpeg.gusari.org/static/32bit/ffmpeg.static.32bit.latest.tar.gz",
+ "https://www.dropbox.com/s/k9s02pv5to6slfb/ffmpeg.static.32bit.2014-05-06.tar.gz?dl=1"
};
}
@@ -141,22 +140,20 @@ namespace MediaBrowser.ServerApplication.FFMpeg
{
return new[]
{
- "http://ffmpeg.gusari.org/static/64bit/ffmpeg.static.64bit.2014-03-04.tar.gz",
- "https://www.dropbox.com/s/9wlxz440mdejuqe/ffmpeg.static.64bit.2014-03-04.tar.gz?dl=1"
+ "http://ffmpeg.gusari.org/static/64bit/ffmpeg.static.64bit.latest.tar.gz",
+ "https://www.dropbox.com/s/onuregwghywnzjo/ffmpeg.static.64bit.2014-05-05.tar.gz?dl=1"
};
}
}
//No Unix version available
- return new string[] {};
-#endif
+ return new string[] { };
}
- return new string[] {};
+ return new string[] { };
}
}
- #if __MonoCS__
public static class PlatformDetection
{
public readonly static bool IsWindows;
@@ -166,34 +163,52 @@ namespace MediaBrowser.ServerApplication.FFMpeg
public readonly static bool IsX86_64;
public readonly static bool IsArm;
- static PlatformDetection ()
+ static PlatformDetection()
{
IsWindows = Path.DirectorySeparatorChar == '\\';
//Don't call uname on windows
if (!IsWindows)
{
- Utsname uname;
- var callResult = Syscall.uname(out uname);
- if (callResult == 0)
- {
- IsMac = uname.sysname == "Darwin";
- IsLinux = !IsMac && uname.sysname == "Linux";
+ var uname = GetUnixName();
- Regex archX86 = new Regex("(i|I)[3-6]86");
- IsX86 = archX86.IsMatch(uname.machine);
- IsX86_64 = !IsX86 && uname.machine == "x86_64";
- IsArm = !IsX86 && !IsX86 && uname.machine.StartsWith("arm");
- }
+ IsMac = uname.sysname == "Darwin";
+ IsLinux = uname.sysname == "Linux";
+
+ var archX86 = new Regex("(i|I)[3-6]86");
+ IsX86 = archX86.IsMatch(uname.machine);
+ IsX86_64 = !IsX86 && uname.machine == "x86_64";
+ IsArm = !IsX86 && !IsX86_64 && uname.machine.StartsWith("arm");
}
else
{
- if (System.Environment.Is64BitOperatingSystem)
+ if (Environment.Is64BitOperatingSystem)
IsX86_64 = true;
else
IsX86 = true;
}
}
+
+ private static Uname GetUnixName()
+ {
+ var uname = new Uname();
+
+#if __MonoCS__
+ Utsname uname;
+ var callResult = Syscall.uname(out uname);
+ if (callResult == 0)
+ {
+ uname.sysname= uname.sysname;
+ uname.machine= uname.machine;
+ }
+#endif
+ return uname;
+ }
+ }
+
+ public class Uname
+ {
+ public string sysname = string.Empty;
+ public string machine = string.Empty;
}
- #endif
}
diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs
index b9c45e0d9..c550cb27f 100644
--- a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs
+++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs
@@ -42,63 +42,86 @@ namespace MediaBrowser.ServerApplication.FFMpeg
public async Task<FFMpegInfo> GetFFMpegInfo(IProgress<double> progress)
{
- var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), FFMpegDownloadInfo.Version);
+ var rootEncoderPath = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
+ var versionedDirectoryPath = Path.Combine(rootEncoderPath, FFMpegDownloadInfo.Version);
var info = new FFMpegInfo
{
ProbePath = Path.Combine(versionedDirectoryPath, FFMpegDownloadInfo.FFProbeFilename),
- Path = Path.Combine(versionedDirectoryPath, FFMpegDownloadInfo.FFMpegFilename),
+ EncoderPath = Path.Combine(versionedDirectoryPath, FFMpegDownloadInfo.FFMpegFilename),
Version = FFMpegDownloadInfo.Version
};
Directory.CreateDirectory(versionedDirectoryPath);
- var tasks = new List<Task>();
-
- double ffmpegPercent = 0;
- double fontPercent = 0;
- var syncLock = new object();
-
- if (!File.Exists(info.ProbePath) || !File.Exists(info.Path))
+ if (!File.Exists(info.ProbePath) || !File.Exists(info.EncoderPath))
{
- var ffmpegProgress = new ActionableProgress<double>();
- ffmpegProgress.RegisterAction(p =>
- {
- ffmpegPercent = p;
+ // ffmpeg not present. See if there's an older version we can start with
+ var existingVersion = GetExistingVersion(info, rootEncoderPath);
- lock (syncLock)
- {
- progress.Report((ffmpegPercent / 2) + (fontPercent / 2));
- }
- });
+ // No older version. Need to download and block until complete
+ if (existingVersion == null)
+ {
+ await DownloadFFMpeg(versionedDirectoryPath, progress).ConfigureAwait(false);
+ }
+ else
+ {
+ // Older version found.
+ // Start with that. Download new version in the background.
+ var newPath = versionedDirectoryPath;
+ Task.Run(() => DownloadFFMpegInBackground(newPath));
- tasks.Add(DownloadFFMpeg(info, ffmpegProgress));
- }
- else
- {
- ffmpegPercent = 100;
- progress.Report(50);
+ info = existingVersion;
+ versionedDirectoryPath = Path.GetDirectoryName(info.EncoderPath);
+ }
}
- var fontProgress = new ActionableProgress<double>();
- fontProgress.RegisterAction(p =>
+ await DownloadFonts(versionedDirectoryPath).ConfigureAwait(false);
+
+ return info;
+ }
+
+ private FFMpegInfo GetExistingVersion(FFMpegInfo info, string rootEncoderPath)
+ {
+ var encoderFilename = Path.GetFileName(info.EncoderPath);
+ var probeFilename = Path.GetFileName(info.ProbePath);
+
+ foreach (var directory in Directory.EnumerateDirectories(rootEncoderPath, "*", SearchOption.TopDirectoryOnly)
+ .ToList())
{
- fontPercent = p;
+ var allFiles = Directory.EnumerateFiles(directory, "*", SearchOption.AllDirectories).ToList();
- lock (syncLock)
+ var encoder = allFiles.FirstOrDefault(i => string.Equals(Path.GetFileName(i), encoderFilename, StringComparison.OrdinalIgnoreCase));
+ var probe = allFiles.FirstOrDefault(i => string.Equals(Path.GetFileName(i), probeFilename, StringComparison.OrdinalIgnoreCase));
+
+ if (!string.IsNullOrWhiteSpace(encoder) &&
+ !string.IsNullOrWhiteSpace(probe))
{
- progress.Report((ffmpegPercent / 2) + (fontPercent / 2));
+ return new FFMpegInfo
+ {
+ EncoderPath = encoder,
+ ProbePath = probe,
+ Version = Path.GetFileNameWithoutExtension(Path.GetDirectoryName(probe))
+ };
}
- });
-
- tasks.Add(DownloadFonts(versionedDirectoryPath, fontProgress));
+ }
- await Task.WhenAll(tasks).ConfigureAwait(false);
+ return null;
+ }
- return info;
+ private async void DownloadFFMpegInBackground(string directory)
+ {
+ try
+ {
+ await DownloadFFMpeg(directory, new Progress<double>()).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error downloading ffmpeg", ex);
+ }
}
- private async Task DownloadFFMpeg(FFMpegInfo info, IProgress<double> progress)
+ private async Task DownloadFFMpeg(string directory, IProgress<double> progress)
{
foreach (var url in FFMpegDownloadInfo.FfMpegUrls)
{
@@ -114,7 +137,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
}).ConfigureAwait(false);
- ExtractFFMpeg(tempFile, Path.GetDirectoryName(info.Path));
+ ExtractFFMpeg(tempFile, directory);
return;
}
catch (HttpException ex)
@@ -132,7 +155,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
private void ExtractFFMpeg(string tempFile, string targetFolder)
{
- _logger.Debug("Extracting ffmpeg from {0}", tempFile);
+ _logger.Info("Extracting ffmpeg from {0}", tempFile);
var tempFolder = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString());
@@ -171,6 +194,8 @@ namespace MediaBrowser.ServerApplication.FFMpeg
private void ExtractArchive(string archivePath, string targetPath)
{
+ _logger.Info("Extracting {0} to {1}", archivePath, targetPath);
+
if (string.Equals(FFMpegDownloadInfo.ArchiveType, "7z", StringComparison.OrdinalIgnoreCase))
{
_zipClient.ExtractAllFrom7z(archivePath, targetPath, true);
@@ -182,6 +207,8 @@ namespace MediaBrowser.ServerApplication.FFMpeg
}
private void Extract7zArchive(string archivePath, string targetPath)
{
+ _logger.Info("Extracting {0} to {1}", archivePath, targetPath);
+
_zipClient.ExtractAllFrom7z(archivePath, targetPath, true);
}
@@ -201,7 +228,8 @@ namespace MediaBrowser.ServerApplication.FFMpeg
/// Extracts the fonts.
/// </summary>
/// <param name="targetPath">The target path.</param>
- private async Task DownloadFonts(string targetPath, IProgress<double> progress)
+ /// <returns>Task.</returns>
+ private async Task DownloadFonts(string targetPath)
{
try
{
@@ -213,12 +241,19 @@ namespace MediaBrowser.ServerApplication.FFMpeg
var fontFile = Path.Combine(fontsDirectory, fontFilename);
- if (!File.Exists(fontFile))
+ if (File.Exists(fontFile))
{
- await DownloadFontFile(fontsDirectory, fontFilename, progress).ConfigureAwait(false);
+ await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
+ }
+ else
+ {
+ // Kick this off, but no need to wait on it
+ Task.Run(async () =>
+ {
+ await DownloadFontFile(fontsDirectory, fontFilename, new Progress<double>()).ConfigureAwait(false);
+ await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
+ });
}
-
- await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
}
catch (HttpException ex)
{
@@ -230,8 +265,6 @@ namespace MediaBrowser.ServerApplication.FFMpeg
// Don't let the server crash because of this
_logger.ErrorException("Error writing ffmpeg font files", ex);
}
-
- progress.Report(100);
}
/// <summary>
@@ -325,19 +358,5 @@ namespace MediaBrowser.ServerApplication.FFMpeg
}
}
}
-
- /// <summary>
- /// Gets the media tools path.
- /// </summary>
- /// <param name="create">if set to <c>true</c> [create].</param>
- /// <returns>System.String.</returns>
- private string GetMediaToolsPath(bool create)
- {
- var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
-
- Directory.CreateDirectory(path);
-
- return path;
- }
}
}
diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs
index 147a9f771..1361277aa 100644
--- a/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs
+++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs
@@ -9,7 +9,7 @@
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
- public string Path { get; set; }
+ public string EncoderPath { get; set; }
/// <summary>
/// Gets or sets the probe path.
/// </summary>