fix chapter image extraction

This commit is contained in:
Luke Pulverenti
2015-04-11 13:59:55 -04:00
parent 635de736a9
commit a639d32454
5 changed files with 92 additions and 45 deletions

View File

@@ -75,7 +75,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
protected readonly Func<ISubtitleEncoder> SubtitleEncoder;
protected readonly Func<IMediaSourceManager> MediaSourceManager;
private readonly List<Process> _runningProcesses = new List<Process>();
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder, Func<IMediaSourceManager> mediaSourceManager)
{
@@ -197,9 +197,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
var processWrapper = new ProcessWrapper(process, this);
try
{
StartProcess(process);
StartProcess(processWrapper);
}
catch (Exception ex)
{
@@ -264,7 +266,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
catch
{
StopProcess(process, 100, true);
StopProcess(processWrapper, 100, true);
throw;
}
@@ -303,7 +305,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
StartProcess(process);
var processWrapper = new ProcessWrapper(process, this);
StartProcess(processWrapper);
var lines = new List<int>();
var outputCancellationSource = new CancellationTokenSource(4000);
@@ -325,7 +329,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
finally
{
StopProcess(process, 100, true);
StopProcess(processWrapper, 100, true);
}
return lines;
@@ -382,23 +386,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary>
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
/// Processes the exited.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
private void ProcessExited(object sender, EventArgs e)
{
var process = (Process) sender;
lock (_runningProcesses)
{
_runningProcesses.Remove(process);
}
process.Dispose();
}
public Task<Stream> ExtractAudioImage(string path, CancellationToken cancellationToken)
{
return ExtractImage(new[] { path }, MediaProtocol.File, true, null, null, cancellationToken);
@@ -423,6 +410,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false);
}
catch (ArgumentException)
{
throw;
}
catch
{
_logger.Error("I-frame image extraction failed, will attempt standard way. Input: {0}", inputArgument);
@@ -505,7 +496,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
StartProcess(process);
var processWrapper = new ProcessWrapper(process, this);
StartProcess(processWrapper);
var memoryStream = new MemoryStream();
@@ -521,12 +514,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!ranToCompletion)
{
StopProcess(process, 1000, false);
StopProcess(processWrapper, 1000, false);
}
resourcePool.Release();
var exitCode = ranToCompletion ? process.ExitCode : -1;
var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
process.Dispose();
@@ -611,9 +604,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
bool ranToCompletion;
var processWrapper = new ProcessWrapper(process, this);
try
{
StartProcess(process);
StartProcess(processWrapper);
// Need to give ffmpeg enough time to make all the thumbnails, which could be a while,
// but we still need to detect if the process hangs.
@@ -637,7 +632,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (!ranToCompletion)
{
StopProcess(process, 1000, false);
StopProcess(processWrapper, 1000, false);
}
}
finally
@@ -645,7 +640,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
resourcePool.Release();
}
var exitCode = ranToCompletion ? process.ExitCode : -1;
var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
process.Dispose();
@@ -699,18 +694,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
return job.OutputFilePath;
}
private void StartProcess(Process process)
private void StartProcess(ProcessWrapper process)
{
process.Exited += ProcessExited;
process.Start();
process.Process.Start();
lock (_runningProcesses)
{
_runningProcesses.Add(process);
}
}
private void StopProcess(Process process, int waitTimeMs, bool enableForceKill)
private void StopProcess(ProcessWrapper process, int waitTimeMs, bool enableForceKill)
{
try
{
@@ -718,7 +711,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
try
{
process.StandardInput.WriteLine("q");
process.Process.StandardInput.WriteLine("q");
}
catch (Exception)
{
@@ -727,7 +720,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
try
{
if (process.WaitForExit(waitTimeMs))
if (process.Process.WaitForExit(waitTimeMs))
{
return;
}
@@ -739,7 +732,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (enableForceKill)
{
process.Kill();
process.Process .Kill();
}
}
catch (Exception ex)
@@ -750,7 +743,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private void StopProcesses()
{
List<Process> proceses;
List<ProcessWrapper> proceses;
lock (_runningProcesses)
{
proceses = _runningProcesses.ToList();
@@ -782,5 +775,36 @@ namespace MediaBrowser.MediaEncoding.Encoder
StopProcesses();
}
}
private class ProcessWrapper
{
public readonly Process Process;
public bool HasExited;
public int? ExitCode;
private readonly MediaEncoder _mediaEncoder;
public ProcessWrapper(Process process, MediaEncoder mediaEncoder)
{
Process = process;
this._mediaEncoder = mediaEncoder;
Process.Exited += Process_Exited;
}
void Process_Exited(object sender, EventArgs e)
{
var process = (Process)sender;
HasExited = true;
ExitCode = process.ExitCode;
lock (_mediaEncoder._runningProcesses)
{
_mediaEncoder._runningProcesses.Remove(this);
}
process.Dispose();
}
}
}
}