mirror of
https://github.com/IAmParadox27/jellyfin-plugin-media-bar.git
synced 2026-11-13 16:54:19 +01:00
Added named pipe service to handle transformations
This commit is contained in:
1 parent
8e34233ef5
commit
69a5233b3e
3 files changed
+113
-1
No files matched your search
@@ -0,0 +1,19 @@
|
||||
using Jellyfin.Plugin.MediaBar.Services;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Jellyfin.Plugin.MediaBar
|
||||
{
|
||||
public class PluginServiceRegistrator : IPluginServiceRegistrator
|
||||
{
|
||||
public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost)
|
||||
{
|
||||
serviceCollection.AddSingleton<NamedPipeService>();
|
||||
serviceCollection.AddHostedService<NamedPipeService>(services =>
|
||||
{
|
||||
return services.GetRequiredService<NamedPipeService>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO.Pipes;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Jellyfin.Plugin.MediaBar.Services
|
||||
{
|
||||
public class NamedPipeService : IHostedService
|
||||
{
|
||||
private ConcurrentBag<NamedPipeServerStream> m_activeStreams = new ConcurrentBag<NamedPipeServerStream>();
|
||||
private bool m_running = false;
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
m_running = true;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
m_running = false;
|
||||
|
||||
while (m_activeStreams.Any(x => x.IsConnected))
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(10), cancellationToken);
|
||||
}
|
||||
|
||||
foreach (NamedPipeServerStream stream in m_activeStreams)
|
||||
{
|
||||
await stream.DisposeAsync();
|
||||
}
|
||||
|
||||
m_activeStreams.Clear();
|
||||
}
|
||||
|
||||
public async void CreateNamedPipeHandler(string pipeName, Func<NamedPipeServerStream, Task> callback)
|
||||
{
|
||||
while (m_running)
|
||||
{
|
||||
NamedPipeServerStream pipeStream = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 254);
|
||||
await pipeStream.WaitForConnectionAsync();
|
||||
|
||||
m_activeStreams.Add(pipeStream);
|
||||
|
||||
AsyncCallback(pipeStream, callback);
|
||||
}
|
||||
}
|
||||
|
||||
private async void AsyncCallback(NamedPipeServerStream pipeStream, Func<NamedPipeServerStream, Task> callback)
|
||||
{
|
||||
await callback(pipeStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Jellyfin.Plugin.MediaBar.Helpers;
|
||||
using Jellyfin.Plugin.MediaBar.Model;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
@@ -24,11 +26,13 @@ namespace Jellyfin.Plugin.MediaBar.Services
|
||||
|
||||
private readonly IServerApplicationHost m_serverApplicationHost;
|
||||
private readonly ILogger<MediaBarPlugin> m_logger;
|
||||
private readonly NamedPipeService m_namedPipeService;
|
||||
|
||||
public StartupService(IServerApplicationHost serverApplicationHost, ILogger<MediaBarPlugin> logger)
|
||||
public StartupService(IServerApplicationHost serverApplicationHost, ILogger<MediaBarPlugin> logger, NamedPipeService namedPipeService)
|
||||
{
|
||||
m_serverApplicationHost = serverApplicationHost;
|
||||
m_logger = logger;
|
||||
m_namedPipeService = namedPipeService;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
|
||||
@@ -42,6 +46,8 @@ namespace Jellyfin.Plugin.MediaBar.Services
|
||||
payload.Add("id", "0dfac9d7-d898-4944-900b-1c1837707279");
|
||||
payload.Add("fileNamePattern", "index.html");
|
||||
payload.Add("transformationEndpoint", "/MediaBar/Patch/IndexHtml");
|
||||
payload.Add("transformationPipe", "Jellyfin.Plugin.MediaBar.Patch.IndexHtml");
|
||||
RegisterPipeEndpoint("Jellyfin.Plugin.MediaBar.Patch.IndexHtml", TransformationPatches.IndexHtml);
|
||||
|
||||
payloads.Add(payload);
|
||||
}
|
||||
@@ -50,6 +56,8 @@ namespace Jellyfin.Plugin.MediaBar.Services
|
||||
payload.Add("id", "e6d32b76-d54b-4946-b73e-c5c9c50575c9");
|
||||
payload.Add("fileNamePattern", "home-html\\.[a-zA-z0-9]+\\.chunk\\.js");
|
||||
payload.Add("transformationEndpoint", "/MediaBar/Patch/HomeHtmlChunk");
|
||||
payload.Add("transformationPipe", "Jellyfin.Plugin.MediaBar.Patch.HomeHtmlChunk");
|
||||
RegisterPipeEndpoint("Jellyfin.Plugin.MediaBar.Patch.HomeHtmlChunk", TransformationPatches.HomeHtmlChunk);
|
||||
|
||||
payloads.Add(payload);
|
||||
}
|
||||
@@ -58,6 +66,8 @@ namespace Jellyfin.Plugin.MediaBar.Services
|
||||
payload.Add("id", "3d171ef1-a198-48ac-9a60-f6aa98e5fd6d");
|
||||
payload.Add("fileNamePattern", "main.jellyfin.bundle.js");
|
||||
payload.Add("transformationEndpoint", "/MediaBar/Patch/MainJellyfinBundle");
|
||||
payload.Add("transformationPipe", "Jellyfin.Plugin.MediaBar.Patch.MainBundle");
|
||||
RegisterPipeEndpoint("Jellyfin.Plugin.MediaBar.Patch.MainBundle", TransformationPatches.MainBundle);
|
||||
|
||||
payloads.Add(payload);
|
||||
}
|
||||
@@ -114,6 +124,35 @@ namespace Jellyfin.Plugin.MediaBar.Services
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterPipeEndpoint(string pipeName, Func<PatchRequestPayload, string> handler)
|
||||
{
|
||||
m_namedPipeService.CreateNamedPipeHandler(pipeName, async stream =>
|
||||
{
|
||||
byte[] lengthBuffer = new byte[8];
|
||||
await stream.ReadExactlyAsync(lengthBuffer, 0, lengthBuffer.Length);
|
||||
long length = BitConverter.ToInt64(lengthBuffer, 0);
|
||||
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
while (length > 0)
|
||||
{
|
||||
byte[] buffer = new byte[Math.Min(length, 1024)];
|
||||
int readBytes = await stream.ReadAsync(buffer, 0, buffer.Length);
|
||||
length -= readBytes;
|
||||
|
||||
memoryStream.Write(buffer, 0, readBytes);
|
||||
}
|
||||
|
||||
string rawJson = Encoding.UTF8.GetString(memoryStream.ToArray());
|
||||
|
||||
string response = handler(JsonConvert.DeserializeObject<PatchRequestPayload>(rawJson)!);
|
||||
byte[] responseBuffer = Encoding.UTF8.GetBytes(response);
|
||||
byte[] responseLengthBuffer = BitConverter.GetBytes((long)responseBuffer.Length);
|
||||
|
||||
await stream.WriteAsync(responseLengthBuffer, 0, responseLengthBuffer.Length);
|
||||
await stream.WriteAsync(responseBuffer, 0, responseBuffer.Length);
|
||||
});
|
||||
}
|
||||
|
||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||
{
|
||||
yield return new TaskTriggerInfo()
|
||||
|
||||
Reference in new issue
Block a user