|
|
|
@ -1,3 +1,4 @@ |
|
|
|
|
|
|
|
using System.Diagnostics; |
|
|
|
using System.Diagnostics.CodeAnalysis; |
|
|
|
using System.Diagnostics.CodeAnalysis; |
|
|
|
using System.IO.Abstractions; |
|
|
|
using System.IO.Abstractions; |
|
|
|
using System.Security.Cryptography; |
|
|
|
using System.Security.Cryptography; |
|
|
|
@ -11,6 +12,7 @@ using ErsatzTV.Core.Domain; |
|
|
|
using ErsatzTV.Core.Extensions; |
|
|
|
using ErsatzTV.Core.Extensions; |
|
|
|
using ErsatzTV.Infrastructure.Data; |
|
|
|
using ErsatzTV.Infrastructure.Data; |
|
|
|
using ErsatzTV.Infrastructure.Extensions; |
|
|
|
using ErsatzTV.Infrastructure.Extensions; |
|
|
|
|
|
|
|
using Humanizer; |
|
|
|
using Microsoft.EntityFrameworkCore; |
|
|
|
using Microsoft.EntityFrameworkCore; |
|
|
|
using Microsoft.Extensions.Logging; |
|
|
|
using Microsoft.Extensions.Logging; |
|
|
|
|
|
|
|
|
|
|
|
@ -97,6 +99,8 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem |
|
|
|
{ |
|
|
|
{ |
|
|
|
foreach (List<Subtitle> allSubtitles in GetSubtitles(mediaItem)) |
|
|
|
foreach (List<Subtitle> allSubtitles in GetSubtitles(mediaItem)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
var sw = Stopwatch.StartNew(); |
|
|
|
|
|
|
|
|
|
|
|
var subtitlesToExtract = new List<SubtitleToExtract>(); |
|
|
|
var subtitlesToExtract = new List<SubtitleToExtract>(); |
|
|
|
|
|
|
|
|
|
|
|
// find each subtitle that needs extraction
|
|
|
|
// find each subtitle that needs extraction
|
|
|
|
@ -129,6 +133,11 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem |
|
|
|
.Add("-hide_banner") |
|
|
|
.Add("-hide_banner") |
|
|
|
.Add("-i").Add(mediaItemPath); |
|
|
|
.Add("-i").Add(mediaItemPath); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var subtitleIndexes = subtitlesToExtract |
|
|
|
|
|
|
|
.OrderBy(s => s.Subtitle.StreamIndex) |
|
|
|
|
|
|
|
.Select(s => s.Subtitle.StreamIndex) |
|
|
|
|
|
|
|
.ToList(); |
|
|
|
|
|
|
|
|
|
|
|
foreach (SubtitleToExtract subtitle in subtitlesToExtract) |
|
|
|
foreach (SubtitleToExtract subtitle in subtitlesToExtract) |
|
|
|
{ |
|
|
|
{ |
|
|
|
string fullOutputPath = Path.Combine(FileSystemLayout.SubtitleCacheFolder, subtitle.OutputPath); |
|
|
|
string fullOutputPath = Path.Combine(FileSystemLayout.SubtitleCacheFolder, subtitle.OutputPath); |
|
|
|
@ -138,7 +147,7 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem |
|
|
|
File.Delete(fullOutputPath); |
|
|
|
File.Delete(fullOutputPath); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
args.Add("-map").Add($"0:{subtitle.Subtitle.StreamIndex}") |
|
|
|
args.Add("-map").Add($"0:s:{subtitleIndexes.IndexOf(subtitle.Subtitle.StreamIndex)}") |
|
|
|
.Add("-c:s").Add(subtitle.Subtitle.Codec == "mov_text" ? "text" : "copy") |
|
|
|
.Add("-c:s").Add(subtitle.Subtitle.Codec == "mov_text" ? "text" : "copy") |
|
|
|
.Add(fullOutputPath); |
|
|
|
.Add(fullOutputPath); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -148,6 +157,8 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem |
|
|
|
.WithValidation(CommandResultValidation.None) |
|
|
|
.WithValidation(CommandResultValidation.None) |
|
|
|
.ExecuteBufferedAsync(cancellationToken); |
|
|
|
.ExecuteBufferedAsync(cancellationToken); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sw.Stop(); |
|
|
|
|
|
|
|
|
|
|
|
if (result.ExitCode == 0) |
|
|
|
if (result.ExitCode == 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
foreach (SubtitleToExtract subtitle in subtitlesToExtract) |
|
|
|
foreach (SubtitleToExtract subtitle in subtitlesToExtract) |
|
|
|
@ -157,11 +168,17 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem |
|
|
|
new { SubtitleId = subtitle.Subtitle.Id, Path = subtitle.OutputPath }); |
|
|
|
new { SubtitleId = subtitle.Subtitle.Id, Path = subtitle.OutputPath }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
logger.LogDebug("Successfully extracted {Count} subtitles", subtitlesToExtract.Count); |
|
|
|
logger.LogDebug( |
|
|
|
|
|
|
|
"Successfully extracted {Count} subtitles in {Duration}", |
|
|
|
|
|
|
|
subtitlesToExtract.Count, |
|
|
|
|
|
|
|
sw.Elapsed.Humanize()); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
logger.LogError("Failed to extract subtitles. {Error}", result.StandardError); |
|
|
|
logger.LogError( |
|
|
|
|
|
|
|
"Failed to extract subtitles in {Duration}. {Error}", |
|
|
|
|
|
|
|
sw.Elapsed.Humanize(), |
|
|
|
|
|
|
|
result.StandardError); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -300,7 +317,7 @@ public abstract class ExtractEmbeddedSubtitlesHandlerBase(IFileSystem fileSystem |
|
|
|
{ |
|
|
|
{ |
|
|
|
foreach (string path in GetRelativeOutputPath(mediaItemId, subtitle)) |
|
|
|
foreach (string path in GetRelativeOutputPath(mediaItemId, subtitle)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return !fileSystem.File.Exists(path); |
|
|
|
return !fileSystem.File.Exists(Path.Combine(FileSystemLayout.SubtitleCacheFolder, path)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|