aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua M. Boniface <joshua@boniface.me>2020-08-05 00:00:15 -0400
committerGitHub <noreply@github.com>2020-08-05 00:00:15 -0400
commit3e974c03519edd5ceb262a475a8b35ff2839add6 (patch)
treed18dd39b10c85733c66dc4ce619a304a0087ca03
parentff4489575b0b29638285a0cf255289134900009f (diff)
parent393666efcfa85e858857334b5cb5a3ec70586f20 (diff)
Merge pull request #3825 from crobibero/api-merge-again
Merge master into api-migration
-rw-r--r--.ci/azure-pipelines-abi.yml28
-rw-r--r--.ci/azure-pipelines-package.yml19
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs58
-rw-r--r--Emby.Server.Implementations/HttpServer/HttpListenerHost.cs2
-rw-r--r--Emby.Server.Implementations/HttpServer/WebSocketConnection.cs8
-rw-r--r--Jellyfin.Api/Controllers/DynamicHlsController.cs2
-rw-r--r--Jellyfin.Api/Controllers/SubtitleController.cs3
-rw-r--r--Jellyfin.Server.Implementations/Activity/ActivityManager.cs5
-rw-r--r--MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs2
-rw-r--r--MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs19
-rw-r--r--MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs4
-rw-r--r--MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs19
-rw-r--r--MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs34
-rw-r--r--MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationStore.cs38
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs32
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs77
-rw-r--r--MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj13
-rw-r--r--MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs3
-rw-r--r--MediaBrowser.MediaEncoding/Probing/MediaChapter.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs4
-rw-r--r--MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs67
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/AssParser.cs21
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs2
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs14
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs62
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs4
-rw-r--r--MediaBrowser.Providers/Manager/ImageSaver.cs4
-rw-r--r--MediaBrowser.Providers/Manager/ProviderManager.cs4
-rw-r--r--README.md2
-rw-r--r--RSSDP/RSSDP.csproj2
31 files changed, 316 insertions, 240 deletions
diff --git a/.ci/azure-pipelines-abi.yml b/.ci/azure-pipelines-abi.yml
index 635aa759c..b558d2a6f 100644
--- a/.ci/azure-pipelines-abi.yml
+++ b/.ci/azure-pipelines-abi.yml
@@ -12,10 +12,12 @@ parameters:
jobs:
- job: CompatibilityCheck
displayName: Compatibility Check
+ dependsOn: Build
+ condition: and(succeeded(), variables['System.PullRequest.PullRequestNumber'])
+
pool:
vmImage: "${{ parameters.LinuxImage }}"
- # only execute for pull requests
- condition: and(succeeded(), variables['System.PullRequest.PullRequestNumber'])
+
strategy:
matrix:
${{ each Package in parameters.Packages }}:
@@ -23,7 +25,7 @@ jobs:
NugetPackageName: ${{ Package.value.NugetPackageName }}
AssemblyFileName: ${{ Package.value.AssemblyFileName }}
maxParallel: 2
- dependsOn: Build
+
steps:
- checkout: none
@@ -34,32 +36,33 @@ jobs:
version: ${{ parameters.DotNetSdkVersion }}
- task: DotNetCoreCLI@2
- displayName: 'Install ABI CompatibilityChecker tool'
+ displayName: 'Install ABI CompatibilityChecker Tool'
inputs:
command: custom
custom: tool
arguments: 'update compatibilitychecker -g'
- task: DownloadPipelineArtifact@2
- displayName: "Download New Assembly Build Artifact"
+ displayName: 'Download New Assembly Build Artifact'
inputs:
- source: "current"
+ source: 'current'
artifact: "$(NugetPackageName)"
path: "$(System.ArtifactsDirectory)/new-artifacts"
runVersion: "latest"
- task: CopyFiles@2
- displayName: "Copy New Assembly Build Artifact"
+ displayName: 'Copy New Assembly Build Artifact'
inputs:
sourceFolder: $(System.ArtifactsDirectory)/new-artifacts
- contents: "**/*.dll"
+ contents: '**/*.dll'
targetFolder: $(System.ArtifactsDirectory)/new-release
cleanTargetFolder: true
overWrite: true
flattenFolders: true
- task: DownloadPipelineArtifact@2
- displayName: "Download Reference Assembly Build Artifact"
+ displayName: 'Download Reference Assembly Build Artifact'
+ enabled: false
inputs:
source: "specific"
artifact: "$(NugetPackageName)"
@@ -70,18 +73,19 @@ jobs:
runBranch: "refs/heads/$(System.PullRequest.TargetBranch)"
- task: CopyFiles@2
- displayName: "Copy Reference Assembly Build Artifact"
+ displayName: 'Copy Reference Assembly Build Artifact'
+ enabled: false
inputs:
sourceFolder: $(System.ArtifactsDirectory)/current-artifacts
- contents: "**/*.dll"
+ contents: '**/*.dll'
targetFolder: $(System.ArtifactsDirectory)/current-release
cleanTargetFolder: true
overWrite: true
flattenFolders: true
- # The `--warnings-only` switch will swallow the return code and not emit any errors.
- task: DotNetCoreCLI@2
displayName: 'Execute ABI Compatibility Check Tool'
+ enabled: false
inputs:
command: custom
custom: compat
diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml
index 1677f71c7..003d5baf0 100644
--- a/.ci/azure-pipelines-package.yml
+++ b/.ci/azure-pipelines-package.yml
@@ -116,6 +116,7 @@ jobs:
$(JellyfinVersion)-$(BuildConfiguration)
- job: CollectArtifacts
+ timeoutInMinutes: 10
displayName: 'Collect Artifacts'
dependsOn:
- BuildPackage
@@ -131,29 +132,23 @@ jobs:
condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/master')
inputs:
sshEndpoint: repository
- runOptions: 'inline'
- inline: |
- sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber) unstable
- rm $0
- exit
+ runOptions: 'commands'
+ commands: sudo -n /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber) unstable
- task: SSH@0
displayName: 'Update Stable Repository'
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags')
inputs:
sshEndpoint: repository
- runOptions: 'inline'
- inline: |
- sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber)
- rm $0
- exit
-
+ runOptions: 'commands'
+ commands: sudo -n /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber)
+
- job: PublishNuget
displayName: 'Publish NuGet packages'
dependsOn:
- BuildPackage
condition: and(succeeded('BuildPackage'), startsWith(variables['Build.SourceBranch'], 'refs/tags'))
-
+
pool:
vmImage: 'ubuntu-latest'
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 1c6d3cb94..d11e5e62e 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -978,7 +978,10 @@ namespace Emby.Server.Implementations.Data
continue;
}
- str.Append($"{i.Key}={i.Value}|");
+ str.Append(i.Key)
+ .Append('=')
+ .Append(i.Value)
+ .Append('|');
}
if (str.Length == 0)
@@ -1032,8 +1035,8 @@ namespace Emby.Server.Implementations.Data
continue;
}
- str.Append(ToValueString(i))
- .Append('|');
+ AppendItemImageInfo(str, i);
+ str.Append('|');
}
str.Length -= 1; // Remove last |
@@ -1067,26 +1070,26 @@ namespace Emby.Server.Implementations.Data
item.ImageInfos = list.ToArray();
}
- public string ToValueString(ItemImageInfo image)
+ public void AppendItemImageInfo(StringBuilder bldr, ItemImageInfo image)
{
- const string Delimeter = "*";
+ const char Delimiter = '*';
var path = image.Path ?? string.Empty;
var hash = image.BlurHash ?? string.Empty;
- return GetPathToSave(path) +
- Delimeter +
- image.DateModified.Ticks.ToString(CultureInfo.InvariantCulture) +
- Delimeter +
- image.Type +
- Delimeter +
- image.Width.ToString(CultureInfo.InvariantCulture) +
- Delimeter +
- image.Height.ToString(CultureInfo.InvariantCulture) +
- Delimeter +
- // Replace delimiters with other characters.
- // This can be removed when we migrate to a proper DB.
- hash.Replace('*', '/').Replace('|', '\\');
+ bldr.Append(GetPathToSave(path))
+ .Append(Delimiter)
+ .Append(image.DateModified.Ticks)
+ .Append(Delimiter)
+ .Append(image.Type)
+ .Append(Delimiter)
+ .Append(image.Width)
+ .Append(Delimiter)
+ .Append(image.Height)
+ .Append(Delimiter)
+ // Replace delimiters with other characters.
+ // This can be removed when we migrate to a proper DB.
+ .Append(hash.Replace('*', '/').Replace('|', '\\'));
}
public ItemImageInfo ItemImageInfoFromValueString(string value)
@@ -5659,10 +5662,10 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
const int Limit = 100;
var startIndex = 0;
+ const string StartInsertText = "insert into ItemValues (ItemId, Type, Value, CleanValue) values ";
+ var insertText = new StringBuilder(StartInsertText);
while (startIndex < values.Count)
{
- var insertText = new StringBuilder("insert into ItemValues (ItemId, Type, Value, CleanValue) values ");
-
var endIndex = Math.Min(values.Count, startIndex + Limit);
for (var i = startIndex; i < endIndex; i++)
@@ -5704,6 +5707,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
}
startIndex += Limit;
+ insertText.Length = StartInsertText.Length;
}
}
@@ -5741,10 +5745,10 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
var startIndex = 0;
var listIndex = 0;
+ const string StartInsertText = "insert into People (ItemId, Name, Role, PersonType, SortOrder, ListOrder) values ";
+ var insertText = new StringBuilder(StartInsertText);
while (startIndex < people.Count)
{
- var insertText = new StringBuilder("insert into People (ItemId, Name, Role, PersonType, SortOrder, ListOrder) values ");
-
var endIndex = Math.Min(people.Count, startIndex + Limit);
for (var i = startIndex; i < endIndex; i++)
{
@@ -5778,6 +5782,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
}
startIndex += Limit;
+ insertText.Length = StartInsertText.Length;
}
}
@@ -5893,10 +5898,9 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
const int Limit = 10;
var startIndex = 0;
+ var insertText = new StringBuilder(_mediaStreamSaveColumnsInsertQuery);
while (startIndex < streams.Count)
{
- var insertText = new StringBuilder(_mediaStreamSaveColumnsInsertQuery);
-
var endIndex = Math.Min(streams.Count, startIndex + Limit);
for (var i = startIndex; i < endIndex; i++)
@@ -5979,6 +5983,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
}
startIndex += Limit;
+ insertText.Length = _mediaStreamSaveColumnsInsertQuery.Length;
}
}
@@ -6230,10 +6235,9 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
{
const int InsertAtOnce = 10;
+ var insertText = new StringBuilder(_mediaAttachmentInsertPrefix);
for (var startIndex = 0; startIndex < attachments.Count; startIndex += InsertAtOnce)
{
- var insertText = new StringBuilder(_mediaAttachmentInsertPrefix);
-
var endIndex = Math.Min(attachments.Count, startIndex + InsertAtOnce);
for (var i = startIndex; i < endIndex; i++)
@@ -6279,6 +6283,8 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
statement.Reset();
statement.MoveNext();
}
+
+ insertText.Length = _mediaAttachmentInsertPrefix.Length;
}
}
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 0d4a789b5..dafdd5b7b 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -567,7 +567,7 @@ namespace Emby.Server.Implementations.HttpServer
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
- var connection = new WebSocketConnection(
+ using var connection = new WebSocketConnection(
_loggerFactory.CreateLogger<WebSocketConnection>(),
webSocket,
context.Connection.RemoteIpAddress,
diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
index 316cd84cf..d738047e0 100644
--- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
+++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
@@ -19,7 +19,7 @@ namespace Emby.Server.Implementations.HttpServer
/// <summary>
/// Class WebSocketConnection.
/// </summary>
- public class WebSocketConnection : IWebSocketConnection
+ public class WebSocketConnection : IWebSocketConnection, IDisposable
{
/// <summary>
/// The logger.
@@ -119,7 +119,7 @@ namespace Emby.Server.Implementations.HttpServer
Memory<byte> memory = writer.GetMemory(512);
try
{
- receiveresult = await _socket.ReceiveAsync(memory, cancellationToken);
+ receiveresult = await _socket.ReceiveAsync(memory, cancellationToken).ConfigureAwait(false);
}
catch (WebSocketException ex)
{
@@ -137,7 +137,7 @@ namespace Emby.Server.Implementations.HttpServer
writer.Advance(bytesRead);
// Make the data available to the PipeReader
- FlushResult flushResult = await writer.FlushAsync();
+ FlushResult flushResult = await writer.FlushAsync().ConfigureAwait(false);
if (flushResult.IsCompleted)
{
// The PipeReader stopped reading
@@ -223,7 +223,7 @@ namespace Emby.Server.Implementations.HttpServer
if (info.MessageType.Equals("KeepAlive", StringComparison.Ordinal))
{
- await SendKeepAliveResponse();
+ await SendKeepAliveResponse().ConfigureAwait(false);
}
else
{
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs
index ec65cb95a..f6f08e873 100644
--- a/Jellyfin.Api/Controllers/DynamicHlsController.cs
+++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs
@@ -1828,7 +1828,7 @@ namespace Jellyfin.Api.Controllers
}
audioTranscodeParams.Add("-vn");
- return string.Join(" ", audioTranscodeParams.ToArray());
+ return string.Join(' ', audioTranscodeParams);
}
if (EncodingHelper.IsCopyCodec(audioCodec))
diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs
index 22144ab1a..d5633fba5 100644
--- a/Jellyfin.Api/Controllers/SubtitleController.cs
+++ b/Jellyfin.Api/Controllers/SubtitleController.cs
@@ -262,8 +262,6 @@ namespace Jellyfin.Api.Controllers
var mediaSource = await _mediaSourceManager.GetMediaSource(item, mediaSourceId, null, false, CancellationToken.None).ConfigureAwait(false);
- var builder = new StringBuilder();
-
var runtime = mediaSource.RunTimeTicks ?? -1;
if (runtime <= 0)
@@ -277,6 +275,7 @@ namespace Jellyfin.Api.Controllers
throw new ArgumentException("segmentLength was not given, or it was given incorrectly. (It should be bigger than 0)");
}
+ var builder = new StringBuilder();
builder.AppendLine("#EXTM3U")
.Append("#EXT-X-TARGETDURATION:")
.AppendLine(segmentLength.ToString(CultureInfo.InvariantCulture))
diff --git a/Jellyfin.Server.Implementations/Activity/ActivityManager.cs b/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
index 65ceee32b..2deefbe81 100644
--- a/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
+++ b/Jellyfin.Server.Implementations/Activity/ActivityManager.cs
@@ -40,8 +40,9 @@ namespace Jellyfin.Server.Implementations.Activity
/// <inheritdoc/>
public async Task CreateAsync(ActivityLog entry)
{
- using var dbContext = _provider.CreateContext();
- await dbContext.ActivityLogs.AddAsync(entry);
+ await using var dbContext = _provider.CreateContext();
+
+ dbContext.ActivityLogs.Add(entry);
await dbContext.SaveChangesAsync().ConfigureAwait(false);
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(ConvertToOldModel(entry)));
diff --git a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
index f02999370..a8ebe6bc5 100644
--- a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
+++ b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs
index e040286ab..4a54b677d 100644
--- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs
+++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Linq;
using BDInfo.IO;
@@ -5,7 +7,7 @@ using MediaBrowser.Model.IO;
namespace MediaBrowser.MediaEncoding.BdInfo
{
- class BdInfoDirectoryInfo : IDirectoryInfo
+ public class BdInfoDirectoryInfo : IDirectoryInfo
{
private readonly IFileSystem _fileSystem = null;
@@ -43,25 +45,32 @@ namespace MediaBrowser.MediaEncoding.BdInfo
public IDirectoryInfo[] GetDirectories()
{
- return Array.ConvertAll(_fileSystem.GetDirectories(_impl.FullName).ToArray(),
+ return Array.ConvertAll(
+ _fileSystem.GetDirectories(_impl.FullName).ToArray(),
x => new BdInfoDirectoryInfo(_fileSystem, x));
}
public IFileInfo[] GetFiles()
{
- return Array.ConvertAll(_fileSystem.GetFiles(_impl.FullName).ToArray(),
+ return Array.ConvertAll(
+ _fileSystem.GetFiles(_impl.FullName).ToArray(),
x => new BdInfoFileInfo(x));
}
public IFileInfo[] GetFiles(string searchPattern)
{
- return Array.ConvertAll(_fileSystem.GetFiles(_impl.FullName, new[] { searchPattern }, false, false).ToArray(),
+ return Array.ConvertAll(
+ _fileSystem.GetFiles(_impl.FullName, new[] { searchPattern }, false, false).ToArray(),
x => new BdInfoFileInfo(x));
}
public IFileInfo[] GetFiles(string searchPattern, System.IO.SearchOption searchOption)
{
- return Array.ConvertAll(_fileSystem.GetFiles(_impl.FullName, new[] { searchPattern }, false,
+ return Array.ConvertAll(
+ _fileSystem.GetFiles(
+ _impl.FullName,
+ new[] { searchPattern },
+ false,
searchOption.HasFlag(System.IO.SearchOption.AllDirectories)).ToArray(),
x => new BdInfoFileInfo(x));
}
diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs
index ccfae2fa5..9108d9649 100644
--- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs
+++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs
@@ -15,6 +15,10 @@ namespace MediaBrowser.MediaEncoding.BdInfo
{
private readonly IFileSystem _fileSystem;
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BdInfoExaminer" /> class.
+ /// </summary>
+ /// <param name="fileSystem">The filesystem.</param>
public BdInfoExaminer(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs
index a6ff4f767..0a8af8e9c 100644
--- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs
+++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoFileInfo.cs
@@ -1,11 +1,18 @@
+#pragma warning disable CS1591
+
using System.IO;
using MediaBrowser.Model.IO;
namespace MediaBrowser.MediaEncoding.BdInfo
{
- class BdInfoFileInfo : BDInfo.IO.IFileInfo
+ public class BdInfoFileInfo : BDInfo.IO.IFileInfo
{
- FileSystemMetadata _impl = null;
+ private FileSystemMetadata _impl = null;
+
+ public BdInfoFileInfo(FileSystemMetadata impl)
+ {
+ _impl = impl;
+ }
public string Name => _impl.Name;
@@ -17,14 +24,10 @@ namespace MediaBrowser.MediaEncoding.BdInfo
public bool IsDir => _impl.IsDirectory;
- public BdInfoFileInfo(FileSystemMetadata impl)
- {
- _impl = impl;
- }
-
public System.IO.Stream OpenRead()
{
- return new FileStream(FullName,
+ return new FileStream(
+ FullName,
FileMode.Open,
FileAccess.Read,
FileShare.Read);
diff --git a/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs b/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs
index 75534b5bd..f81a337db 100644
--- a/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs
+++ b/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs
@@ -1,9 +1,7 @@
-using System;
+#pragma warning disable CS1591
+
using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
using MediaBrowser.Common.Configuration;
-using MediaBrowser.Model.Configuration;
namespace MediaBrowser.MediaEncoding.Configuration
{
@@ -17,32 +15,4 @@ namespace MediaBrowser.MediaEncoding.Configuration
};
}
}
-
- public class EncodingConfigurationStore : ConfigurationStore, IValidatingConfiguration
- {
- public EncodingConfigurationStore()
- {
- ConfigurationType = typeof(EncodingOptions);
- Key = "encoding";
- }
-
- public void Validate(object oldConfig, object newConfig)
- {
- var newPath = ((EncodingOptions)newConfig).TranscodingTempPath;
-
- if (!string.IsNullOrWhiteSpace(newPath)
- && !string.Equals(((EncodingOptions)oldConfig).TranscodingTempPath, newPath, StringComparison.Ordinal))
- {
- // Validate
- if (!Directory.Exists(newPath))
- {
- throw new DirectoryNotFoundException(
- string.Format(
- CultureInfo.InvariantCulture,
- "{0} does not exist.",
- newPath));
- }
- }
- }
- }
}
diff --git a/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationStore.cs b/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationStore.cs
new file mode 100644
index 000000000..2f158157e
--- /dev/null
+++ b/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationStore.cs
@@ -0,0 +1,38 @@
+#pragma warning disable CS1591
+
+using System;
+using System.Globalization;
+using System.IO;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.Configuration;
+
+namespace MediaBrowser.MediaEncoding.Configuration
+{
+ public class EncodingConfigurationStore : ConfigurationStore, IValidatingConfiguration
+ {
+ public EncodingConfigurationStore()
+ {
+ ConfigurationType = typeof(EncodingOptions);
+ Key = "encoding";
+ }
+
+ public void Validate(object oldConfig, object newConfig)
+ {
+ var newPath = ((EncodingOptions)newConfig).TranscodingTempPath;
+
+ if (!string.IsNullOrWhiteSpace(newPath)
+ && !string.Equals(((EncodingOptions)oldConfig).TranscodingTempPath, newPath, StringComparison.Ordinal))
+ {
+ // Validate
+ if (!Directory.Exists(newPath))
+ {
+ throw new DirectoryNotFoundException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} does not exist.",
+ newPath));
+ }
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index 5c43fdcfa..75123a843 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -12,7 +14,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
private const string DefaultEncoderPath = "ffmpeg";
- private static readonly string[] requiredDecoders = new[]
+ private static readonly string[] _requiredDecoders = new[]
{
"h264",
"hevc",
@@ -55,7 +57,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
"vc1_opencl"
};
- private static readonly string[] requiredEncoders = new[]
+ private static readonly string[] _requiredEncoders = new[]
{
"libx264",
"libx265",
@@ -110,6 +112,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
_encoderPath = encoderPath;
}
+ private enum Codec
+ {
+ Encoder,
+ Decoder
+ }
+
public static Version MinVersion { get; } = new Version(4, 0);
public static Version MaxVersion { get; } = null;
@@ -193,8 +201,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// If that fails then we use one of the main libraries to determine if it's new/older than the latest
/// we have stored.
/// </summary>
- /// <param name="output"></param>
- /// <returns></returns>
+ /// <param name="output">The output from "ffmpeg -version".</param>
+ /// <returns>The FFmpeg version.</returns>
internal static Version GetFFmpegVersion(string output)
{
// For pre-built binaries the FFmpeg version should be mentioned at the very start of the output
@@ -216,10 +224,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <summary>
/// Grabs the library names and major.minor version numbers from the 'ffmpeg -version' output
- /// and condenses them on to one line. Output format is "name1=major.minor,name2=major.minor,etc."
+ /// and condenses them on to one line. Output format is "name1=major.minor,name2=major.minor,etc.".
/// </summary>
- /// <param name="output"></param>
- /// <returns></returns>
+ /// <param name="output">The 'ffmpeg -version' output.</param>
+ /// <returns>The library names and major.minor version numbers.</returns>
private static string GetLibrariesVersionString(string output)
{
var rc = new StringBuilder(144);
@@ -239,12 +247,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
return rc.Length == 0 ? null : rc.ToString();
}
- private enum Codec
- {
- Encoder,
- Decoder
- }
-
private IEnumerable<string> GetHwaccelTypes()
{
string output = null;
@@ -262,7 +264,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return Enumerable.Empty<string>();
}
- var found = output.Split(new char[] {'\r','\n'}, StringSplitOptions.RemoveEmptyEntries).Skip(1).Distinct().ToList();
+ var found = output.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(1).Distinct().ToList();
_logger.LogInformation("Available hwaccel types: {Types}", found);
return found;
@@ -286,7 +288,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return Enumerable.Empty<string>();
}
- var required = codec == Codec.Encoder ? requiredEncoders : requiredDecoders;
+ var required = codec == Codec.Encoder ? _requiredEncoders : _requiredDecoders;
var found = Regex
.Matches(output, @"^\s\S{6}\s(?<codec>[\w|-]+)\s+.+$", RegexOptions.Multiline)
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
index d4aede572..7c2d9f1fd 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.MediaInfo;
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 62fdbc618..778c0b18c 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -1,5 +1,8 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -19,9 +22,8 @@ using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.System;
-using Microsoft.Extensions.Logging;
-using System.Diagnostics;
using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
namespace MediaBrowser.MediaEncoding.Encoder
{
@@ -35,6 +37,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary>
internal const int DefaultImageExtractionTimeout = 5000;
+ /// <summary>
+ /// The us culture.
+ /// </summary>
+ private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+
private readonly ILogger<MediaEncoder> _logger;
private readonly IServerConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
@@ -47,6 +54,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly object _runningProcessesLock = new object();
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
+ private List<string> _encoders = new List<string>();
+ private List<string> _decoders = new List<string>();
+ private List<string> _hwaccels = new List<string>();
+
private string _ffmpegPath = string.Empty;
private string _ffprobePath;
@@ -77,7 +88,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <summary>
/// Run at startup or if the user removes a Custom path from transcode page.
/// Sets global variables FFmpegPath.
- /// Precedence is: Config > CLI > $PATH
+ /// Precedence is: Config > CLI > $PATH.
/// </summary>
public void SetFFmpegPath()
{
@@ -122,8 +133,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// Triggered from the Settings > Transcoding UI page when users submits Custom FFmpeg path to use.
/// Only write the new path to xml if it exists. Do not perform validation checks on ffmpeg here.
/// </summary>
- /// <param name="path"></param>
- /// <param name="pathType"></param>
+ /// <param name="path">The path.</param>
+ /// <param name="pathType">The path type.</param>
public void UpdateEncoderPath(string path, string pathType)
{
string newPath;
@@ -168,8 +179,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// If checks pass, global variable FFmpegPath and EncoderLocation are updated.
/// </summary>
/// <param name="path">FQPN to test.</param>
- /// <param name="location">Location (External, Custom, System) of tool</param>
- /// <returns></returns>
+ /// <param name="location">Location (External, Custom, System) of tool.</param>
+ /// <returns><c>true</c> if the version validation succeeded; otherwise, <c>false</c>.</returns>
private bool ValidatePath(string path, FFmpegLocation location)
{
bool rc = false;
@@ -221,8 +232,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <summary>
/// Search the system $PATH environment variable looking for given filename.
/// </summary>
- /// <param name="fileName"></param>
- /// <returns></returns>
+ /// <param name="fileName">The filename.</param>
+ /// <returns>The full path to the file.</returns>
private string ExistsOnSystemPath(string fileName)
{
var inJellyfinPath = GetEncoderPathFromDirectory(AppContext.BaseDirectory, fileName, recursive: true);
@@ -246,25 +257,19 @@ namespace MediaBrowser.MediaEncoding.Encoder
return null;
}
- private List<string> _encoders = new List<string>();
public void SetAvailableEncoders(IEnumerable<string> list)
{
_encoders = list.ToList();
- // _logger.Info("Supported encoders: {0}", string.Join(",", list.ToArray()));
}
- private List<string> _decoders = new List<string>();
public void SetAvailableDecoders(IEnumerable<string> list)
{
_decoders = list.ToList();
- // _logger.Info("Supported decoders: {0}", string.Join(",", list.ToArray()));
}
- private List<string> _hwaccels = new List<string>();
public void SetAvailableHwaccels(IEnumerable<string> list)
{
_hwaccels = list.ToList();
- //_logger.Info("Supported hwaccels: {0}", string.Join(",", list.ToArray()));
}
public bool SupportsEncoder(string encoder)
@@ -332,8 +337,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
var forceEnableLogging = request.MediaSource.Protocol != MediaProtocol.File;
- return GetMediaInfoInternal(GetInputArgument(inputFiles, request.MediaSource.Protocol), request.MediaSource.Path, request.MediaSource.Protocol, extractChapters,
- probeSize, request.MediaType == DlnaProfileType.Audio, request.MediaSource.VideoType, forceEnableLogging, cancellationToken);
+ return GetMediaInfoInternal(
+ GetInputArgument(inputFiles, request.MediaSource.Protocol),
+ request.MediaSource.Path,
+ request.MediaSource.Protocol,
+ extractChapters,
+ probeSize,
+ request.MediaType == DlnaProfileType.Audio,
+ request.MediaSource.VideoType,
+ forceEnableLogging,
+ cancellationToken);
}
/// <summary>
@@ -342,7 +355,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// <param name="inputFiles">The input files.</param>
/// <param name="protocol">The protocol.</param>
/// <returns>System.String.</returns>
- /// <exception cref="ArgumentException">Unrecognized InputType</exception>
+ /// <exception cref="ArgumentException">Unrecognized InputType.</exception>
public string GetInputArgument(IReadOnlyList<string> inputFiles, MediaProtocol protocol)
=> EncodingUtils.GetInputArgument(inputFiles, protocol);
@@ -350,7 +363,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// Gets the media info internal.
/// </summary>
/// <returns>Task{MediaInfoResult}.</returns>
- private async Task<MediaInfo> GetMediaInfoInternal(string inputPath,
+ private async Task<MediaInfo> GetMediaInfoInternal(
+ string inputPath,
string primaryPath,
MediaProtocol protocol,
bool extractChapters,
@@ -378,7 +392,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
FileName = _ffprobePath,
Arguments = args,
-
WindowStyle = ProcessWindowStyle.Hidden,
ErrorDialog = false,
},
@@ -439,11 +452,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
}
- /// <summary>
- /// The us culture.
- /// </summary>
- protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
public Task<string> ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken)
{
return ExtractImage(new[] { path }, null, null, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken);
@@ -459,8 +467,16 @@ namespace MediaBrowser.MediaEncoding.Encoder
return ExtractImage(inputFiles, container, imageStream, imageStreamIndex, protocol, false, null, null, cancellationToken);
}
- private async Task<string> ExtractImage(string[] inputFiles, string container, MediaStream videoStream, int? imageStreamIndex, MediaProtocol protocol, bool isAudio,
- Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
+ private async Task<string> ExtractImage(
+ string[] inputFiles,
+ string container,
+ MediaStream videoStream,
+ int? imageStreamIndex,
+ MediaProtocol protocol,
+ bool isAudio,
+ Video3DFormat? threedFormat,
+ TimeSpan? offset,
+ CancellationToken cancellationToken)
{
var inputArgument = GetInputArgument(inputFiles, protocol);
@@ -645,7 +661,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
public string GetTimeParameter(TimeSpan time)
{
- return time.ToString(@"hh\:mm\:ss\.fff", UsCulture);
+ return time.ToString(@"hh\:mm\:ss\.fff", _usCulture);
}
public async Task ExtractVideoImagesOnInterval(
@@ -662,11 +678,11 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
var inputArgument = GetInputArgument(inputFiles, protocol);
- var vf = "fps=fps=1/" + interval.TotalSeconds.ToString(UsCulture);
+ var vf = "fps=fps=1/" + interval.TotalSeconds.ToString(_usCulture);
if (maxWidth.HasValue)
{
- var maxWidthParam = maxWidth.Value.ToString(UsCulture);
+ var maxWidthParam = maxWidth.Value.ToString(_usCulture);
vf += string.Format(",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam);
}
@@ -859,6 +875,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
if (dispose)
{
StopProcesses();
+ _thumbnailResourcePool.Dispose();
}
}
diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
index aeb4dbe73..017f917e2 100644
--- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
+++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
@@ -9,6 +9,7 @@
<TargetFramework>netstandard2.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
@@ -27,4 +28,16 @@
<PackageReference Include="UTF.Unknown" Version="2.3.0" />
</ItemGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+
+ <!-- Code Analyzers-->
+ <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <!-- <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" /> -->
+ <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
+ <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
+ <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
+ </ItemGroup>
+
</Project>
diff --git a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
index 3aa296f7f..b2d4db894 100644
--- a/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
+++ b/MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
@@ -3,6 +3,9 @@ using System.Collections.Generic;
namespace MediaBrowser.MediaEncoding.Probing
{
+ /// <summary>
+ /// Class containing helper methods for working with FFprobe output.
+ /// </summary>
public static class FFProbeHelpers
{
/// <summary>
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs b/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs
index 6a45ccf49..de062d06b 100644
--- a/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs
+++ b/MediaBrowser.MediaEncoding/Probing/MediaChapter.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.Text.Json.Serialization;
diff --git a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
index a2ea0766a..8996d3b09 100644
--- a/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
+++ b/MediaBrowser.MediaEncoding/Probing/MediaStreamInfo.cs
@@ -269,6 +269,10 @@ namespace MediaBrowser.MediaEncoding.Probing
[JsonPropertyName("loro_surmixlev")]
public string LoroSurmixlev { get; set; }
+ /// <summary>
+ /// Gets or sets the field_order.
+ /// </summary>
+ /// <value>The field_order.</value>
[JsonPropertyName("field_order")]
public string FieldOrder { get; set; }
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index 0b447e3e6..19e3bd8e6 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -16,10 +18,19 @@ namespace MediaBrowser.MediaEncoding.Probing
{
public class ProbeResultNormalizer
{
+ // When extracting subtitles, the maximum length to consider (to avoid invalid filenames)
+ private const int MaxSubtitleDescriptionExtractionLength = 100;
+
+ private const string ArtistReplaceValue = " | ";
+
+ private readonly char[] _nameDelimiters = { '/', '|', ';', '\\' };
+
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private readonly ILogger _logger;
private readonly ILocalizationManager _localization;
+ private List<string> _splitWhiteList = null;
+
public ProbeResultNormalizer(ILogger logger, ILocalizationManager localization)
{
_logger = logger;
@@ -368,7 +379,6 @@ namespace MediaBrowser.MediaEncoding.Probing
private List<NameValuePair> ReadValueArray(XmlReader reader)
{
-
var pairs = new List<NameValuePair>();
reader.MoveToContent();
@@ -949,50 +959,46 @@ namespace MediaBrowser.MediaEncoding.Probing
private void SetAudioInfoFromTags(MediaInfo audio, Dictionary<string, string> tags)
{
+ var peoples = new List<BaseItemPerson>();
var composer = FFProbeHelpers.GetDictionaryValue(tags, "composer");
if (!string.IsNullOrWhiteSpace(composer))
{
- var peoples = new List<BaseItemPerson>();
foreach (var person in Split(composer, false))
{
peoples.Add(new BaseItemPerson { Name = person, Type = PersonType.Composer });
}
-
- audio.People = peoples.ToArray();
}
- // var conductor = FFProbeHelpers.GetDictionaryValue(tags, "conductor");
- // if (!string.IsNullOrWhiteSpace(conductor))
- //{
- // foreach (var person in Split(conductor, false))
- // {
- // audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Conductor });
- // }
- //}
+ var conductor = FFProbeHelpers.GetDictionaryValue(tags, "conductor");
+ if (!string.IsNullOrWhiteSpace(conductor))
+ {
+ foreach (var person in Split(conductor, false))
+ {
+ peoples.Add(new BaseItemPerson { Name = person, Type = PersonType.Conductor });
+ }
+ }
- // var lyricist = FFProbeHelpers.GetDictionaryValue(tags, "lyricist");
- // if (!string.IsNullOrWhiteSpace(lyricist))
- //{
- // foreach (var person in Split(lyricist, false))
- // {
- // audio.People.Add(new BaseItemPerson { Name = person, Type = PersonType.Lyricist });
- // }
- //}
+ var lyricist = FFProbeHelpers.GetDictionaryValue(tags, "lyricist");
+ if (!string.IsNullOrWhiteSpace(lyricist))
+ {
+ foreach (var person in Split(lyricist, false))
+ {
+ peoples.Add(new BaseItemPerson { Name = person, Type = PersonType.Lyricist });
+ }
+ }
// Check for writer some music is tagged that way as alternative to composer/lyricist
var writer = FFProbeHelpers.GetDictionaryValue(tags, "writer");
if (!string.IsNullOrWhiteSpace(writer))
{
- var peoples = new List<BaseItemPerson>();
foreach (var person in Split(writer, false))
{
peoples.Add(new BaseItemPerson { Name = person, Type = PersonType.Writer });
}
-
- audio.People = peoples.ToArray();
}
+ audio.People = peoples.ToArray();
audio.Album = FFProbeHelpers.GetDictionaryValue(tags, "album");
var artists = FFProbeHelpers.GetDictionaryValue(tags, "artists");
@@ -1117,8 +1123,6 @@ namespace MediaBrowser.MediaEncoding.Probing
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
- private readonly char[] _nameDelimiters = { '/', '|', ';', '\\' };
-
/// <summary>
/// Splits the specified val.
/// </summary>
@@ -1138,8 +1142,6 @@ namespace MediaBrowser.MediaEncoding.Probing
.Select(i => i.Trim());
}
- private const string ArtistReplaceValue = " | ";
-
private IEnumerable<string> SplitArtists(string val, char[] delimiters, bool splitFeaturing)
{
if (splitFeaturing)
@@ -1169,9 +1171,6 @@ namespace MediaBrowser.MediaEncoding.Probing
return artistsFound;
}
-
- private List<string> _splitWhiteList = null;
-
private IEnumerable<string> GetSplitWhitelist()
{
if (_splitWhiteList == null)
@@ -1248,7 +1247,7 @@ namespace MediaBrowser.MediaEncoding.Probing
}
/// <summary>
- /// Gets the disc number, which is sometimes can be in the form of '1', or '1/3'
+ /// Gets the disc number, which is sometimes can be in the form of '1', or '1/3'.
/// </summary>
/// <param name="tags">The tags.</param>
/// <param name="tagName">Name of the tag.</param>
@@ -1294,8 +1293,6 @@ namespace MediaBrowser.MediaEncoding.Probing
return info;
}
- private const int MaxSubtitleDescriptionExtractionLength = 100; // When extracting subtitles, the maximum length to consider (to avoid invalid filenames)
-
private void FetchWtvInfo(MediaInfo video, InternalMediaInfoResult data)
{
if (data.Format == null || data.Format.Tags == null)
@@ -1380,8 +1377,8 @@ namespace MediaBrowser.MediaEncoding.Probing
if (subtitle.Contains('/', StringComparison.Ordinal)) // It contains a episode number and season number
{
string[] numbers = subtitle.Split(' ');
- video.IndexNumber = int.Parse(numbers[0].Replace(".", "").Split('/')[0]);
- int totalEpisodesInSeason = int.Parse(numbers[0].Replace(".", "").Split('/')[1]);
+ video.IndexNumber = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[0]);
+ int totalEpisodesInSeason = int.Parse(numbers[0].Replace(".", string.Empty, StringComparison.Ordinal).Split('/')[1]);
description = string.Join(" ", numbers, 1, numbers.Length - 1).Trim(); // Skip the first, concatenate the rest, clean up spaces and save it
}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
index 43a45291c..308b62886 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -13,6 +15,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+ /// <inheritdoc />
public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
{
var trackInfo = new SubtitleTrackInfo();
@@ -22,7 +25,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
string line;
while (reader.ReadLine() != "[Events]")
- { }
+ {
+ }
var headers = ParseFieldHeaders(reader.ReadLine());
@@ -72,17 +76,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
var fields = line.Substring(8).Split(',').Select(x => x.Trim()).ToList();
- var result = new Dictionary<string, int> {
- {"Start", fields.IndexOf("Start")},
- {"End", fields.IndexOf("End")},
- {"Text", fields.IndexOf("Text")}
- };
- return result;
+ return new Dictionary<string, int>
+ {
+ { "Start", fields.IndexOf("Start") },
+ { "End", fields.IndexOf("End") },
+ { "Text", fields.IndexOf("Text") }
+ };
}
- /// <summary>
- /// Credit: https://github.com/SubtitleEdit/subtitleedit/blob/master/src/Logic/SubtitleFormats/AdvancedSubStationAlpha.cs
- /// </summary>
private void RemoteNativeFormatting(SubtitleTrackEvent p)
{
int indexOfBegin = p.Text.IndexOf('{');
diff --git a/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs b/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs
index f0d107196..c0023ebf2 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.IO;
using System.Threading;
using MediaBrowser.Model.MediaInfo;
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
index bd330f568..6b7a81e6e 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs
@@ -8,7 +8,7 @@ using MediaBrowser.Model.MediaInfo;
namespace MediaBrowser.MediaEncoding.Subtitles
{
/// <summary>
- /// Credit to https://github.com/SubtitleEdit/subtitleedit/blob/a299dc4407a31796364cc6ad83f0d3786194ba22/src/Logic/SubtitleFormats/SubStationAlpha.cs
+ /// <see href="https://github.com/SubtitleEdit/subtitleedit/blob/a299dc4407a31796364cc6ad83f0d3786194ba22/src/Logic/SubtitleFormats/SubStationAlpha.cs">Credit</see>.
/// </summary>
public class SsaParser : ISubtitleParser
{
@@ -179,10 +179,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
// h:mm:ss.cc
string[] timeCode = time.Split(':', '.');
- return new TimeSpan(0, int.Parse(timeCode[0]),
- int.Parse(timeCode[1]),
- int.Parse(timeCode[2]),
- int.Parse(timeCode[3]) * 10).Ticks;
+ return new TimeSpan(
+ 0,
+ int.Parse(timeCode[0]),
+ int.Parse(timeCode[1]),
+ int.Parse(timeCode[2]),
+ int.Parse(timeCode[3]) * 10).Ticks;
}
private static string GetFormattedText(string text)
@@ -282,6 +284,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
text = text.Insert(start, "<font color=\"" + color + "\"" + extraTags + ">");
}
+
int indexOfEndTag = text.IndexOf("{\\c}", start);
if (indexOfEndTag > 0)
{
@@ -320,6 +323,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
{
text = text.Insert(start, "<font color=\"" + color + "\"" + extraTags + ">");
}
+
text += "</font>";
}
}
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index 2afa89cda..374e35b96 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -34,6 +34,12 @@ namespace MediaBrowser.MediaEncoding.Subtitles
private readonly IHttpClient _httpClient;
private readonly IMediaSourceManager _mediaSourceManager;
+ /// <summary>
+ /// The _semaphoreLocks.
+ /// </summary>
+ private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks =
+ new ConcurrentDictionary<string, SemaphoreSlim>();
+
public SubtitleEncoder(
ILibraryManager libraryManager,
ILogger<SubtitleEncoder> logger,
@@ -269,25 +275,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
return new SubtitleInfo(subtitleStream.Path, protocol, currentFormat, true);
}
- private struct SubtitleInfo
- {
- public SubtitleInfo(string path, MediaProtocol protocol, string format, bool isExternal)
- {
- Path = path;
- Protocol = protocol;
- Format = format;
- IsExternal = isExternal;
- }
-
- public string Path { get; set; }
-
- public MediaProtocol Protocol { get; set; }
-
- public string Format { get; set; }
-
- public bool IsExternal { get; set; }
- }
-
private ISubtitleParser GetReader(string format, bool throwIfMissing)
{
if (string.IsNullOrEmpty(format))
@@ -361,12 +348,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles
}
/// <summary>
- /// The _semaphoreLocks.
- /// </summary>
- private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks =
- new ConcurrentDictionary<string, SemaphoreSlim>();
-
- /// <summary>
/// Gets the lock.
/// </summary>
/// <param name="filename">The filename.</param>
@@ -380,6 +361,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// Converts the text subtitle to SRT.
/// </summary>
/// <param name="inputPath">The input path.</param>
+ /// <param name="language">The language.</param>
/// <param name="inputProtocol">The input protocol.</param>
/// <param name="outputPath">The output path.</param>
/// <param name="cancellationToken">The cancellation token.</param>
@@ -407,14 +389,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// Converts the text subtitle to SRT internal.
/// </summary>
/// <param name="inputPath">The input path.</param>
+ /// <param name="language">The language.</param>
/// <param name="inputProtocol">The input protocol.</param>
/// <param name="outputPath">The output path.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
/// <exception cref="ArgumentNullException">
- /// inputPath
- /// or
- /// outputPath
+ /// The <c>inputPath</c> or <c>outputPath</c> is <c>null</c>.
/// </exception>
private async Task ConvertTextSubtitleToSrtInternal(string inputPath, string language, MediaProtocol inputProtocol, string outputPath, CancellationToken cancellationToken)
{
@@ -438,7 +419,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
(encodingParam.Equals("UTF-16BE", StringComparison.OrdinalIgnoreCase) ||
encodingParam.Equals("UTF-16LE", StringComparison.OrdinalIgnoreCase)))
{
- encodingParam = "";
+ encodingParam = string.Empty;
}
else if (!string.IsNullOrEmpty(encodingParam))
{
@@ -540,7 +521,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
/// <param name="outputPath">The output path.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- /// <exception cref="ArgumentException">Must use inputPath list overload</exception>
+ /// <exception cref="ArgumentException">Must use inputPath list overload.</exception>
private async Task ExtractTextSubtitle(
string[] inputFiles,
MediaProtocol protocol,
@@ -759,7 +740,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
&& (string.Equals(charset, "utf-16le", StringComparison.OrdinalIgnoreCase)
|| string.Equals(charset, "utf-16be", StringComparison.OrdinalIgnoreCase)))
{
- charset = "";
+ charset = string.Empty;
}
_logger.LogDebug("charset {0} detected for {Path}", charset ?? "null", path);
@@ -790,5 +771,24 @@ namespace MediaBrowser.MediaEncoding.Subtitles
throw new ArgumentOutOfRangeException(nameof(protocol));
}
}
+
+ private struct SubtitleInfo
+ {
+ public SubtitleInfo(string path, MediaProtocol protocol, string format, bool isExternal)
+ {
+ Path = path;
+ Protocol = protocol;
+ Format = format;
+ IsExternal = isExternal;
+ }
+
+ public string Path { get; set; }
+
+ public MediaProtocol Protocol { get; set; }
+
+ public string Format { get; set; }
+
+ public bool IsExternal { get; set; }
+ }
}
}
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index 1b37cfc93..f9ec0d238 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -233,7 +233,7 @@ namespace MediaBrowser.Model.Entities
if (!string.IsNullOrEmpty(Title))
{
- var result = new StringBuilder(Title);
+ var result = new StringBuilder(Title);
foreach (var tag in attributes)
{
// Keep Tags that are not already in Title.
@@ -246,7 +246,7 @@ namespace MediaBrowser.Model.Entities
return result.ToString();
}
- return string.Join(" - ", attributes.ToArray());
+ return string.Join(" - ", attributes);
}
default:
diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs
index f655b8edd..32b543fef 100644
--- a/MediaBrowser.Providers/Manager/ImageSaver.cs
+++ b/MediaBrowser.Providers/Manager/ImageSaver.cs
@@ -125,7 +125,7 @@ namespace MediaBrowser.Providers.Manager
// If there are more than one output paths, the stream will need to be seekable
var memoryStream = new MemoryStream();
- using (source)
+ await using (source.ConfigureAwait(false))
{
await source.CopyToAsync(memoryStream).ConfigureAwait(false);
}
@@ -138,7 +138,7 @@ namespace MediaBrowser.Providers.Manager
var savedPaths = new List<string>();
- await using (source)
+ await using (source.ConfigureAwait(false))
{
var currentPathIndex = 0;
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index 9170c7002..2d6935a0b 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -966,7 +966,7 @@ namespace MediaBrowser.Providers.Manager
/// <inheritdoc/>
public void OnRefreshStart(BaseItem item)
{
- _logger.LogInformation("OnRefreshStart {0}", item.Id.ToString("N", CultureInfo.InvariantCulture));
+ _logger.LogDebug("OnRefreshStart {0}", item.Id.ToString("N", CultureInfo.InvariantCulture));
_activeRefreshes[item.Id] = 0;
RefreshStarted?.Invoke(this, new GenericEventArgs<BaseItem>(item));
}
@@ -974,7 +974,7 @@ namespace MediaBrowser.Providers.Manager
/// <inheritdoc/>
public void OnRefreshComplete(BaseItem item)
{
- _logger.LogInformation("OnRefreshComplete {0}", item.Id.ToString("N", CultureInfo.InvariantCulture));
+ _logger.LogDebug("OnRefreshComplete {0}", item.Id.ToString("N", CultureInfo.InvariantCulture));
_activeRefreshes.Remove(item.Id, out _);
diff --git a/README.md b/README.md
index 3f1b5e514..a41bfbca8 100644
--- a/README.md
+++ b/README.md
@@ -100,7 +100,7 @@ Note that it is also possible to [host the web client separately](#hosting-the-w
There are three options to get the files for the web client.
-1. Download one of the finished builds from the [Azure DevOps pipeline](https://dev.azure.com/jellyfin-project/jellyfin/_build?definitionId=11). You can download the build for a specific release by looking at the [branches tab](https://dev.azure.com/jellyfin-project/jellyfin/_build?definitionId=11&_a=summary&repositoryFilter=6&view=branches) of the pipelines page.
+1. Download one of the finished builds from the [Azure DevOps pipeline](https://dev.azure.com/jellyfin-project/jellyfin/_build?definitionId=27). You can download the build for a specific release by looking at the [branches tab](https://dev.azure.com/jellyfin-project/jellyfin/_build?definitionId=27&_a=summary&repositoryFilter=6&view=branches) of the pipelines page.
2. Build them from source following the instructions on the [jellyfin-web repository](https://github.com/jellyfin/jellyfin-web)
3. Get the pre-built files from an existing installation of the server. For example, with a Windows server installation the client files are located at `C:\Program Files\Jellyfin\Server\jellyfin-web`
diff --git a/RSSDP/RSSDP.csproj b/RSSDP/RSSDP.csproj
index 553693171..664663bd7 100644
--- a/RSSDP/RSSDP.csproj
+++ b/RSSDP/RSSDP.csproj
@@ -6,9 +6,7 @@
</PropertyGroup>
<ItemGroup>
- <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
- <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
</ItemGroup>
<PropertyGroup>