allow ffmpeg reports on windows (#547)

* enable troubleshooting reports on windows

* update changelog

* tweak changelog
This commit is contained in:
Jason Dove
2021-12-21 09:27:49 -06:00
committed by GitHub
parent 85b2a46353
commit 7b73677bad
6 changed files with 20 additions and 41 deletions
+1
View File
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased] ## [Unreleased]
### Fixed ### Fixed
- Fix other video and song scanners to include videos contained directly in top-level folders that are added to a library - Fix other video and song scanners to include videos contained directly in top-level folders that are added to a library
- Allow saving ffmpeg troubleshooting reports on Windows
## [0.3.3-alpha] - 2021-12-12 ## [0.3.3-alpha] - 2021-12-12
### Fixed ### Fixed
@@ -1,13 +1,11 @@
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core; using ErsatzTV.Core;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Runtime;
using LanguageExt; using LanguageExt;
namespace ErsatzTV.Application.FFmpegProfiles.Commands namespace ErsatzTV.Application.FFmpegProfiles.Commands
@@ -16,16 +14,13 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
{ {
private readonly IConfigElementRepository _configElementRepository; private readonly IConfigElementRepository _configElementRepository;
private readonly ILocalFileSystem _localFileSystem; private readonly ILocalFileSystem _localFileSystem;
private readonly IRuntimeInfo _runtimeInfo;
public UpdateFFmpegSettingsHandler( public UpdateFFmpegSettingsHandler(
IConfigElementRepository configElementRepository, IConfigElementRepository configElementRepository,
ILocalFileSystem localFileSystem, ILocalFileSystem localFileSystem)
IRuntimeInfo runtimeInfo)
{ {
_configElementRepository = configElementRepository; _configElementRepository = configElementRepository;
_localFileSystem = localFileSystem; _localFileSystem = localFileSystem;
_runtimeInfo = runtimeInfo;
} }
public Task<Either<BaseError, Unit>> Handle( public Task<Either<BaseError, Unit>> Handle(
@@ -36,8 +31,8 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
.Bind(v => v.ToEitherAsync()); .Bind(v => v.ToEitherAsync());
private async Task<Validation<BaseError, Unit>> Validate(UpdateFFmpegSettings request) => private async Task<Validation<BaseError, Unit>> Validate(UpdateFFmpegSettings request) =>
(await FFmpegMustExist(request), await FFprobeMustExist(request), ReportsAreNotSupportedOnWindows(request)) (await FFmpegMustExist(request), await FFprobeMustExist(request))
.Apply((_, _, _) => Unit.Default); .Apply((_, _) => Unit.Default);
private Task<Validation<BaseError, Unit>> FFmpegMustExist(UpdateFFmpegSettings request) => private Task<Validation<BaseError, Unit>> FFmpegMustExist(UpdateFFmpegSettings request) =>
ValidateToolPath(request.Settings.FFmpegPath, "ffmpeg"); ValidateToolPath(request.Settings.FFmpegPath, "ffmpeg");
@@ -45,16 +40,6 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
private Task<Validation<BaseError, Unit>> FFprobeMustExist(UpdateFFmpegSettings request) => private Task<Validation<BaseError, Unit>> FFprobeMustExist(UpdateFFmpegSettings request) =>
ValidateToolPath(request.Settings.FFprobePath, "ffprobe"); ValidateToolPath(request.Settings.FFprobePath, "ffprobe");
private Validation<BaseError, Unit> ReportsAreNotSupportedOnWindows(UpdateFFmpegSettings request)
{
if (request.Settings.SaveReports && _runtimeInfo.IsOSPlatform(OSPlatform.Windows))
{
return BaseError.New("FFmpeg reports are not supported on Windows");
}
return Unit.Default;
}
private async Task<Validation<BaseError, Unit>> ValidateToolPath(string path, string name) private async Task<Validation<BaseError, Unit>> ValidateToolPath(string path, string name)
{ {
if (!_localFileSystem.FileExists(path)) if (!_localFileSystem.FileExists(path))
@@ -1,11 +1,9 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core; using ErsatzTV.Core;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Interfaces.Runtime;
using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions; using ErsatzTV.Infrastructure.Extensions;
using LanguageExt; using LanguageExt;
@@ -16,16 +14,13 @@ namespace ErsatzTV.Application.Streaming.Queries
public class GetConcatProcessByChannelNumberHandler : FFmpegProcessHandler<GetConcatProcessByChannelNumber> public class GetConcatProcessByChannelNumberHandler : FFmpegProcessHandler<GetConcatProcessByChannelNumber>
{ {
private readonly IFFmpegProcessService _ffmpegProcessService; private readonly IFFmpegProcessService _ffmpegProcessService;
private readonly IRuntimeInfo _runtimeInfo;
public GetConcatProcessByChannelNumberHandler( public GetConcatProcessByChannelNumberHandler(
IDbContextFactory<TvContext> dbContextFactory, IDbContextFactory<TvContext> dbContextFactory,
IFFmpegProcessService ffmpegProcessService, IFFmpegProcessService ffmpegProcessService)
IRuntimeInfo runtimeInfo)
: base(dbContextFactory) : base(dbContextFactory)
{ {
_ffmpegProcessService = ffmpegProcessService; _ffmpegProcessService = ffmpegProcessService;
_runtimeInfo = runtimeInfo;
} }
protected override async Task<Either<BaseError, PlayoutItemProcessModel>> GetProcess( protected override async Task<Either<BaseError, PlayoutItemProcessModel>> GetProcess(
@@ -34,7 +29,7 @@ namespace ErsatzTV.Application.Streaming.Queries
Channel channel, Channel channel,
string ffmpegPath) string ffmpegPath)
{ {
bool saveReports = !_runtimeInfo.IsOSPlatform(OSPlatform.Windows) && await dbContext.ConfigElements bool saveReports = await dbContext.ConfigElements
.GetValue<bool>(ConfigElementKey.FFmpegSaveReports) .GetValue<bool>(ConfigElementKey.FFmpegSaveReports)
.Map(result => result.IfNone(false)); .Map(result => result.IfNone(false));
@@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core; using ErsatzTV.Core;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
@@ -15,7 +14,6 @@ using ErsatzTV.Core.Interfaces.Jellyfin;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Interfaces.Plex; using ErsatzTV.Core.Interfaces.Plex;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Runtime;
using ErsatzTV.Core.Scheduling; using ErsatzTV.Core.Scheduling;
using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Data;
using ErsatzTV.Infrastructure.Extensions; using ErsatzTV.Infrastructure.Extensions;
@@ -36,7 +34,6 @@ namespace ErsatzTV.Application.Streaming.Queries
private readonly IJellyfinPathReplacementService _jellyfinPathReplacementService; private readonly IJellyfinPathReplacementService _jellyfinPathReplacementService;
private readonly ILocalFileSystem _localFileSystem; private readonly ILocalFileSystem _localFileSystem;
private readonly IPlexPathReplacementService _plexPathReplacementService; private readonly IPlexPathReplacementService _plexPathReplacementService;
private readonly IRuntimeInfo _runtimeInfo;
private readonly ISongVideoGenerator _songVideoGenerator; private readonly ISongVideoGenerator _songVideoGenerator;
public GetPlayoutItemProcessByChannelNumberHandler( public GetPlayoutItemProcessByChannelNumberHandler(
@@ -49,7 +46,6 @@ namespace ErsatzTV.Application.Streaming.Queries
IMediaCollectionRepository mediaCollectionRepository, IMediaCollectionRepository mediaCollectionRepository,
ITelevisionRepository televisionRepository, ITelevisionRepository televisionRepository,
IArtistRepository artistRepository, IArtistRepository artistRepository,
IRuntimeInfo runtimeInfo,
ISongVideoGenerator songVideoGenerator) ISongVideoGenerator songVideoGenerator)
: base(dbContextFactory) : base(dbContextFactory)
{ {
@@ -61,7 +57,6 @@ namespace ErsatzTV.Application.Streaming.Queries
_mediaCollectionRepository = mediaCollectionRepository; _mediaCollectionRepository = mediaCollectionRepository;
_televisionRepository = televisionRepository; _televisionRepository = televisionRepository;
_artistRepository = artistRepository; _artistRepository = artistRepository;
_runtimeInfo = runtimeInfo;
_songVideoGenerator = songVideoGenerator; _songVideoGenerator = songVideoGenerator;
} }
@@ -142,7 +137,7 @@ namespace ErsatzTV.Application.Streaming.Queries
ffmpegPath); ffmpegPath);
} }
bool saveReports = !_runtimeInfo.IsOSPlatform(OSPlatform.Windows) && await dbContext.ConfigElements bool saveReports = await dbContext.ConfigElements
.GetValue<bool>(ConfigElementKey.FFmpegSaveReports) .GetValue<bool>(ConfigElementKey.FFmpegSaveReports)
.Map(result => result.IfNone(false)); .Map(result => result.IfNone(false));
@@ -22,6 +22,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
@@ -641,6 +642,17 @@ namespace ErsatzTV.Core.FFmpeg
string fileName = _isConcat string fileName = _isConcat
? Path.Combine(FileSystemLayout.FFmpegReportsFolder, "ffmpeg-%t-concat.log") ? Path.Combine(FileSystemLayout.FFmpegReportsFolder, "ffmpeg-%t-concat.log")
: Path.Combine(FileSystemLayout.FFmpegReportsFolder, "ffmpeg-%t-transcode.log"); : Path.Combine(FileSystemLayout.FFmpegReportsFolder, "ffmpeg-%t-transcode.log");
// rework filename in a format that works on windows
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// \ is escape, so use / for directory separators
fileName = fileName.Replace(@"\", @"/");
// colon after drive letter needs to be escaped
fileName = fileName.Replace(@":/", @"\:/");
}
startInfo.EnvironmentVariables.Add("FFREPORT", $"file={fileName}:level=32"); startInfo.EnvironmentVariables.Add("FFREPORT", $"file={fileName}:level=32");
} }
@@ -2,9 +2,7 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Interfaces.Runtime; using ErsatzTV.Core.Interfaces.Runtime;
using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Data;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
@@ -33,13 +31,6 @@ namespace ErsatzTV.Services.RunOnce
await using TvContext dbContext = scope.ServiceProvider.GetRequiredService<TvContext>(); await using TvContext dbContext = scope.ServiceProvider.GetRequiredService<TvContext>();
IRuntimeInfo runtimeInfo = scope.ServiceProvider.GetRequiredService<IRuntimeInfo>(); IRuntimeInfo runtimeInfo = scope.ServiceProvider.GetRequiredService<IRuntimeInfo>();
if (runtimeInfo != null && runtimeInfo.IsOSPlatform(OSPlatform.Windows))
{
_logger.LogInformation("Disabling ffmpeg reports on Windows platform");
IConfigElementRepository repo = scope.ServiceProvider.GetRequiredService<IConfigElementRepository>();
await repo.Upsert(ConfigElementKey.FFmpegSaveReports, false);
}
if (runtimeInfo != null && runtimeInfo.IsOSPlatform(OSPlatform.Linux) && if (runtimeInfo != null && runtimeInfo.IsOSPlatform(OSPlatform.Linux) &&
System.IO.Directory.Exists("/dev/dri")) System.IO.Directory.Exists("/dev/dri"))
{ {