jellyfin/Emby.Server.Implementations/FFMpeg/FFMpegLoader.cs

142 lines
5.3 KiB
C#
Raw Normal View History

2014-10-06 19:58:46 -04:00
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
2013-09-24 20:54:51 -04:00
using MediaBrowser.Model.IO;
using Microsoft.Extensions.Logging;
using System;
2014-10-06 19:58:46 -04:00
using System.Collections.Generic;
using System.IO;
using System.Linq;
2016-11-18 16:06:00 -05:00
namespace Emby.Server.Implementations.FFMpeg
{
2016-04-02 00:29:48 -04:00
public class FFMpegLoader
{
private readonly IHttpClient _httpClient;
private readonly IApplicationPaths _appPaths;
private readonly ILogger _logger;
2013-09-24 20:54:51 -04:00
private readonly IZipClient _zipClient;
private readonly IFileSystem _fileSystem;
2016-04-02 00:29:48 -04:00
private readonly FFMpegInstallInfo _ffmpegInstallInfo;
2016-11-11 02:24:36 -05:00
public FFMpegLoader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient, IFileSystem fileSystem, FFMpegInstallInfo ffmpegInstallInfo)
{
_logger = logger;
_appPaths = appPaths;
_httpClient = httpClient;
2013-09-24 20:54:51 -04:00
_zipClient = zipClient;
_fileSystem = fileSystem;
2016-04-02 00:29:48 -04:00
_ffmpegInstallInfo = ffmpegInstallInfo;
}
2018-09-12 13:26:21 -04:00
public FFMpegInfo GetFFMpegInfo(StartupOptions options)
{
2014-09-14 11:26:33 -04:00
var customffMpegPath = options.GetOption("-ffmpeg");
var customffProbePath = options.GetOption("-ffprobe");
if (!string.IsNullOrWhiteSpace(customffMpegPath) && !string.IsNullOrWhiteSpace(customffProbePath))
{
return new FFMpegInfo
{
ProbePath = customffProbePath,
EncoderPath = customffMpegPath,
2016-06-23 13:04:18 -04:00
Version = "external"
2014-09-14 11:26:33 -04:00
};
}
2016-04-02 00:29:48 -04:00
var downloadInfo = _ffmpegInstallInfo;
2018-09-12 13:26:21 -04:00
var prebuiltFolder = _appPaths.ProgramSystemPath;
var prebuiltffmpeg = Path.Combine(prebuiltFolder, downloadInfo.FFMpegFilename);
var prebuiltffprobe = Path.Combine(prebuiltFolder, downloadInfo.FFProbeFilename);
2017-10-02 16:18:27 -04:00
if (_fileSystem.FileExists(prebuiltffmpeg) && _fileSystem.FileExists(prebuiltffprobe))
{
return new FFMpegInfo
{
2017-10-02 16:18:27 -04:00
ProbePath = prebuiltffprobe,
EncoderPath = prebuiltffmpeg,
Version = "external"
};
}
2017-10-02 16:18:27 -04:00
var version = downloadInfo.Version;
2016-06-29 21:19:38 -04:00
if (string.Equals(version, "0", StringComparison.OrdinalIgnoreCase))
{
return new FFMpegInfo();
}
2014-05-06 22:28:19 -04:00
var rootEncoderPath = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
var versionedDirectoryPath = Path.Combine(rootEncoderPath, version);
var info = new FFMpegInfo
{
ProbePath = Path.Combine(versionedDirectoryPath, downloadInfo.FFProbeFilename),
EncoderPath = Path.Combine(versionedDirectoryPath, downloadInfo.FFMpegFilename),
Version = version
};
2016-04-02 00:16:18 -04:00
_fileSystem.CreateDirectory(versionedDirectoryPath);
2014-09-14 11:10:51 -04:00
var excludeFromDeletions = new List<string> { versionedDirectoryPath };
2016-04-02 00:16:18 -04:00
if (!_fileSystem.FileExists(info.ProbePath) || !_fileSystem.FileExists(info.EncoderPath))
{
2014-05-06 22:28:19 -04:00
// ffmpeg not present. See if there's an older version we can start with
var existingVersion = GetExistingVersion(info, rootEncoderPath);
2014-05-06 22:28:19 -04:00
// No older version. Need to download and block until complete
if (existingVersion == null)
{
2018-09-12 13:26:21 -04:00
return new FFMpegInfo();
2014-05-06 22:28:19 -04:00
}
else
{
info = existingVersion;
2017-05-10 15:12:03 -04:00
versionedDirectoryPath = _fileSystem.GetDirectoryName(info.EncoderPath);
2014-09-14 11:10:51 -04:00
excludeFromDeletions.Add(versionedDirectoryPath);
2014-05-06 22:28:19 -04:00
}
}
// Allow just one of these to be overridden, if desired.
if (!string.IsNullOrWhiteSpace(customffMpegPath))
{
info.EncoderPath = customffMpegPath;
}
if (!string.IsNullOrWhiteSpace(customffProbePath))
{
2017-07-23 01:54:24 -04:00
info.ProbePath = customffProbePath;
}
2014-05-06 22:28:19 -04:00
return info;
}
private FFMpegInfo GetExistingVersion(FFMpegInfo info, string rootEncoderPath)
{
var encoderFilename = Path.GetFileName(info.EncoderPath);
var probeFilename = Path.GetFileName(info.ProbePath);
2016-11-18 16:06:00 -05:00
foreach (var directory in _fileSystem.GetDirectoryPaths(rootEncoderPath)
2014-05-06 22:28:19 -04:00
.ToList())
{
2016-11-18 16:06:00 -05:00
var allFiles = _fileSystem.GetFilePaths(directory, true).ToList();
2014-05-06 22:28:19 -04:00
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))
{
2014-05-06 22:28:19 -04:00
return new FFMpegInfo
{
2015-02-11 15:23:07 -05:00
EncoderPath = encoder,
ProbePath = probe,
2017-05-10 15:12:03 -04:00
Version = Path.GetFileName(_fileSystem.GetDirectoryName(probe))
2014-05-06 22:28:19 -04:00
};
}
2014-05-06 22:28:19 -04:00
}
2013-09-23 13:27:38 -04:00
2014-05-06 22:28:19 -04:00
return null;
}
}
}