Skip to content

Commit 618912e

Browse files
committed
fix: configuration changes don't take effect until restart.
A configuration change creates a totally new instance of the configuration object, so we need to discard the one we have. Since most things are singletons, that becomes impossible unless it's done via IPluginManager. Fixes #5.
1 parent 1e256d7 commit 618912e

File tree

3 files changed

+20
-18
lines changed

3 files changed

+20
-18
lines changed

Jellyfin.Plugin.DoViRemux/DownmuxWorkflow.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System.Diagnostics;
22
using MediaBrowser.Common.Configuration;
3-
using MediaBrowser.Controller.MediaEncoding;
3+
using MediaBrowser.Common.Plugins;
44
using MediaBrowser.Model.Dto;
55
using Microsoft.Extensions.Logging;
66

@@ -12,18 +12,22 @@ namespace Jellyfin.Plugin.DoViRemux;
1212
// We only need to go as far as the mp4box step, and then the main
1313
// RemuxLibraryTask can handle the rest (it just copies the video
1414
// stream from our MP4 instead of the original MKV)
15-
public class DownmuxWorkflow(PluginConfiguration _configuration,
15+
public class DownmuxWorkflow(IPluginManager _pluginManager,
1616
ILogger<DownmuxWorkflow> _logger,
1717
IApplicationPaths _paths)
1818
{
1919
public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken token)
2020
{
21+
var configuration = (_pluginManager.GetPlugin(Plugin.OurGuid)?.Instance as Plugin)?.Configuration
22+
?? throw new Exception("Can't get plugin configuration");
23+
2124
string hevcStreamPath = $"/tmp/dovi_tool_{mediaSource.Id}.hevc";
2225
string downmuxPath = $"/tmp/{mediaSource.Id}_profile8.mp4";
2326

2427
// extract the HEVC stream...
2528
using var ffmpeg = new Process()
2629
{
30+
// technically this should use the configured path, since it can be overridden with a CLI argument
2731
StartInfo = new ProcessStartInfo("ffmpeg")
2832
{
2933
Arguments = string.Join(" ", [
@@ -47,7 +51,7 @@ public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken
4751
// and feed it into dovi_tool, discarding the enhancement layer
4852
using var doviTool = new Process()
4953
{
50-
StartInfo = new ProcessStartInfo(_configuration.PathToDoviTool)
54+
StartInfo = new ProcessStartInfo(configuration.PathToDoviTool)
5155
{
5256
Arguments = string.Join(" ", [
5357
"-m 2", // convert RPU to 8.1
@@ -86,7 +90,7 @@ public async Task<string> Downmux(MediaSourceInfo mediaSource, CancellationToken
8690
// indicating it's now profile 8.1. I don't think ffmpeg can do this.
8791
using var mp4box = new Process()
8892
{
89-
StartInfo = new ProcessStartInfo(_configuration.PathToMP4Box)
93+
StartInfo = new ProcessStartInfo(configuration.PathToMP4Box)
9094
{
9195
// no clue what any of this does, except for the dvp line
9296
Arguments = string.Join(" ", [

Jellyfin.Plugin.DoViRemux/Registrations.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using MediaBrowser.Common.Plugins;
21
using MediaBrowser.Controller;
32
using MediaBrowser.Controller.Plugins;
43
using Microsoft.Extensions.DependencyInjection;
@@ -9,11 +8,6 @@ public class Registrations : IPluginServiceRegistrator
98
{
109
public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost)
1110
{
12-
// bug: yes very clever, katie, but the plugin system creates a new instance of the configuration when a change is saved,
13-
// and scheduled tasks are singletons (by virtue of IPluginManager being a singleton), so they won't see config changes.
14-
serviceCollection.AddTransient(sp => (sp.GetRequiredService<IPluginManager>().GetPlugin(Plugin.OurGuid)?.Instance as Plugin)?.Configuration
15-
?? throw new InvalidOperationException("Plugin configuration not registered"));
16-
1711
serviceCollection.AddTransient<RemuxLibraryTask>();
1812
serviceCollection.AddTransient<CleanRemuxesTask>();
1913
serviceCollection.AddTransient<DownmuxWorkflow>();

Jellyfin.Plugin.DoViRemux/RemuxLibraryTask.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Jellyfin.Data.Entities;
22
using Jellyfin.Data.Enums;
33
using MediaBrowser.Common.Configuration;
4+
using MediaBrowser.Common.Plugins;
45
using MediaBrowser.Controller.Entities;
56
using MediaBrowser.Controller.Library;
67
using MediaBrowser.Controller.MediaEncoding;
@@ -14,7 +15,7 @@ namespace Jellyfin.Plugin.DoViRemux;
1415
public class RemuxLibraryTask(IItemRepository _itemRepo,
1516
IMediaSourceManager _sourceManager,
1617
ITranscodeManager _transcodeManager,
17-
PluginConfiguration _configuration,
18+
IPluginManager _pluginManager,
1819
ILogger<RemuxLibraryTask> _logger,
1920
IApplicationPaths _paths,
2021
ILibraryManager _libraryManager,
@@ -35,15 +36,18 @@ public class RemuxLibraryTask(IItemRepository _itemRepo,
3536

3637
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
3738
{
38-
var primaryUser = _configuration.PrimaryUser is not null
39-
? _userManager.GetUserByName(_configuration.PrimaryUser)
40-
?? throw new Exception($"Primary user '{_configuration.PrimaryUser}' does not exist")
39+
var configuration = (_pluginManager.GetPlugin(Plugin.OurGuid)?.Instance as Plugin)?.Configuration
40+
?? throw new Exception("Can't get plugin configuration");
41+
42+
var primaryUser = configuration.PrimaryUser is not null
43+
? _userManager.GetUserByName(configuration.PrimaryUser)
44+
?? throw new Exception($"Primary user '{configuration.PrimaryUser}' does not exist")
4145
: null;
4246

4347
var itemsToProcess = _itemRepo.GetItems(new InternalItemsQuery
4448
{
4549
MediaTypes = [MediaType.Video],
46-
AncestorIds = _configuration.IncludeAncestors
50+
AncestorIds = configuration.IncludeAncestors
4751
})
4852
.Items
4953
.Cast<Video>() // has some additional properties (that I don't remember if we use or not)
@@ -57,7 +61,7 @@ public async Task ExecuteAsync(IProgress<double> progress, CancellationToken can
5761

5862
try
5963
{
60-
await ProcessOneItem(item, cancellationToken);
64+
await ProcessOneItem(item, cancellationToken, configuration);
6165
}
6266
catch (Exception x)
6367
{
@@ -107,7 +111,7 @@ private bool ShouldProcessItem(Video item, User? primaryUser)
107111
return true;
108112
}
109113

110-
private async Task ProcessOneItem(Video item, CancellationToken cancellationToken)
114+
private async Task ProcessOneItem(Video item, CancellationToken cancellationToken, PluginConfiguration configuration)
111115
{
112116
var streams = _sourceManager.GetMediaStreams(item.Id);
113117
var otherSources = item.GetMediaSources(true);
@@ -138,7 +142,7 @@ private async Task ProcessOneItem(Video item, CancellationToken cancellationToke
138142
// This will be presented as a second input to FFmpeg, and it will copy that
139143
// converted video stream instead of our original MKV's.
140144
string? downmuxedVideoPath = null;
141-
if (streams.Any(s => s.DvProfile == 7 && s.DvLevel == 6) && _configuration.DownmuxProfile7)
145+
if (streams.Any(s => s.DvProfile == 7 && s.DvLevel == 6) && configuration.DownmuxProfile7)
142146
{
143147
_logger.LogInformation("Downmuxing {Id} {Name} to Profile 8.1 first", item.Id, item.Name);
144148
downmuxedVideoPath = await _downmuxWorkflow.Downmux(ourSource, cancellationToken);

0 commit comments

Comments
 (0)