mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-04-24 22:17:25 -04:00
re-enable sync
This commit is contained in:
parent
e9fd871069
commit
00b5150999
7 changed files with 128 additions and 23 deletions
|
@ -82,5 +82,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool IsVideoEncoder
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancellationToken.Register(() => Cancel(process, encodingJob));
|
||||||
|
|
||||||
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
|
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
|
||||||
process.BeginOutputReadLine();
|
process.BeginOutputReadLine();
|
||||||
|
|
||||||
|
@ -157,6 +159,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return encodingJob;
|
return encodingJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Cancel(Process process, EncodingJob job)
|
||||||
|
{
|
||||||
|
Logger.Info("Killing ffmpeg process for {0}", job.OutputFilePath);
|
||||||
|
|
||||||
|
//process.Kill();
|
||||||
|
process.StandardInput.WriteLine("q");
|
||||||
|
|
||||||
|
job.IsCancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes the exited.
|
/// Processes the exited.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -169,25 +181,53 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
Logger.Debug("Disposing stream resources");
|
Logger.Debug("Disposing stream resources");
|
||||||
job.Dispose();
|
job.Dispose();
|
||||||
|
|
||||||
|
var isSuccesful = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Info("FFMpeg exited with code {0}", process.ExitCode);
|
var exitCode = process.ExitCode;
|
||||||
|
Logger.Info("FFMpeg exited with code {0}", exitCode);
|
||||||
|
|
||||||
|
isSuccesful = exitCode == 0;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.Error("FFMpeg exited with an error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSuccesful && !job.IsCancelled)
|
||||||
|
{
|
||||||
|
job.TaskCompletionSource.TrySetResult(true);
|
||||||
|
}
|
||||||
|
else if (job.IsCancelled)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
job.TaskCompletionSource.TrySetResult(true);
|
DeleteFiles(job);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
job.TaskCompletionSource.TrySetException(new OperationCanceledException());
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
else
|
||||||
{
|
{
|
||||||
Logger.Error("FFMpeg exited with an error.");
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
job.TaskCompletionSource.TrySetException(new ApplicationException());
|
DeleteFiles(job);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
job.TaskCompletionSource.TrySetException(new ApplicationException("Encoding failed"));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -206,6 +246,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void DeleteFiles(EncodingJob job)
|
||||||
|
{
|
||||||
|
File.Delete(job.OutputFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnTranscodeBeginning(EncodingJob job)
|
private void OnTranscodeBeginning(EncodingJob job)
|
||||||
{
|
{
|
||||||
job.ReportTranscodingProgress(null, null, null, null);
|
job.ReportTranscodingProgress(null, null, null, null);
|
||||||
|
@ -219,10 +264,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool IsVideoEncoder
|
protected abstract bool IsVideoEncoder { get; }
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual string GetWorkingDirectory(EncodingJobOptions options)
|
protected virtual string GetWorkingDirectory(EncodingJobOptions options)
|
||||||
{
|
{
|
||||||
|
@ -263,6 +305,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
protected int GetNumberOfThreads(EncodingJob job, bool isWebm)
|
protected int GetNumberOfThreads(EncodingJob job, bool isWebm)
|
||||||
{
|
{
|
||||||
|
// Only need one thread for sync
|
||||||
|
if (job.Options.Context == EncodingContext.Static)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (isWebm)
|
if (isWebm)
|
||||||
{
|
{
|
||||||
// Recommended per docs
|
// Recommended per docs
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
public class EncodingJob : IDisposable
|
public class EncodingJob : IDisposable
|
||||||
{
|
{
|
||||||
public bool HasExited { get; internal set; }
|
public bool HasExited { get; internal set; }
|
||||||
|
public bool IsCancelled { get; internal set; }
|
||||||
|
|
||||||
public Stream LogFileStream { get; set; }
|
public Stream LogFileStream { get; set; }
|
||||||
public IProgress<double> Progress { get; set; }
|
public IProgress<double> Progress { get; set; }
|
||||||
|
@ -399,6 +400,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
// job.Framerate = framerate;
|
// job.Framerate = framerate;
|
||||||
|
|
||||||
|
if (!percentComplete.HasValue && ticks.HasValue && RunTimeTicks.HasValue)
|
||||||
|
{
|
||||||
|
var pct = ticks.Value/RunTimeTicks.Value;
|
||||||
|
percentComplete = pct*100;
|
||||||
|
}
|
||||||
|
|
||||||
if (percentComplete.HasValue)
|
if (percentComplete.HasValue)
|
||||||
{
|
{
|
||||||
Progress.Report(percentComplete.Value);
|
Progress.Report(percentComplete.Value);
|
||||||
|
|
|
@ -173,5 +173,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool IsVideoEncoder
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Common.Progress;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
|
@ -337,7 +338,9 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
await ProcessJobItem(item, cancellationToken).ConfigureAwait(false);
|
var innerProgress = new ActionableProgress<double>();
|
||||||
|
|
||||||
|
await ProcessJobItem(item, innerProgress, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var job = _syncRepo.GetJob(item.JobId);
|
var job = _syncRepo.GetJob(item.JobId);
|
||||||
await UpdateJobStatus(job).ConfigureAwait(false);
|
await UpdateJobStatus(job).ConfigureAwait(false);
|
||||||
|
@ -346,7 +349,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProcessJobItem(SyncJobItem jobItem, CancellationToken cancellationToken)
|
private async Task ProcessJobItem(SyncJobItem jobItem, IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(jobItem.ItemId);
|
var item = _libraryManager.GetItemById(jobItem.ItemId);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
|
@ -372,12 +375,12 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
var video = item as Video;
|
var video = item as Video;
|
||||||
if (video != null)
|
if (video != null)
|
||||||
{
|
{
|
||||||
await Sync(jobItem, video, deviceProfile, cancellationToken).ConfigureAwait(false);
|
await Sync(jobItem, video, deviceProfile, progress, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (item is Audio)
|
else if (item is Audio)
|
||||||
{
|
{
|
||||||
await Sync(jobItem, (Audio)item, deviceProfile, cancellationToken).ConfigureAwait(false);
|
await Sync(jobItem, (Audio)item, deviceProfile, progress, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (item is Photo)
|
else if (item is Photo)
|
||||||
|
@ -391,7 +394,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, CancellationToken cancellationToken)
|
private async Task Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var options = new VideoOptions
|
var options = new VideoOptions
|
||||||
{
|
{
|
||||||
|
@ -412,7 +415,26 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
jobItem.Status = SyncJobItemStatus.Converting;
|
jobItem.Status = SyncJobItemStatus.Converting;
|
||||||
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
|
||||||
jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, profile), new Progress<double>(), cancellationToken);
|
try
|
||||||
|
{
|
||||||
|
jobItem.OutputPath = await _mediaEncoder.EncodeVideo(new EncodingJobOptions(streamInfo, profile), progress,
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
jobItem.Status = SyncJobItemStatus.Queued;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
jobItem.Status = SyncJobItemStatus.Failed;
|
||||||
|
_logger.ErrorException("Error during sync transcoding", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jobItem.Status == SyncJobItemStatus.Failed || jobItem.Status == SyncJobItemStatus.Queued)
|
||||||
|
{
|
||||||
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -435,7 +457,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Sync(SyncJobItem jobItem, Audio item, DeviceProfile profile, CancellationToken cancellationToken)
|
private async Task Sync(SyncJobItem jobItem, Audio item, DeviceProfile profile, IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var options = new AudioOptions
|
var options = new AudioOptions
|
||||||
{
|
{
|
||||||
|
@ -455,8 +477,26 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
{
|
{
|
||||||
jobItem.Status = SyncJobItemStatus.Converting;
|
jobItem.Status = SyncJobItemStatus.Converting;
|
||||||
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
|
||||||
jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile), new Progress<double>(), cancellationToken);
|
try
|
||||||
|
{
|
||||||
|
jobItem.OutputPath = await _mediaEncoder.EncodeAudio(new EncodingJobOptions(streamInfo, profile), progress, cancellationToken);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
jobItem.Status = SyncJobItemStatus.Queued;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
jobItem.Status = SyncJobItemStatus.Failed;
|
||||||
|
_logger.ErrorException("Error during sync transcoding", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jobItem.Status == SyncJobItemStatus.Failed || jobItem.Status == SyncJobItemStatus.Queued)
|
||||||
|
{
|
||||||
|
await _syncRepo.Update(jobItem).ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||||
|
|
||||||
public bool IsHidden
|
public bool IsHidden
|
||||||
{
|
{
|
||||||
get { return true; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEnabled
|
public bool IsEnabled
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
//[assembly: AssemblyVersion("3.0.*")]
|
[assembly: AssemblyVersion("3.0.*")]
|
||||||
[assembly: AssemblyVersion("3.0.5482.1")]
|
//[assembly: AssemblyVersion("3.0.5482.1")]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue