Browse Source

check for working avisynth

pull/2612/head
Jason Dove 9 months ago
parent
commit
315dadbdc9
No known key found for this signature in database
  1. 18
      ErsatzTV.Application/FFmpeg/Commands/RefreshFFmpegCapabilitiesHandler.cs
  2. 3
      ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs
  3. 3
      ErsatzTV.Application/Troubleshooting/Queries/GetTroubleshootingInfoHandler.cs
  4. 1
      ErsatzTV.Application/Troubleshooting/TroubleshootingInfo.cs
  5. 30
      ErsatzTV.FFmpeg/Capabilities/HardwareCapabilitiesFactory.cs
  6. 4
      ErsatzTV.FFmpeg/Capabilities/IHardwareCapabilitiesFactory.cs
  7. 1
      ErsatzTV/ErsatzTV.csproj
  8. 3
      ErsatzTV/Pages/Troubleshooting/Troubleshooting.razor
  9. 2
      ErsatzTV/Resources/test.avs
  10. 1
      ErsatzTV/Services/RunOnce/ResourceExtractorService.cs

18
ErsatzTV.Application/FFmpeg/Commands/RefreshFFmpegCapabilitiesHandler.cs

@ -1,4 +1,6 @@
using ErsatzTV.Core;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.FFmpeg.Capabilities; using ErsatzTV.FFmpeg.Capabilities;
using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions; using ErsatzTV.Infrastructure.Extensions;
@ -8,7 +10,8 @@ namespace ErsatzTV.Application.FFmpeg;
public class RefreshFFmpegCapabilitiesHandler( public class RefreshFFmpegCapabilitiesHandler(
IDbContextFactory<TvContext> dbContextFactory, IDbContextFactory<TvContext> dbContextFactory,
IHardwareCapabilitiesFactory hardwareCapabilitiesFactory) IHardwareCapabilitiesFactory hardwareCapabilitiesFactory,
ILocalStatisticsProvider localStatisticsProvider)
: IRequestHandler<RefreshFFmpegCapabilities> : IRequestHandler<RefreshFFmpegCapabilities>
{ {
public async Task Handle(RefreshFFmpegCapabilities request, CancellationToken cancellationToken) public async Task Handle(RefreshFFmpegCapabilities request, CancellationToken cancellationToken)
@ -24,6 +27,19 @@ public class RefreshFFmpegCapabilitiesHandler(
foreach (string ffmpegPath in maybeFFmpegPath) foreach (string ffmpegPath in maybeFFmpegPath)
{ {
_ = await hardwareCapabilitiesFactory.GetFFmpegCapabilities(ffmpegPath); _ = await hardwareCapabilitiesFactory.GetFFmpegCapabilities(ffmpegPath);
Option<string> maybeFFprobePath = await dbContext.ConfigElements
.GetValue<string>(ConfigElementKey.FFprobePath, cancellationToken)
.FilterT(File.Exists);
foreach (string ffprobePath in maybeFFprobePath)
{
Either<BaseError, MediaVersion> result = await localStatisticsProvider.GetStatistics(
ffprobePath,
Path.Combine(FileSystemLayout.ResourcesCacheFolder, "test.avs"));
hardwareCapabilitiesFactory.SetAviSynthInstalled(result.IsRight);
}
} }
} }
} }

3
ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs

@ -1,6 +1,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Threading.Channels; using System.Threading.Channels;
using ErsatzTV.Application.FFmpeg;
using ErsatzTV.Application.Subtitles; using ErsatzTV.Application.Subtitles;
using ErsatzTV.Core; using ErsatzTV.Core;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
@ -151,6 +152,8 @@ public class UpdateFFmpegSettingsHandler(
request.Settings.InitialSegmentCount, request.Settings.InitialSegmentCount,
cancellationToken); cancellationToken);
await workerChannel.WriteAsync(new RefreshFFmpegCapabilities(), cancellationToken);
return Unit.Default; return Unit.Default;
} }
} }

3
ErsatzTV.Application/Troubleshooting/Queries/GetTroubleshootingInfoHandler.cs

@ -74,6 +74,7 @@ public class GetTroubleshootingInfoHandler : IRequestHandler<GetTroubleshootingI
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
bool aviSynthDemuxer = false; bool aviSynthDemuxer = false;
bool aviSynthInstalled = false;
string nvidiaCapabilities = null; string nvidiaCapabilities = null;
StringBuilder qsvCapabilities = new(); StringBuilder qsvCapabilities = new();
@ -162,6 +163,7 @@ public class GetTroubleshootingInfoHandler : IRequestHandler<GetTroubleshootingI
var ffmpegCapabilities = await _hardwareCapabilitiesFactory.GetFFmpegCapabilities(ffmpegPath.Value); var ffmpegCapabilities = await _hardwareCapabilitiesFactory.GetFFmpegCapabilities(ffmpegPath.Value);
aviSynthDemuxer = ffmpegCapabilities.HasDemuxFormat(FFmpegKnownFormat.AviSynth); aviSynthDemuxer = ffmpegCapabilities.HasDemuxFormat(FFmpegKnownFormat.AviSynth);
aviSynthInstalled = _hardwareCapabilitiesFactory.IsAviSynthInstalled();
} }
} }
@ -195,6 +197,7 @@ public class GetTroubleshootingInfoHandler : IRequestHandler<GetTroubleshootingI
channels, channels,
channelWatermarks, channelWatermarks,
aviSynthDemuxer, aviSynthDemuxer,
aviSynthInstalled,
nvidiaCapabilities, nvidiaCapabilities,
qsvCapabilities.ToString(), qsvCapabilities.ToString(),
vaapiCapabilities.ToString(), vaapiCapabilities.ToString(),

1
ErsatzTV.Application/Troubleshooting/TroubleshootingInfo.cs

@ -15,6 +15,7 @@ public record TroubleshootingInfo(
List<Channel> Channels, List<Channel> Channels,
List<ChannelWatermark> Watermarks, List<ChannelWatermark> Watermarks,
bool AviSynthDemuxer, bool AviSynthDemuxer,
bool AviSynthInstalled,
string NvidiaCapabilities, string NvidiaCapabilities,
string QsvCapabilities, string QsvCapabilities,
string VaapiCapabilities, string VaapiCapabilities,

30
ErsatzTV.FFmpeg/Capabilities/HardwareCapabilitiesFactory.cs

@ -152,13 +152,13 @@ public partial class HardwareCapabilitiesFactory(
// if we don't have a list of cuda devices, fall back to ffmpeg check // if we don't have a list of cuda devices, fall back to ffmpeg check
string[] arguments = string[] arguments =
{ [
"-f", "lavfi", "-f", "lavfi",
"-i", "nullsrc", "-i", "nullsrc",
"-c:v", "h264_nvenc", "-c:v", "h264_nvenc",
"-gpu", "list", "-gpu", "list",
"-f", "null", "-" "-f", "null", "-"
}; ];
BufferedCommandResult result = await Cli.Wrap(ffmpegPath) BufferedCommandResult result = await Cli.Wrap(ffmpegPath)
.WithArguments(arguments) .WithArguments(arguments)
@ -310,6 +310,26 @@ public partial class HardwareCapabilitiesFactory(
public List<string> GetVideoToolboxEncoders() => VideoToolboxUtil.GetAvailableEncoders(logger); public List<string> GetVideoToolboxEncoders() => VideoToolboxUtil.GetAvailableEncoders(logger);
public void SetAviSynthInstalled(bool aviSynthInstalled)
{
var cacheKey = string.Format(
CultureInfo.InvariantCulture,
FFmpegCapabilitiesCacheKeyFormat,
"avisynth_installed");
memoryCache.Set(cacheKey, aviSynthInstalled);
}
public bool IsAviSynthInstalled()
{
var cacheKey = string.Format(
CultureInfo.InvariantCulture,
FFmpegCapabilitiesCacheKeyFormat,
"avisynth_installed");
return memoryCache.TryGetValue(cacheKey, out bool installed) && installed;
}
private async Task<IReadOnlySet<string>> GetFFmpegCapabilities( private async Task<IReadOnlySet<string>> GetFFmpegCapabilities(
string ffmpegPath, string ffmpegPath,
string capabilities, string capabilities,
@ -322,7 +342,7 @@ public partial class HardwareCapabilitiesFactory(
return cachedCapabilities; return cachedCapabilities;
} }
string[] arguments = { "-hide_banner", $"-{capabilities}" }; string[] arguments = ["-hide_banner", $"-{capabilities}"];
BufferedCommandResult result = await Cli.Wrap(ffmpegPath) BufferedCommandResult result = await Cli.Wrap(ffmpegPath)
.WithArguments(arguments) .WithArguments(arguments)
@ -351,7 +371,7 @@ public partial class HardwareCapabilitiesFactory(
return cachedCapabilities; return cachedCapabilities;
} }
string[] arguments = { "-hide_banner", "-h", "long" }; string[] arguments = ["-hide_banner", "-h", "long"];
BufferedCommandResult result = await Cli.Wrap(ffmpegPath) BufferedCommandResult result = await Cli.Wrap(ffmpegPath)
.WithArguments(arguments) .WithArguments(arguments)
@ -380,7 +400,7 @@ public partial class HardwareCapabilitiesFactory(
return cachedCapabilities; return cachedCapabilities;
} }
string[] arguments = { "-hide_banner", "-formats" }; string[] arguments = ["-hide_banner", "-formats"];
BufferedCommandResult result = await Cli.Wrap(ffmpegPath) BufferedCommandResult result = await Cli.Wrap(ffmpegPath)
.WithArguments(arguments) .WithArguments(arguments)

4
ErsatzTV.FFmpeg/Capabilities/IHardwareCapabilitiesFactory.cs

@ -31,4 +31,8 @@ public interface IHardwareCapabilitiesFactory
List<string> GetVideoToolboxDecoders(); List<string> GetVideoToolboxDecoders();
List<string> GetVideoToolboxEncoders(); List<string> GetVideoToolboxEncoders();
void SetAviSynthInstalled(bool aviSynthInstalled);
bool IsAviSynthInstalled();
} }

1
ErsatzTV/ErsatzTV.csproj

@ -104,6 +104,7 @@
<EmbeddedResource Include="Resources\sequential-schedule-import.schema.json" /> <EmbeddedResource Include="Resources\sequential-schedule-import.schema.json" />
<EmbeddedResource Include="Resources\sequential-schedule.schema.json" /> <EmbeddedResource Include="Resources\sequential-schedule.schema.json" />
<EmbeddedResource Include="Resources\empty.sqlite3" /> <EmbeddedResource Include="Resources\empty.sqlite3" />
<EmbeddedResource Include="Resources\test.avs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

3
ErsatzTV/Pages/Troubleshooting/Troubleshooting.razor

@ -159,7 +159,8 @@
info.FFmpegSettings, info.FFmpegSettings,
AviSynth = new AviSynth = new
{ {
Demuxer = info.AviSynthDemuxer Demuxer = info.AviSynthDemuxer,
Installed = info.AviSynthInstalled
}, },
info.Channels, info.Channels,
info.FFmpegProfiles info.FFmpegProfiles

2
ErsatzTV/Resources/test.avs

@ -0,0 +1,2 @@
ColorBars(width=640, height=360, pixel_type="YV12")
Trim(0, 299)

1
ErsatzTV/Services/RunOnce/ResourceExtractorService.cs

@ -26,6 +26,7 @@ public class ResourceExtractorService : BackgroundService
await ExtractResource(assembly, "ErsatzTV.png", stoppingToken); await ExtractResource(assembly, "ErsatzTV.png", stoppingToken);
await ExtractResource(assembly, "sequential-schedule.schema.json", stoppingToken); await ExtractResource(assembly, "sequential-schedule.schema.json", stoppingToken);
await ExtractResource(assembly, "sequential-schedule-import.schema.json", stoppingToken); await ExtractResource(assembly, "sequential-schedule-import.schema.json", stoppingToken);
await ExtractResource(assembly, "test.avs", stoppingToken);
await ExtractFontResource(assembly, "Sen.ttf", stoppingToken); await ExtractFontResource(assembly, "Sen.ttf", stoppingToken);
await ExtractFontResource(assembly, "Roboto-Regular.ttf", stoppingToken); await ExtractFontResource(assembly, "Roboto-Regular.ttf", stoppingToken);

Loading…
Cancel
Save