normalize framerate (#122)
* normalize framerate * simplify audio normalization settings
This commit is contained in:
@@ -40,3 +40,6 @@ msbuild.wrn
|
|||||||
core
|
core
|
||||||
|
|
||||||
scripts/generate-api-sdk/swagger.json
|
scripts/generate-api-sdk/swagger.json
|
||||||
|
|
||||||
|
docker-compose.override.yml
|
||||||
|
|
||||||
|
|||||||
@@ -11,17 +11,16 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
|
|||||||
bool Transcode,
|
bool Transcode,
|
||||||
HardwareAccelerationKind HardwareAcceleration,
|
HardwareAccelerationKind HardwareAcceleration,
|
||||||
int ResolutionId,
|
int ResolutionId,
|
||||||
bool NormalizeResolution,
|
bool NormalizeVideo,
|
||||||
string VideoCodec,
|
string VideoCodec,
|
||||||
bool NormalizeVideoCodec,
|
|
||||||
int VideoBitrate,
|
int VideoBitrate,
|
||||||
int VideoBufferSize,
|
int VideoBufferSize,
|
||||||
string AudioCodec,
|
string AudioCodec,
|
||||||
bool NormalizeAudioCodec,
|
|
||||||
int AudioBitrate,
|
int AudioBitrate,
|
||||||
int AudioBufferSize,
|
int AudioBufferSize,
|
||||||
int AudioVolume,
|
int AudioVolume,
|
||||||
int AudioChannels,
|
int AudioChannels,
|
||||||
int AudioSampleRate,
|
int AudioSampleRate,
|
||||||
bool NormalizeAudio) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
|
bool NormalizeAudio,
|
||||||
|
string FrameRate) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,19 +43,18 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
|
|||||||
Transcode = request.Transcode,
|
Transcode = request.Transcode,
|
||||||
HardwareAcceleration = request.HardwareAcceleration,
|
HardwareAcceleration = request.HardwareAcceleration,
|
||||||
ResolutionId = resolutionId,
|
ResolutionId = resolutionId,
|
||||||
NormalizeResolution = request.NormalizeResolution,
|
NormalizeVideo = request.NormalizeVideo,
|
||||||
VideoCodec = request.VideoCodec,
|
VideoCodec = request.VideoCodec,
|
||||||
NormalizeVideoCodec = request.NormalizeVideoCodec,
|
|
||||||
VideoBitrate = request.VideoBitrate,
|
VideoBitrate = request.VideoBitrate,
|
||||||
VideoBufferSize = request.VideoBufferSize,
|
VideoBufferSize = request.VideoBufferSize,
|
||||||
AudioCodec = request.AudioCodec,
|
AudioCodec = request.AudioCodec,
|
||||||
NormalizeAudioCodec = request.NormalizeAudioCodec,
|
|
||||||
AudioBitrate = request.AudioBitrate,
|
AudioBitrate = request.AudioBitrate,
|
||||||
AudioBufferSize = request.AudioBufferSize,
|
AudioBufferSize = request.AudioBufferSize,
|
||||||
AudioVolume = request.AudioVolume,
|
AudioVolume = request.AudioVolume,
|
||||||
AudioChannels = request.AudioChannels,
|
AudioChannels = request.AudioChannels,
|
||||||
AudioSampleRate = request.AudioSampleRate,
|
AudioSampleRate = request.AudioSampleRate,
|
||||||
NormalizeAudio = request.NormalizeAudio
|
NormalizeAudio = request.NormalizeAudio,
|
||||||
|
FrameRate = request.FrameRate
|
||||||
});
|
});
|
||||||
|
|
||||||
private Validation<BaseError, string> ValidateName(CreateFFmpegProfile createFFmpegProfile) =>
|
private Validation<BaseError, string> ValidateName(CreateFFmpegProfile createFFmpegProfile) =>
|
||||||
|
|||||||
@@ -12,17 +12,16 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
|
|||||||
bool Transcode,
|
bool Transcode,
|
||||||
HardwareAccelerationKind HardwareAcceleration,
|
HardwareAccelerationKind HardwareAcceleration,
|
||||||
int ResolutionId,
|
int ResolutionId,
|
||||||
bool NormalizeResolution,
|
bool NormalizeVideo,
|
||||||
string VideoCodec,
|
string VideoCodec,
|
||||||
bool NormalizeVideoCodec,
|
|
||||||
int VideoBitrate,
|
int VideoBitrate,
|
||||||
int VideoBufferSize,
|
int VideoBufferSize,
|
||||||
string AudioCodec,
|
string AudioCodec,
|
||||||
bool NormalizeAudioCodec,
|
|
||||||
int AudioBitrate,
|
int AudioBitrate,
|
||||||
int AudioBufferSize,
|
int AudioBufferSize,
|
||||||
int AudioVolume,
|
int AudioVolume,
|
||||||
int AudioChannels,
|
int AudioChannels,
|
||||||
int AudioSampleRate,
|
int AudioSampleRate,
|
||||||
bool NormalizeAudio) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
|
bool NormalizeAudio,
|
||||||
|
string FrameRate) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,19 +37,18 @@ namespace ErsatzTV.Application.FFmpegProfiles.Commands
|
|||||||
p.Transcode = update.Transcode;
|
p.Transcode = update.Transcode;
|
||||||
p.HardwareAcceleration = update.HardwareAcceleration;
|
p.HardwareAcceleration = update.HardwareAcceleration;
|
||||||
p.ResolutionId = update.ResolutionId;
|
p.ResolutionId = update.ResolutionId;
|
||||||
p.NormalizeResolution = update.NormalizeResolution;
|
p.NormalizeVideo = update.NormalizeVideo;
|
||||||
p.VideoCodec = update.VideoCodec;
|
p.VideoCodec = update.VideoCodec;
|
||||||
p.NormalizeVideoCodec = update.NormalizeVideoCodec;
|
|
||||||
p.VideoBitrate = update.VideoBitrate;
|
p.VideoBitrate = update.VideoBitrate;
|
||||||
p.VideoBufferSize = update.VideoBufferSize;
|
p.VideoBufferSize = update.VideoBufferSize;
|
||||||
p.AudioCodec = update.AudioCodec;
|
p.AudioCodec = update.AudioCodec;
|
||||||
p.NormalizeAudioCodec = update.NormalizeAudioCodec;
|
|
||||||
p.AudioBitrate = update.AudioBitrate;
|
p.AudioBitrate = update.AudioBitrate;
|
||||||
p.AudioBufferSize = update.AudioBufferSize;
|
p.AudioBufferSize = update.AudioBufferSize;
|
||||||
p.AudioVolume = update.AudioVolume;
|
p.AudioVolume = update.AudioVolume;
|
||||||
p.AudioChannels = update.AudioChannels;
|
p.AudioChannels = update.AudioChannels;
|
||||||
p.AudioSampleRate = update.AudioSampleRate;
|
p.AudioSampleRate = update.AudioSampleRate;
|
||||||
p.NormalizeAudio = update.NormalizeAudio;
|
p.NormalizeAudio = update.NormalizeAudio;
|
||||||
|
p.FrameRate = update.FrameRate;
|
||||||
await _ffmpegProfileRepository.Update(p);
|
await _ffmpegProfileRepository.Update(p);
|
||||||
return ProjectToViewModel(p);
|
return ProjectToViewModel(p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,17 +10,16 @@ namespace ErsatzTV.Application.FFmpegProfiles
|
|||||||
bool Transcode,
|
bool Transcode,
|
||||||
HardwareAccelerationKind HardwareAcceleration,
|
HardwareAccelerationKind HardwareAcceleration,
|
||||||
ResolutionViewModel Resolution,
|
ResolutionViewModel Resolution,
|
||||||
bool NormalizeResolution,
|
bool NormalizeVideo,
|
||||||
string VideoCodec,
|
string VideoCodec,
|
||||||
bool NormalizeVideoCodec,
|
|
||||||
int VideoBitrate,
|
int VideoBitrate,
|
||||||
int VideoBufferSize,
|
int VideoBufferSize,
|
||||||
string AudioCodec,
|
string AudioCodec,
|
||||||
bool NormalizeAudioCodec,
|
|
||||||
int AudioBitrate,
|
int AudioBitrate,
|
||||||
int AudioBufferSize,
|
int AudioBufferSize,
|
||||||
int AudioVolume,
|
int AudioVolume,
|
||||||
int AudioChannels,
|
int AudioChannels,
|
||||||
int AudioSampleRate,
|
int AudioSampleRate,
|
||||||
bool NormalizeAudio);
|
bool NormalizeAudio,
|
||||||
|
string FrameRate);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,19 +13,18 @@ namespace ErsatzTV.Application.FFmpegProfiles
|
|||||||
profile.Transcode,
|
profile.Transcode,
|
||||||
profile.HardwareAcceleration,
|
profile.HardwareAcceleration,
|
||||||
Project(profile.Resolution),
|
Project(profile.Resolution),
|
||||||
profile.NormalizeResolution,
|
profile.NormalizeVideo,
|
||||||
profile.VideoCodec,
|
profile.VideoCodec,
|
||||||
profile.NormalizeVideoCodec,
|
|
||||||
profile.VideoBitrate,
|
profile.VideoBitrate,
|
||||||
profile.VideoBufferSize,
|
profile.VideoBufferSize,
|
||||||
profile.AudioCodec,
|
profile.AudioCodec,
|
||||||
profile.NormalizeAudioCodec,
|
|
||||||
profile.AudioBitrate,
|
profile.AudioBitrate,
|
||||||
profile.AudioBufferSize,
|
profile.AudioBufferSize,
|
||||||
profile.AudioVolume,
|
profile.AudioVolume,
|
||||||
profile.AudioChannels,
|
profile.AudioChannels,
|
||||||
profile.AudioSampleRate,
|
profile.AudioSampleRate,
|
||||||
profile.NormalizeAudio);
|
profile.NormalizeAudio,
|
||||||
|
profile.FrameRate);
|
||||||
|
|
||||||
private static ResolutionViewModel Project(Resolution resolution) =>
|
private static ResolutionViewModel Project(Resolution resolution) =>
|
||||||
new(resolution.Id, resolution.Name, resolution.Width, resolution.Height);
|
new(resolution.Id, resolution.Name, resolution.Width, resolution.Height);
|
||||||
|
|||||||
@@ -163,9 +163,9 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ShouldNot_SetScaledSize_When_NotNormalizingResolution_ForTransportStream()
|
public void ShouldNot_SetScaledSize_When_NotNormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with { NormalizeResolution = false };
|
FFmpegProfile ffmpegProfile = TestProfile() with { NormalizeVideo = false };
|
||||||
|
|
||||||
FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
|
FFmpegPlaybackSettings actual = _calculator.CalculateSettings(
|
||||||
StreamingMode.TransportStream,
|
StreamingMode.TransportStream,
|
||||||
@@ -184,7 +184,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -303,11 +303,11 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_NotPadToDesiredResolution_When_NotNormalizingResolution()
|
public void Should_NotPadToDesiredResolution_When_NotNormalizingVideo()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeResolution = false,
|
NormalizeVideo = false,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
Resolution = new Resolution { Width = 1920, Height = 1080 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -332,9 +332,8 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = false,
|
|
||||||
VideoCodec = "testCodec"
|
VideoCodec = "testCodec"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -357,13 +356,12 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void
|
public void
|
||||||
Should_SetDesiredVideoCodec_When_ContentIsCorrectSize_And_NormalizingWrongCodec_ForTransportStream()
|
Should_SetDesiredVideoCodec_When_ContentIsCorrectSize_And_NormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = true,
|
|
||||||
VideoCodec = "testCodec"
|
VideoCodec = "testCodec"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -387,13 +385,12 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void
|
public void
|
||||||
Should_SetCopyVideoCodec_When_ContentIsCorrectSize_And_NormalizingWrongCodec_ForHttpLiveStreaming()
|
Should_SetCopyVideoCodec_When_ContentIsCorrectSize_And_NormalizingVideo_ForHttpLiveStreaming()
|
||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = true,
|
|
||||||
VideoCodec = "testCodec"
|
VideoCodec = "testCodec"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -420,9 +417,8 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = true,
|
|
||||||
VideoCodec = "libx264"
|
VideoCodec = "libx264"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -446,13 +442,12 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void
|
public void
|
||||||
Should_SetCopyVideoCodec_When_ContentIsCorrectSize_And_NotNormalizingWrongCodec_ForTransportStream()
|
Should_SetCopyVideoCodec_When_ContentIsCorrectSize_And_NotNormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = false,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = false,
|
|
||||||
VideoCodec = "libx264"
|
VideoCodec = "libx264"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -479,9 +474,8 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = false,
|
|
||||||
VideoBitrate = 2525
|
VideoBitrate = 2525
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -503,13 +497,12 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetVideoBitrate_When_ContentIsCorrectSize_And_NormalizingWrongCodec_ForTransportStream()
|
public void Should_SetVideoBitrate_When_ContentIsCorrectSize_And_NormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = true,
|
|
||||||
VideoBitrate = 2525
|
VideoBitrate = 2525
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -536,9 +529,8 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = false,
|
|
||||||
VideoBufferSize = 2525
|
VideoBufferSize = 2525
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -561,13 +553,12 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void
|
public void
|
||||||
Should_SetVideoBufferSize_When_ContentIsCorrectSize_And_NormalizingWrongCodec_ForTransportStream()
|
Should_SetVideoBufferSize_When_ContentIsCorrectSize_And_NormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
var ffmpegProfile = new FFmpegProfile
|
var ffmpegProfile = new FFmpegProfile
|
||||||
{
|
{
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
Resolution = new Resolution { Width = 1920, Height = 1080 },
|
||||||
NormalizeVideoCodec = true,
|
|
||||||
VideoBufferSize = 2525
|
VideoBufferSize = 2525
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -594,7 +585,7 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
NormalizeAudio = true,
|
||||||
AudioCodec = "aac"
|
AudioCodec = "aac"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -613,11 +604,11 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetCopyAudioCodec_When_NotNormalizingWrongCodec_ForTransportStream()
|
public void Should_SetCopyAudioCodec_When_NotNormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = false,
|
NormalizeAudio = false,
|
||||||
AudioCodec = "aac"
|
AudioCodec = "aac"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -636,11 +627,11 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetDesiredAudioCodec_When_NormalizingWrongCodec_ForTransportStream()
|
public void Should_SetDesiredAudioCodec_When_NormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
NormalizeAudio = true,
|
||||||
AudioCodec = "aac"
|
AudioCodec = "aac"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -659,11 +650,11 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetCopyAudioCodec_When_NormalizingWrongCodec_ForHttpLiveStreaming()
|
public void Should_SetCopyAudioCodec_When_NormalizingVideo_ForHttpLiveStreaming()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
NormalizeAudio = true,
|
||||||
AudioCodec = "aac"
|
AudioCodec = "aac"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -682,11 +673,11 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetAudioBitrate_When_NormalizingWrongCodec_ForTransportStream()
|
public void Should_SetAudioBitrate_When_NormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
NormalizeAudio = true,
|
||||||
AudioBitrate = 2424
|
AudioBitrate = 2424
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -705,11 +696,11 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetAudioBufferSize_When_NormalizingWrongCodec_ForTransportStream()
|
public void Should_SetAudioBufferSize_When_NormalizingVideo_ForTransportStream()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
NormalizeAudio = true,
|
||||||
AudioBufferSize = 2424
|
AudioBufferSize = 2424
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -732,7 +723,6 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
|
||||||
NormalizeAudio = true,
|
NormalizeAudio = true,
|
||||||
AudioCodec = "ac3",
|
AudioCodec = "ac3",
|
||||||
AudioChannels = 6
|
AudioChannels = 6
|
||||||
@@ -757,7 +747,6 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
|
||||||
NormalizeAudio = true,
|
NormalizeAudio = true,
|
||||||
AudioCodec = "ac3",
|
AudioCodec = "ac3",
|
||||||
AudioSampleRate = 48
|
AudioSampleRate = 48
|
||||||
@@ -778,11 +767,10 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetAudioChannels_When_NormalizingWrongCodecAndAudio_ForTransportStream()
|
public void Should_SetAudioChannels_When_NormalizingVideoAndAudio_ForTransportStream()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
|
||||||
NormalizeAudio = true,
|
NormalizeAudio = true,
|
||||||
AudioChannels = 6
|
AudioChannels = 6
|
||||||
};
|
};
|
||||||
@@ -802,11 +790,10 @@ namespace ErsatzTV.Core.Tests.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Should_SetAudioSampleRate_When_NormalizingWrongCodecAndAudio_ForTransportStream()
|
public void Should_SetAudioSampleRate_When_NormalizingVideoAndAudio_ForTransportStream()
|
||||||
{
|
{
|
||||||
FFmpegProfile ffmpegProfile = TestProfile() with
|
FFmpegProfile ffmpegProfile = TestProfile() with
|
||||||
{
|
{
|
||||||
NormalizeAudioCodec = true,
|
|
||||||
NormalizeAudio = true,
|
NormalizeAudio = true,
|
||||||
AudioSampleRate = 48
|
AudioSampleRate = 48
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,13 +9,12 @@
|
|||||||
public HardwareAccelerationKind HardwareAcceleration { get; set; }
|
public HardwareAccelerationKind HardwareAcceleration { get; set; }
|
||||||
public int ResolutionId { get; set; }
|
public int ResolutionId { get; set; }
|
||||||
public Resolution Resolution { get; set; }
|
public Resolution Resolution { get; set; }
|
||||||
public bool NormalizeResolution { get; set; }
|
|
||||||
public string VideoCodec { get; set; }
|
public string VideoCodec { get; set; }
|
||||||
public bool NormalizeVideoCodec { get; set; }
|
public bool NormalizeVideo { get; set; }
|
||||||
public int VideoBitrate { get; set; }
|
public int VideoBitrate { get; set; }
|
||||||
public int VideoBufferSize { get; set; }
|
public int VideoBufferSize { get; set; }
|
||||||
|
public string FrameRate { get; set; }
|
||||||
public string AudioCodec { get; set; }
|
public string AudioCodec { get; set; }
|
||||||
public bool NormalizeAudioCodec { get; set; }
|
|
||||||
public int AudioBitrate { get; set; }
|
public int AudioBitrate { get; set; }
|
||||||
public int AudioBufferSize { get; set; }
|
public int AudioBufferSize { get; set; }
|
||||||
public int AudioVolume { get; set; }
|
public int AudioVolume { get; set; }
|
||||||
@@ -40,9 +39,8 @@
|
|||||||
AudioVolume = 100,
|
AudioVolume = 100,
|
||||||
AudioChannels = 2,
|
AudioChannels = 2,
|
||||||
AudioSampleRate = 48,
|
AudioSampleRate = 48,
|
||||||
NormalizeResolution = true,
|
NormalizeVideo = true,
|
||||||
NormalizeVideoCodec = true,
|
FrameRate = "24",
|
||||||
NormalizeAudioCodec = true,
|
|
||||||
NormalizeAudio = true
|
NormalizeAudio = true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
{
|
{
|
||||||
private Option<TimeSpan> _audioDuration = None;
|
private Option<TimeSpan> _audioDuration = None;
|
||||||
private bool _deinterlace;
|
private bool _deinterlace;
|
||||||
|
private Option<string> _frameRate = None;
|
||||||
private Option<HardwareAccelerationKind> _hardwareAccelerationKind = None;
|
private Option<HardwareAccelerationKind> _hardwareAccelerationKind = None;
|
||||||
private string _inputCodec;
|
private string _inputCodec;
|
||||||
private Option<IDisplaySize> _padToSize = None;
|
private Option<IDisplaySize> _padToSize = None;
|
||||||
@@ -54,6 +55,12 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FFmpegComplexFilterBuilder WithFrameRate(Option<string> frameRate)
|
||||||
|
{
|
||||||
|
_frameRate = frameRate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Option<FFmpegComplexFilter> Build(int videoStreamIndex, int audioStreamIndex)
|
public Option<FFmpegComplexFilter> Build(int videoStreamIndex, int audioStreamIndex)
|
||||||
{
|
{
|
||||||
var complexFilter = new StringBuilder();
|
var complexFilter = new StringBuilder();
|
||||||
@@ -104,6 +111,8 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_frameRate.IfSome(frameRate => filterQueue.Add($"fps=fps={frameRate}"));
|
||||||
|
|
||||||
_scaleToSize.IfSome(
|
_scaleToSize.IfSome(
|
||||||
size =>
|
size =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
public Option<TimeSpan> StreamSeek { get; set; }
|
public Option<TimeSpan> StreamSeek { get; set; }
|
||||||
public Option<IDisplaySize> ScaledSize { get; set; }
|
public Option<IDisplaySize> ScaledSize { get; set; }
|
||||||
public bool PadToDesiredResolution { get; set; }
|
public bool PadToDesiredResolution { get; set; }
|
||||||
public string ScalingAlgorithm => "fast_bilinear"; // TODO: from config, add tests
|
|
||||||
public string VideoCodec { get; set; }
|
public string VideoCodec { get; set; }
|
||||||
public Option<int> VideoBitrate { get; set; }
|
public Option<int> VideoBitrate { get; set; }
|
||||||
public Option<int> VideoBufferSize { get; set; }
|
public Option<int> VideoBufferSize { get; set; }
|
||||||
@@ -27,5 +26,6 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
public Option<TimeSpan> AudioDuration { get; set; }
|
public Option<TimeSpan> AudioDuration { get; set; }
|
||||||
public string AudioCodec { get; set; }
|
public string AudioCodec { get; set; }
|
||||||
public bool Deinterlace { get; set; }
|
public bool Deinterlace { get; set; }
|
||||||
|
public Option<string> FrameRate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,11 +81,18 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
IDisplaySize sizeAfterScaling = result.ScaledSize.IfNone(version);
|
IDisplaySize sizeAfterScaling = result.ScaledSize.IfNone(version);
|
||||||
if (ffmpegProfile.NormalizeResolution && !sizeAfterScaling.IsSameSizeAs(ffmpegProfile.Resolution))
|
if (ffmpegProfile.NormalizeVideo && !sizeAfterScaling.IsSameSizeAs(ffmpegProfile.Resolution))
|
||||||
{
|
{
|
||||||
result.PadToDesiredResolution = true;
|
result.PadToDesiredResolution = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ffmpegProfile.NormalizeVideo)
|
||||||
|
{
|
||||||
|
result.FrameRate = string.IsNullOrWhiteSpace(ffmpegProfile.FrameRate)
|
||||||
|
? None
|
||||||
|
: Some(ffmpegProfile.FrameRate);
|
||||||
|
}
|
||||||
|
|
||||||
if (result.ScaledSize.IsSome || result.PadToDesiredResolution ||
|
if (result.ScaledSize.IsSome || result.PadToDesiredResolution ||
|
||||||
NeedToNormalizeVideoCodec(ffmpegProfile, videoStream))
|
NeedToNormalizeVideoCodec(ffmpegProfile, videoStream))
|
||||||
{
|
{
|
||||||
@@ -141,7 +148,7 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
};
|
};
|
||||||
|
|
||||||
private static bool NeedToScale(FFmpegProfile ffmpegProfile, MediaVersion version) =>
|
private static bool NeedToScale(FFmpegProfile ffmpegProfile, MediaVersion version) =>
|
||||||
ffmpegProfile.NormalizeResolution &&
|
ffmpegProfile.NormalizeVideo &&
|
||||||
IsIncorrectSize(ffmpegProfile.Resolution, version) ||
|
IsIncorrectSize(ffmpegProfile.Resolution, version) ||
|
||||||
IsTooLarge(ffmpegProfile.Resolution, version) ||
|
IsTooLarge(ffmpegProfile.Resolution, version) ||
|
||||||
IsOddSize(version);
|
IsOddSize(version);
|
||||||
@@ -159,10 +166,10 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
version.Height % 2 == 1 || version.Width % 2 == 1;
|
version.Height % 2 == 1 || version.Width % 2 == 1;
|
||||||
|
|
||||||
private static bool NeedToNormalizeVideoCodec(FFmpegProfile ffmpegProfile, MediaStream videoStream) =>
|
private static bool NeedToNormalizeVideoCodec(FFmpegProfile ffmpegProfile, MediaStream videoStream) =>
|
||||||
ffmpegProfile.NormalizeVideoCodec && ffmpegProfile.VideoCodec != videoStream.Codec;
|
ffmpegProfile.NormalizeVideo && ffmpegProfile.VideoCodec != videoStream.Codec;
|
||||||
|
|
||||||
private static bool NeedToNormalizeAudioCodec(FFmpegProfile ffmpegProfile, MediaStream audioStream) =>
|
private static bool NeedToNormalizeAudioCodec(FFmpegProfile ffmpegProfile, MediaStream audioStream) =>
|
||||||
ffmpegProfile.NormalizeAudioCodec && ffmpegProfile.AudioCodec != audioStream.Codec;
|
ffmpegProfile.NormalizeAudio && ffmpegProfile.AudioCodec != audioStream.Codec;
|
||||||
|
|
||||||
private static IDisplaySize CalculateScaledSize(FFmpegProfile ffmpegProfile, MediaVersion version)
|
private static IDisplaySize CalculateScaledSize(FFmpegProfile ffmpegProfile, MediaVersion version)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
const string X = "x=(w-text_w)/2";
|
const string X = "x=(w-text_w)/2";
|
||||||
const string Y = "y=(h-text_h)/3*2";
|
const string Y = "y=(h-text_h)/3*2";
|
||||||
|
|
||||||
string fontSize = text.Length > 60 ? "fontsize=40" : "fontsize=60";
|
string fontSize = text.Length > 80 ? "fontsize=30" : text.Length > 60 ? "fontsize=40" : "fontsize=60";
|
||||||
|
|
||||||
return WithFilterComplex(
|
return WithFilterComplex(
|
||||||
$"[0:0]scale={desiredResolution.Width}:{desiredResolution.Height},drawtext={FONT_FILE}:{fontSize}:{FONT_COLOR}:{X}:{Y}:text='{text}'[v]",
|
$"[0:0]scale={desiredResolution.Width}:{desiredResolution.Height},drawtext={FONT_FILE}:{fontSize}:{FONT_COLOR}:{X}:{Y}:text='{text}'[v]",
|
||||||
@@ -324,6 +324,12 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FFmpegProcessBuilder WithFrameRate(Option<string> frameRate)
|
||||||
|
{
|
||||||
|
_complexFilterBuilder = _complexFilterBuilder.WithFrameRate(frameRate);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public FFmpegProcessBuilder WithDeinterlace(bool deinterlace)
|
public FFmpegProcessBuilder WithDeinterlace(bool deinterlace)
|
||||||
{
|
{
|
||||||
_complexFilterBuilder = _complexFilterBuilder.WithDeinterlace(deinterlace);
|
_complexFilterBuilder = _complexFilterBuilder.WithDeinterlace(deinterlace);
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ namespace ErsatzTV.Core.FFmpeg
|
|||||||
.WithFormatFlags(playbackSettings.FormatFlags)
|
.WithFormatFlags(playbackSettings.FormatFlags)
|
||||||
.WithRealtimeOutput(playbackSettings.RealtimeOutput)
|
.WithRealtimeOutput(playbackSettings.RealtimeOutput)
|
||||||
.WithSeek(playbackSettings.StreamSeek)
|
.WithSeek(playbackSettings.StreamSeek)
|
||||||
.WithInputCodec(path, playbackSettings.HardwareAcceleration, videoStream.Codec);
|
.WithInputCodec(path, playbackSettings.HardwareAcceleration, videoStream.Codec)
|
||||||
|
.WithFrameRate(playbackSettings.FrameRate);
|
||||||
|
|
||||||
playbackSettings.ScaledSize.Match(
|
playbackSettings.ScaledSize.Match(
|
||||||
scaledSize =>
|
scaledSize =>
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ namespace ErsatzTV.Core.Scheduling
|
|||||||
peekMediaItem =>
|
peekMediaItem =>
|
||||||
{
|
{
|
||||||
customGroup = true;
|
customGroup = true;
|
||||||
|
|
||||||
MediaVersion peekVersion = peekMediaItem switch
|
MediaVersion peekVersion = peekMediaItem switch
|
||||||
{
|
{
|
||||||
Movie m => m.MediaVersions.Head(),
|
Movie m => m.MediaVersions.Head(),
|
||||||
|
|||||||
+1829
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
public partial class Add_FFmpegProfile_FrameRate : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
"NormalizeResolution",
|
||||||
|
"FFmpegProfile");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
"NormalizeVideoCodec",
|
||||||
|
"FFmpegProfile",
|
||||||
|
"NormalizeVideo");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
"FrameRate",
|
||||||
|
"FFmpegProfile",
|
||||||
|
"TEXT",
|
||||||
|
nullable: true,
|
||||||
|
defaultValue: "24");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
"FrameRate",
|
||||||
|
"FFmpegProfile");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
"NormalizeVideo",
|
||||||
|
"FFmpegProfile",
|
||||||
|
"NormalizeVideoCodec");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
"NormalizeResolution",
|
||||||
|
"FFmpegProfile",
|
||||||
|
"INTEGER",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1826
File diff suppressed because it is too large
Load Diff
+20
@@ -0,0 +1,20 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
public partial class Remove_FFmpegProfile_NormalizeAudioCodec : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder) =>
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
"NormalizeAudioCodec",
|
||||||
|
"FFmpegProfile");
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder) =>
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
"NormalizeAudioCodec",
|
||||||
|
"FFmpegProfile",
|
||||||
|
"INTEGER",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -240,6 +240,9 @@ namespace ErsatzTV.Infrastructure.Migrations
|
|||||||
b.Property<int>("AudioVolume")
|
b.Property<int>("AudioVolume")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("FrameRate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<int>("HardwareAcceleration")
|
b.Property<int>("HardwareAcceleration")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
@@ -249,13 +252,7 @@ namespace ErsatzTV.Infrastructure.Migrations
|
|||||||
b.Property<bool>("NormalizeAudio")
|
b.Property<bool>("NormalizeAudio")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<bool>("NormalizeAudioCodec")
|
b.Property<bool>("NormalizeVideo")
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<bool>("NormalizeResolution")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<bool>("NormalizeVideoCodec")
|
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<int>("ResolutionId")
|
b.Property<int>("ResolutionId")
|
||||||
|
|||||||
@@ -74,17 +74,17 @@
|
|||||||
@(context.Transcode ? "Yes" : "No")
|
@(context.Transcode ? "Yes" : "No")
|
||||||
</MudTd>
|
</MudTd>
|
||||||
<MudTd DataLabel="Resolution">
|
<MudTd DataLabel="Resolution">
|
||||||
<MudText Color="@(context.Transcode && context.NormalizeResolution ? Color.Tertiary : Color.Inherit)">
|
<MudText Color="@(context.Transcode && context.NormalizeVideo ? Color.Tertiary : Color.Inherit)">
|
||||||
@context.Resolution.Name
|
@context.Resolution.Name
|
||||||
</MudText>
|
</MudText>
|
||||||
</MudTd>
|
</MudTd>
|
||||||
<MudTd DataLabel="Video Codec">
|
<MudTd DataLabel="Video Codec">
|
||||||
<MudText Color="@(context.Transcode && context.NormalizeVideoCodec ? Color.Tertiary : Color.Inherit)">
|
<MudText Color="@(context.Transcode && context.NormalizeVideo ? Color.Tertiary : Color.Inherit)">
|
||||||
@context.VideoCodec
|
@context.VideoCodec
|
||||||
</MudText>
|
</MudText>
|
||||||
</MudTd>
|
</MudTd>
|
||||||
<MudTd DataLabel="Audio Codec">
|
<MudTd DataLabel="Audio Codec">
|
||||||
<MudText Color="@(context.Transcode && context.NormalizeAudioCodec ? Color.Tertiary : Color.Inherit)">
|
<MudText Color="@(context.Transcode && context.NormalizeAudio ? Color.Tertiary : Color.Inherit)">
|
||||||
@context.AudioCodec
|
@context.AudioCodec
|
||||||
</MudText>
|
</MudText>
|
||||||
</MudTd>
|
</MudTd>
|
||||||
|
|||||||
@@ -58,6 +58,9 @@
|
|||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
</MudElement>
|
</MudElement>
|
||||||
|
<MudElement HtmlTag="div" Class="mt-3">
|
||||||
|
<MudTextField Disabled="@(!_model.Transcode)" Label="Frame Rate" @bind-Value="_model.FrameRate" For="@(() => _model.FrameRate)" Adornment="Adornment.End" AdornmentText="fps"/>
|
||||||
|
</MudElement>
|
||||||
</MudItem>
|
</MudItem>
|
||||||
<MudItem>
|
<MudItem>
|
||||||
<MudText Typo="Typo.h6">Audio</MudText>
|
<MudText Typo="Typo.h6">Audio</MudText>
|
||||||
@@ -80,13 +83,7 @@
|
|||||||
</MudItem>
|
</MudItem>
|
||||||
<MudItem>
|
<MudItem>
|
||||||
<MudText Typo="Typo.h6">Normalization</MudText>
|
<MudText Typo="Typo.h6">Normalization</MudText>
|
||||||
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Resolution" @bind-Checked="@_model.NormalizeResolution" For="@(() => _model.NormalizeResolution)"/>
|
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Video" @bind-Checked="@_model.NormalizeVideo" For="@(() => _model.NormalizeVideo)"/>
|
||||||
<MudElement HtmlTag="div" Class="mt-3">
|
|
||||||
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Video Codec" @bind-Checked="@_model.NormalizeVideoCodec" For="@(() => _model.NormalizeVideoCodec)"/>
|
|
||||||
</MudElement>
|
|
||||||
<MudElement HtmlTag="div" Class="mt-3">
|
|
||||||
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Audio Codec" @bind-Checked="@_model.NormalizeAudioCodec" For="@(() => _model.NormalizeAudioCodec)"/>
|
|
||||||
</MudElement>
|
|
||||||
<MudElement HtmlTag="div" Class="mt-3">
|
<MudElement HtmlTag="div" Class="mt-3">
|
||||||
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Audio" @bind-Checked="@_model.NormalizeAudio" For="@(() => _model.NormalizeAudio)"/>
|
<MudCheckBox Disabled="@(!_model.Transcode)" Label="Normalize Audio" @bind-Checked="@_model.NormalizeAudio" For="@(() => _model.NormalizeAudio)"/>
|
||||||
</MudElement>
|
</MudElement>
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ namespace ErsatzTV.ViewModels
|
|||||||
Id = viewModel.Id;
|
Id = viewModel.Id;
|
||||||
Name = viewModel.Name;
|
Name = viewModel.Name;
|
||||||
NormalizeAudio = viewModel.NormalizeAudio;
|
NormalizeAudio = viewModel.NormalizeAudio;
|
||||||
NormalizeAudioCodec = viewModel.NormalizeAudioCodec;
|
NormalizeVideo = viewModel.NormalizeVideo;
|
||||||
NormalizeResolution = viewModel.NormalizeResolution;
|
|
||||||
NormalizeVideoCodec = viewModel.NormalizeVideoCodec;
|
|
||||||
Resolution = viewModel.Resolution;
|
Resolution = viewModel.Resolution;
|
||||||
ThreadCount = viewModel.ThreadCount;
|
ThreadCount = viewModel.ThreadCount;
|
||||||
Transcode = viewModel.Transcode;
|
Transcode = viewModel.Transcode;
|
||||||
@@ -32,6 +30,7 @@ namespace ErsatzTV.ViewModels
|
|||||||
VideoBitrate = viewModel.VideoBitrate;
|
VideoBitrate = viewModel.VideoBitrate;
|
||||||
VideoBufferSize = viewModel.VideoBufferSize;
|
VideoBufferSize = viewModel.VideoBufferSize;
|
||||||
VideoCodec = viewModel.VideoCodec;
|
VideoCodec = viewModel.VideoCodec;
|
||||||
|
FrameRate = viewModel.FrameRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int AudioBitrate { get; set; }
|
public int AudioBitrate { get; set; }
|
||||||
@@ -43,9 +42,7 @@ namespace ErsatzTV.ViewModels
|
|||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool NormalizeAudio { get; set; }
|
public bool NormalizeAudio { get; set; }
|
||||||
public bool NormalizeAudioCodec { get; set; }
|
public bool NormalizeVideo { get; set; }
|
||||||
public bool NormalizeResolution { get; set; }
|
|
||||||
public bool NormalizeVideoCodec { get; set; }
|
|
||||||
public ResolutionViewModel Resolution { get; set; }
|
public ResolutionViewModel Resolution { get; set; }
|
||||||
public int ThreadCount { get; set; }
|
public int ThreadCount { get; set; }
|
||||||
public bool Transcode { get; set; }
|
public bool Transcode { get; set; }
|
||||||
@@ -53,6 +50,7 @@ namespace ErsatzTV.ViewModels
|
|||||||
public int VideoBitrate { get; set; }
|
public int VideoBitrate { get; set; }
|
||||||
public int VideoBufferSize { get; set; }
|
public int VideoBufferSize { get; set; }
|
||||||
public string VideoCodec { get; set; }
|
public string VideoCodec { get; set; }
|
||||||
|
public string FrameRate { get; set; }
|
||||||
|
|
||||||
public CreateFFmpegProfile ToCreate() =>
|
public CreateFFmpegProfile ToCreate() =>
|
||||||
new(
|
new(
|
||||||
@@ -61,19 +59,18 @@ namespace ErsatzTV.ViewModels
|
|||||||
Transcode,
|
Transcode,
|
||||||
HardwareAcceleration,
|
HardwareAcceleration,
|
||||||
Resolution.Id,
|
Resolution.Id,
|
||||||
NormalizeResolution,
|
NormalizeVideo,
|
||||||
VideoCodec,
|
VideoCodec,
|
||||||
NormalizeVideoCodec,
|
|
||||||
VideoBitrate,
|
VideoBitrate,
|
||||||
VideoBufferSize,
|
VideoBufferSize,
|
||||||
AudioCodec,
|
AudioCodec,
|
||||||
NormalizeAudioCodec,
|
|
||||||
AudioBitrate,
|
AudioBitrate,
|
||||||
AudioBufferSize,
|
AudioBufferSize,
|
||||||
AudioVolume,
|
AudioVolume,
|
||||||
AudioChannels,
|
AudioChannels,
|
||||||
AudioSampleRate,
|
AudioSampleRate,
|
||||||
NormalizeAudio
|
NormalizeAudio,
|
||||||
|
FrameRate
|
||||||
);
|
);
|
||||||
|
|
||||||
public UpdateFFmpegProfile ToUpdate() =>
|
public UpdateFFmpegProfile ToUpdate() =>
|
||||||
@@ -84,19 +81,18 @@ namespace ErsatzTV.ViewModels
|
|||||||
Transcode,
|
Transcode,
|
||||||
HardwareAcceleration,
|
HardwareAcceleration,
|
||||||
Resolution.Id,
|
Resolution.Id,
|
||||||
NormalizeResolution,
|
NormalizeVideo,
|
||||||
VideoCodec,
|
VideoCodec,
|
||||||
NormalizeVideoCodec,
|
|
||||||
VideoBitrate,
|
VideoBitrate,
|
||||||
VideoBufferSize,
|
VideoBufferSize,
|
||||||
AudioCodec,
|
AudioCodec,
|
||||||
NormalizeAudioCodec,
|
|
||||||
AudioBitrate,
|
AudioBitrate,
|
||||||
AudioBufferSize,
|
AudioBufferSize,
|
||||||
AudioVolume,
|
AudioVolume,
|
||||||
AudioChannels,
|
AudioChannels,
|
||||||
AudioSampleRate,
|
AudioSampleRate,
|
||||||
NormalizeAudio
|
NormalizeAudio,
|
||||||
|
FrameRate
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user