mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 11:34:57 +02:00
Merge pull request #6084 from Bond-009/nullable5
Enable nullable reference types for MediaBrowser.MediaEncoding
This commit is contained in:
commit
8046143158
18 changed files with 65 additions and 52 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
#nullable disable
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
|
@ -9,9 +9,9 @@ namespace MediaBrowser.MediaEncoding.BdInfo
|
||||||
{
|
{
|
||||||
public class BdInfoDirectoryInfo : IDirectoryInfo
|
public class BdInfoDirectoryInfo : IDirectoryInfo
|
||||||
{
|
{
|
||||||
private readonly IFileSystem _fileSystem = null;
|
private readonly IFileSystem _fileSystem;
|
||||||
|
|
||||||
private readonly FileSystemMetadata _impl = null;
|
private readonly FileSystemMetadata _impl;
|
||||||
|
|
||||||
public BdInfoDirectoryInfo(IFileSystem fileSystem, string path)
|
public BdInfoDirectoryInfo(IFileSystem fileSystem, string path)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ namespace MediaBrowser.MediaEncoding.BdInfo
|
||||||
|
|
||||||
public string FullName => _impl.FullName;
|
public string FullName => _impl.FullName;
|
||||||
|
|
||||||
public IDirectoryInfo Parent
|
public IDirectoryInfo? Parent
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace MediaBrowser.MediaEncoding.BdInfo
|
||||||
{
|
{
|
||||||
public class BdInfoFileInfo : BDInfo.IO.IFileInfo
|
public class BdInfoFileInfo : BDInfo.IO.IFileInfo
|
||||||
{
|
{
|
||||||
private FileSystemMetadata _impl = null;
|
private FileSystemMetadata _impl;
|
||||||
|
|
||||||
public BdInfoFileInfo(FileSystemMetadata impl)
|
public BdInfoFileInfo(FileSystemMetadata impl)
|
||||||
{
|
{
|
||||||
|
|
|
@ -121,11 +121,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
// When changing this, also change the minimum library versions in _ffmpegMinimumLibraryVersions
|
// When changing this, also change the minimum library versions in _ffmpegMinimumLibraryVersions
|
||||||
public static Version MinVersion { get; } = new Version(4, 0);
|
public static Version MinVersion { get; } = new Version(4, 0);
|
||||||
|
|
||||||
public static Version MaxVersion { get; } = null;
|
public static Version? MaxVersion { get; } = null;
|
||||||
|
|
||||||
public bool ValidateVersion()
|
public bool ValidateVersion()
|
||||||
{
|
{
|
||||||
string output = null;
|
string output;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
output = GetProcessOutput(_encoderPath, "-version");
|
output = GetProcessOutput(_encoderPath, "-version");
|
||||||
|
@ -133,6 +133,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error validating encoder");
|
_logger.LogError(ex, "Error validating encoder");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(output))
|
if (string.IsNullOrWhiteSpace(output))
|
||||||
|
@ -207,7 +208,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="output">The output from "ffmpeg -version".</param>
|
/// <param name="output">The output from "ffmpeg -version".</param>
|
||||||
/// <returns>The FFmpeg version.</returns>
|
/// <returns>The FFmpeg version.</returns>
|
||||||
internal Version GetFFmpegVersion(string output)
|
internal Version? GetFFmpegVersion(string output)
|
||||||
{
|
{
|
||||||
// For pre-built binaries the FFmpeg version should be mentioned at the very start of the output
|
// For pre-built binaries the FFmpeg version should be mentioned at the very start of the output
|
||||||
var match = Regex.Match(output, @"^ffmpeg version n?((?:[0-9]+\.?)+)");
|
var match = Regex.Match(output, @"^ffmpeg version n?((?:[0-9]+\.?)+)");
|
||||||
|
@ -275,7 +276,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
|
|
||||||
private IEnumerable<string> GetHwaccelTypes()
|
private IEnumerable<string> GetHwaccelTypes()
|
||||||
{
|
{
|
||||||
string output = null;
|
string? output = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
output = GetProcessOutput(_encoderPath, "-hwaccels");
|
output = GetProcessOutput(_encoderPath, "-hwaccels");
|
||||||
|
@ -303,7 +304,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string output = null;
|
string output;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
output = GetProcessOutput(_encoderPath, "-h filter=" + filter);
|
output = GetProcessOutput(_encoderPath, "-h filter=" + filter);
|
||||||
|
@ -311,6 +312,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error detecting the given filter");
|
_logger.LogError(ex, "Error detecting the given filter");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output.Contains("Filter " + filter, StringComparison.Ordinal))
|
if (output.Contains("Filter " + filter, StringComparison.Ordinal))
|
||||||
|
@ -331,7 +333,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
private IEnumerable<string> GetCodecs(Codec codec)
|
private IEnumerable<string> GetCodecs(Codec codec)
|
||||||
{
|
{
|
||||||
string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
|
string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
|
||||||
string output = null;
|
string output;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
output = GetProcessOutput(_encoderPath, "-" + codecstr);
|
output = GetProcessOutput(_encoderPath, "-" + codecstr);
|
||||||
|
@ -339,6 +341,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error detecting available {Codec}", codecstr);
|
_logger.LogError(ex, "Error detecting available {Codec}", codecstr);
|
||||||
|
return Enumerable.Empty<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(output))
|
if (string.IsNullOrWhiteSpace(output))
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#nullable disable
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#nullable disable
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#nullable disable
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Nikse.SubtitleEdit.Core.SubtitleFormats;
|
using Nikse.SubtitleEdit.Core.SubtitleFormats;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#nullable enable
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
namespace MediaBrowser.MediaEncoding.Subtitles
|
namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Nikse.SubtitleEdit.Core.SubtitleFormats;
|
using Nikse.SubtitleEdit.Core.SubtitleFormats;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Nikse.SubtitleEdit.Core.SubtitleFormats;
|
using Nikse.SubtitleEdit.Core.SubtitleFormats;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#nullable enable
|
|
||||||
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -71,8 +72,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var reader = GetReader(inputFormat, true);
|
var reader = GetReader(inputFormat);
|
||||||
|
|
||||||
var trackInfo = reader.Parse(stream, cancellationToken);
|
var trackInfo = reader.Parse(stream, cancellationToken);
|
||||||
|
|
||||||
FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps);
|
FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps);
|
||||||
|
@ -139,10 +139,9 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
var inputFormat = subtitle.format;
|
var inputFormat = subtitle.format;
|
||||||
var writer = TryGetWriter(outputFormat);
|
|
||||||
|
|
||||||
// Return the original if we don't have any way of converting it
|
// Return the original if we don't have any way of converting it
|
||||||
if (writer == null)
|
if (!TryGetWriter(outputFormat, out var writer))
|
||||||
{
|
{
|
||||||
return subtitle.stream;
|
return subtitle.stream;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +238,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec)
|
var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec)
|
||||||
.TrimStart('.');
|
.TrimStart('.');
|
||||||
|
|
||||||
if (GetReader(currentFormat, false) == null)
|
if (TryGetReader(currentFormat, out _))
|
||||||
{
|
{
|
||||||
// Convert
|
// Convert
|
||||||
var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, ".srt");
|
var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, ".srt");
|
||||||
|
@ -257,37 +256,41 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
return new SubtitleInfo(subtitleStream.Path, mediaSource.Protocol, currentFormat, true);
|
return new SubtitleInfo(subtitleStream.Path, mediaSource.Protocol, currentFormat, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISubtitleParser GetReader(string format, bool throwIfMissing)
|
private bool TryGetReader(string format, [NotNullWhen(true)] out ISubtitleParser? value)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(format))
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(format));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new SrtParser(_logger);
|
value = new SrtParser(_logger);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(format, SubtitleFormat.SSA, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(format, SubtitleFormat.SSA, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new SsaParser(_logger);
|
value = new SsaParser(_logger);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new AssParser(_logger);
|
value = new AssParser(_logger);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (throwIfMissing)
|
value = null;
|
||||||
{
|
return false;
|
||||||
throw new ArgumentException("Unsupported format: " + format);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISubtitleWriter TryGetWriter(string format)
|
private ISubtitleParser GetReader(string format)
|
||||||
|
{
|
||||||
|
if (TryGetReader(format, out var reader))
|
||||||
|
{
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException("Unsupported format: " + format);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetWriter(string format, [NotNullWhen(true)] out ISubtitleWriter? value)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(format))
|
if (string.IsNullOrEmpty(format))
|
||||||
{
|
{
|
||||||
|
@ -296,32 +299,35 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
|
|
||||||
if (string.Equals(format, "json", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(format, "json", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new JsonWriter();
|
value = new JsonWriter();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new SrtWriter();
|
value = new SrtWriter();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(format, SubtitleFormat.VTT, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(format, SubtitleFormat.VTT, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new VttWriter();
|
value = new VttWriter();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.Equals(format, SubtitleFormat.TTML, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(format, SubtitleFormat.TTML, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new TtmlWriter();
|
value = new TtmlWriter();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
value = null;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISubtitleWriter GetWriter(string format)
|
private ISubtitleWriter GetWriter(string format)
|
||||||
{
|
{
|
||||||
var writer = TryGetWriter(format);
|
if (TryGetWriter(format, out var writer))
|
||||||
|
|
||||||
if (writer != null)
|
|
||||||
{
|
{
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
@ -391,7 +397,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
throw new ArgumentNullException(nameof(outputPath));
|
throw new ArgumentNullException(nameof(outputPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
|
Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)));
|
||||||
|
|
||||||
var encodingParam = await GetSubtitleFileCharacterSet(inputPath, language, mediaSource.Protocol, cancellationToken).ConfigureAwait(false);
|
var encodingParam = await GetSubtitleFileCharacterSet(inputPath, language, mediaSource.Protocol, cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
|
@ -549,7 +555,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
throw new ArgumentNullException(nameof(outputPath));
|
throw new ArgumentNullException(nameof(outputPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
|
Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new ArgumentException($"Provided path ({outputPath}) is not valid.", nameof(outputPath)));
|
||||||
|
|
||||||
var processArgs = string.Format(
|
var processArgs = string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
|
@ -715,7 +721,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
{
|
{
|
||||||
using (var stream = await GetStream(path, protocol, cancellationToken).ConfigureAwait(false))
|
using (var stream = await GetStream(path, protocol, cancellationToken).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName;
|
var charset = CharsetDetector.DetectFromStream(stream).Detected?.EncodingName ?? string.Empty;
|
||||||
|
|
||||||
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
|
// UTF16 is automatically converted to UTF8 by FFmpeg, do not specify a character encoding
|
||||||
if ((path.EndsWith(".ass", StringComparison.Ordinal) || path.EndsWith(".ssa", StringComparison.Ordinal) || path.EndsWith(".srt", StringComparison.Ordinal))
|
if ((path.EndsWith(".ass", StringComparison.Ordinal) || path.EndsWith(".ssa", StringComparison.Ordinal) || path.EndsWith(".srt", StringComparison.Ordinal))
|
||||||
|
@ -725,7 +731,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
charset = string.Empty;
|
charset = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("charset {0} detected for {Path}", charset ?? "null", path);
|
_logger.LogDebug("charset {0} detected for {Path}", charset, path);
|
||||||
|
|
||||||
return charset;
|
return charset;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue