feat(ads/seo/release): v1.2.0 with live Google Ads, isolated ad profile, ads.txt, and SEO/AEO/GEO optimization
This commit is contained in:
parent
a88aafa1e5
commit
0e568f1f0a
975 changed files with 130593 additions and 16783 deletions
55
src/Paca.Core/AudioDynamicRangeCompressor.cs
Normal file
55
src/Paca.Core/AudioDynamicRangeCompressor.cs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Paca.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Predefined dynamic range compression presets for dialogue clarity and evening listening.
|
||||
/// </summary>
|
||||
public enum CompressorPreset
|
||||
{
|
||||
None,
|
||||
NightListening,
|
||||
PodcastSpeech,
|
||||
BroadcastStandard
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intelligent audio dynamic range compression (DRC) and peak limiter filter generator.
|
||||
/// Balances quiet speech and loud sound effects (gunfire, explosions) for clear, non-fatiguing audio.
|
||||
/// </summary>
|
||||
public static class AudioDynamicRangeCompressor
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds the ffmpeg acompressor and alimiter filter chain for the given preset.
|
||||
/// </summary>
|
||||
public static string BuildFilter(CompressorPreset preset)
|
||||
{
|
||||
return preset switch
|
||||
{
|
||||
CompressorPreset.NightListening => "acompressor=threshold=-24dB:ratio=6:attack=5:release=100:makeup=6dB,alimiter=limit=-1dB",
|
||||
CompressorPreset.PodcastSpeech => "acompressor=threshold=-20dB:ratio=4:attack=10:release=150:makeup=4dB,alimiter=limit=-1dB",
|
||||
CompressorPreset.BroadcastStandard => "acompressor=threshold=-18dB:ratio=8:attack=2:release=80:makeup=8dB,alimiter=limit=0dB",
|
||||
_ => "anull"
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds custom compressor filter chain with granular acoustic parameters.
|
||||
/// </summary>
|
||||
public static string BuildCustomFilter(double thresholdDb, double ratio, double attackMs, double releaseMs, double makeupDb, double limitPeakDb)
|
||||
{
|
||||
var inv = CultureInfo.InvariantCulture;
|
||||
return $"acompressor=threshold={thresholdDb.ToString("0.##", inv)}dB:ratio={ratio.ToString("0.##", inv)}:attack={attackMs.ToString("0.##", inv)}:release={releaseMs.ToString("0.##", inv)}:makeup={makeupDb.ToString("0.##", inv)}dB,alimiter=limit={limitPeakDb.ToString("0.##", inv)}dB";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds full ffmpeg command line arguments for applying DRC to video or audio files.
|
||||
/// </summary>
|
||||
public static string BuildFfmpegArgs(string inputPath, string outputPath, CompressorPreset preset, bool copyVideo = true, int audioBitrateKbps = 192)
|
||||
{
|
||||
string vCodec = copyVideo ? "-c:v copy" : "-c:v libx264 -crf 20 -preset fast";
|
||||
var filter = BuildFilter(preset);
|
||||
return $"-hide_banner -y -i \"{inputPath}\" {vCodec} -af \"{filter}\" -c:a aac -b:a {audioBitrateKbps}k \"{outputPath}\"";
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue