ffmpeg tweaks (#121)
* save reports from ffmpeg concat process * let ffmpeg determine thread count by default * disable stdin for ffmpeg processes
This commit is contained in:
@@ -63,7 +63,7 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
|
||||
.Bind(_ => createFFmpegProfile.NotLongerThan(50)(x => x.Name));
|
||||
|
||||
private Validation<BaseError, int> ValidateThreadCount(CreateFFmpegProfile createFFmpegProfile) =>
|
||||
createFFmpegProfile.AtLeast(1)(p => p.ThreadCount);
|
||||
createFFmpegProfile.AtLeast(0)(p => p.ThreadCount);
|
||||
|
||||
private async Task<Validation<BaseError, int>> ResolutionMustExist(CreateFFmpegProfile createFFmpegProfile) =>
|
||||
(await _resolutionRepository.Get(createFFmpegProfile.ResolutionId))
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
|
||||
.Bind(_ => updateFFmpegProfile.NotLongerThan(50)(x => x.Name));
|
||||
|
||||
private Validation<BaseError, int> ValidateThreadCount(UpdateFFmpegProfile updateFFmpegProfile) =>
|
||||
updateFFmpegProfile.AtLeast(1)(p => p.ThreadCount);
|
||||
updateFFmpegProfile.AtLeast(0)(p => p.ThreadCount);
|
||||
|
||||
private async Task<Validation<BaseError, int>> ResolutionMustExist(UpdateFFmpegProfile updateFFmpegProfile) =>
|
||||
(await _resolutionRepository.Get(updateFFmpegProfile.ResolutionId))
|
||||
|
||||
@@ -5,30 +5,38 @@ using ErsatzTV.Core.Domain;
|
||||
using ErsatzTV.Core.FFmpeg;
|
||||
using ErsatzTV.Core.Interfaces.Repositories;
|
||||
using LanguageExt;
|
||||
using static LanguageExt.Prelude;
|
||||
|
||||
namespace ErsatzTV.Application.Streaming.Queries
|
||||
{
|
||||
public class GetConcatProcessByChannelNumberHandler : FFmpegProcessHandler<GetConcatProcessByChannelNumber>
|
||||
{
|
||||
private readonly IConfigElementRepository _configElementRepository;
|
||||
private readonly FFmpegProcessService _ffmpegProcessService;
|
||||
|
||||
public GetConcatProcessByChannelNumberHandler(
|
||||
IChannelRepository channelRepository,
|
||||
IConfigElementRepository configElementRepository,
|
||||
FFmpegProcessService ffmpegProcessService)
|
||||
: base(channelRepository, configElementRepository) =>
|
||||
: base(channelRepository, configElementRepository)
|
||||
{
|
||||
_configElementRepository = configElementRepository;
|
||||
_ffmpegProcessService = ffmpegProcessService;
|
||||
}
|
||||
|
||||
protected override Task<Either<BaseError, Process>> GetProcess(
|
||||
protected override async Task<Either<BaseError, Process>> GetProcess(
|
||||
GetConcatProcessByChannelNumber request,
|
||||
Channel channel,
|
||||
string ffmpegPath) =>
|
||||
Right<BaseError, Process>(
|
||||
_ffmpegProcessService.ConcatChannel(
|
||||
ffmpegPath,
|
||||
channel,
|
||||
request.Scheme,
|
||||
request.Host)).AsTask();
|
||||
string ffmpegPath)
|
||||
{
|
||||
bool saveReports = await _configElementRepository.GetValue<bool>(ConfigElementKey.FFmpegSaveReports)
|
||||
.Map(result => result.IfNone(false));
|
||||
|
||||
return _ffmpegProcessService.ConcatChannel(
|
||||
ffmpegPath,
|
||||
saveReports,
|
||||
channel,
|
||||
request.Scheme,
|
||||
request.Host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ErsatzTV.CommandLine.Commands
|
||||
public string Name { get; set; }
|
||||
|
||||
[CommandOption("thread-count", Description = "The number of threads")]
|
||||
public int ThreadCount { get; set; } = 4;
|
||||
public int ThreadCount { get; set; } = 0;
|
||||
|
||||
[CommandOption("transcode", Description = "Whether to transcode all media")]
|
||||
public bool Transcode { get; set; } = true;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
new()
|
||||
{
|
||||
Name = name,
|
||||
ThreadCount = 4,
|
||||
ThreadCount = 0,
|
||||
Transcode = true,
|
||||
ResolutionId = resolution.Id,
|
||||
Resolution = resolution,
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace ErsatzTV.Core.FFmpeg
|
||||
private readonly string _ffmpegPath;
|
||||
private readonly bool _saveReports;
|
||||
private FFmpegComplexFilterBuilder _complexFilterBuilder = new();
|
||||
private bool _isConcat;
|
||||
|
||||
public FFmpegProcessBuilder(string ffmpegPath, bool saveReports)
|
||||
{
|
||||
@@ -186,6 +187,8 @@ namespace ErsatzTV.Core.FFmpeg
|
||||
|
||||
public FFmpegProcessBuilder WithConcat(string concatPlaylist)
|
||||
{
|
||||
_isConcat = true;
|
||||
|
||||
var arguments = new List<string>
|
||||
{
|
||||
"-f", "concat",
|
||||
@@ -193,8 +196,6 @@ namespace ErsatzTV.Core.FFmpeg
|
||||
"-protocol_whitelist", "file,http,tcp,https,tcp,tls",
|
||||
"-probesize", "32",
|
||||
"-i", concatPlaylist,
|
||||
"-map", "0:v",
|
||||
"-map", "0:a",
|
||||
"-c", "copy",
|
||||
"-muxdelay", "0",
|
||||
"-muxpreload", "0"
|
||||
@@ -373,10 +374,13 @@ namespace ErsatzTV.Core.FFmpeg
|
||||
|
||||
if (_saveReports)
|
||||
{
|
||||
string fileName = Path.Combine(FileSystemLayout.FFmpegReportsFolder, "%p-%t.log");
|
||||
string fileName = _isConcat
|
||||
? Path.Combine(FileSystemLayout.FFmpegReportsFolder, "ffmpeg-%t-concat.log")
|
||||
: Path.Combine(FileSystemLayout.FFmpegReportsFolder, "ffmpeg-%t-transcode.log");
|
||||
startInfo.EnvironmentVariables.Add("FFREPORT", $"file={fileName}:level=32");
|
||||
}
|
||||
|
||||
startInfo.ArgumentList.Add("-nostdin");
|
||||
foreach (string argument in _arguments)
|
||||
{
|
||||
startInfo.ArgumentList.Add(argument);
|
||||
|
||||
@@ -124,11 +124,11 @@ namespace ErsatzTV.Core.FFmpeg
|
||||
return builder.WithPipe().Build();
|
||||
}
|
||||
|
||||
public Process ConcatChannel(string ffmpegPath, Channel channel, string scheme, string host)
|
||||
public Process ConcatChannel(string ffmpegPath, bool saveReports, Channel channel, string scheme, string host)
|
||||
{
|
||||
FFmpegPlaybackSettings playbackSettings = _playbackSettingsCalculator.ConcatSettings;
|
||||
|
||||
return new FFmpegProcessBuilder(ffmpegPath, false)
|
||||
return new FFmpegProcessBuilder(ffmpegPath, saveReports)
|
||||
.WithThreads(1)
|
||||
.WithQuiet()
|
||||
.WithFormatFlags(playbackSettings.FormatFlags)
|
||||
|
||||
1829
ErsatzTV.Infrastructure/Migrations/20210331010449_Update_FFmpegProfile_ThreadCount.Designer.cs
generated
Normal file
1829
ErsatzTV.Infrastructure/Migrations/20210331010449_Update_FFmpegProfile_ThreadCount.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations
|
||||
{
|
||||
public partial class Update_FFmpegProfile_ThreadCount : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder) =>
|
||||
migrationBuilder.Sql(@"UPDATE FFmpegProfile SET ThreadCount = 0 WHERE ThreadCount = 4");
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,9 @@ namespace ErsatzTV.Controllers
|
||||
process =>
|
||||
{
|
||||
_logger.LogInformation("Starting ts stream for channel {ChannelNumber}", channelNumber);
|
||||
// _logger.LogDebug(
|
||||
// "ffmpeg concat arguments {FFmpegArguments}",
|
||||
// string.Join(" ", process.StartInfo.ArgumentList));
|
||||
process.Start();
|
||||
return new FileStreamResult(process.StandardOutput.BaseStream, "video/mp2t");
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ErsatzTV.Validators
|
||||
public FFmpegProfileEditViewModelValidator()
|
||||
{
|
||||
RuleFor(x => x.Name).NotEmpty();
|
||||
RuleFor(x => x.ThreadCount).GreaterThan(0);
|
||||
RuleFor(x => x.ThreadCount).GreaterThanOrEqualTo(0);
|
||||
|
||||
When(
|
||||
x => x.Transcode,
|
||||
|
||||
Reference in New Issue
Block a user