From ef27a0f16f16305e527409e8bf5ac25066cb813e Mon Sep 17 00:00:00 2001 From: Hai Vo Date: Wed, 5 Aug 2026 11:55:14 +0700 Subject: [PATCH] docs: sync README/llms.txt/GitHub Pages docs with ProbeResult and Cut changes README.md, llms.txt, llms-full.txt, and the four GitHub Pages doc pages (API-Reference, Advanced-Features, Getting-Started, index) still documented the old ProbeResult shape (DurationInSeconds/BitsPerSample/ BitRate/SampleRate/Height/Width/Result) and claimed AudioCutter.Cut requires matching source/destination extensions -- both no longer true after the recent ProbeResult redesign and Cut generalization. Update all of them to the current API: the flat ProbeResult with FormatName/ CodecName/DurationSeconds/etc., and Cut's any-source-to-any-dest behavior. Also note WavReader/WavWriter's new 8-bit/32-bit-float PCM support in the API reference. --- README.md | 2 +- docs/API-Reference.html | 28 ++++++++++++++++++------- docs/Advanced-Features.html | 4 ++-- docs/Getting-Started.html | 30 +++++++++++++++++--------- docs/index.html | 4 ++-- llms-full.txt | 42 +++++++++++++++++++++++++------------ llms.txt | 4 ++-- 7 files changed, 77 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 686a78a..9f5cc08 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ var probeResult = await encoder.Probe("track.flac"); | WMA | ✅ | ✅ | ❌ | | MOV/MP4 (metadata only) | ✅ | ❌ | ❌ | -`IMediaEncoder.CutFile` supports WAV, FLAC, MP3, and AAC — sample-accurate, no re-encode of the untouched region. +`IMediaEncoder.CutFile` decodes any supported source (WAV, FLAC, MP3, AAC, WMA) and can cut into any supported destination format, including converting as it trims — sample-accurate, no re-encode of the untouched region. ## License diff --git a/docs/API-Reference.html b/docs/API-Reference.html index 62462c5..07d5dff 100644 --- a/docs/API-Reference.html +++ b/docs/API-Reference.html @@ -52,15 +52,26 @@

IMediaEncoder

}

ProbeResult

+

Only fields this library can genuinely compute are populated — no ffprobe-style placeholders (e.g. no probe_score, no disposition flags).

public class ProbeResult
 {
-    public int DurationInSeconds { get; set; }
-    public int? BitsPerSample { get; set; }
-    public int? BitRate { get; set; }
-    public int? SampleRate { get; set; }
-    public int? Height { get; set; }
-    public int? Width { get; set; }
-    public string? Result { get; set; }
+    public string FormatName { get; init; }        // e.g. "wav", "flac", "mp3", "aac", "asf", "mov", "mp4"
+    public string FormatLongName { get; init; }     // e.g. "WAV / WAVE (Waveform Audio)"
+    public long SizeBytes { get; init; }
+    public double DurationSeconds { get; init; }
+    public string CodecType { get; init; }          // "audio" or "video"
+    public string? CodecName { get; init; }         // e.g. "pcm_s16le", "flac", "mp3", "aac", "wmav2"
+    public string? CodecLongName { get; init; }
+    public int? SampleRate { get; init; }
+    public int? Channels { get; init; }
+    public string? ChannelLayout { get; init; }     // "mono", "stereo", or "{n} channels"
+    public int? BitsPerSample { get; init; }
+    public int? BitRate { get; init; }
+    public bool? IsVariableBitRate { get; init; }   // MP3 only
+    public long? DurationInSamples { get; init; }
+    public string? TimeBase { get; init; }          // e.g. "1/44100"
+    public int? Width { get; init; }                // set for video containers (MOV/MP4), null for audio
+    public int? Height { get; init; }
     public string? WaveformResult { get; set; }
 }
@@ -86,6 +97,7 @@

AudioCutter

public static void Convert(string sourceFilePath, string destFilePath); public static bool Cut(string sourceFilePath, string destFilePath, int startInSeconds, int endInSeconds); } +

Cut decodes any supported source (.wav, .flac, .mp3, .aac, .wma) and writes any supported destination extension — source and destination don't need to match, so it can transcode while it trims. Returns false (and writes no file) if the requested range is entirely outside the source's duration.

WaveformCalculator

Namespace: EggEncoder.Waveform.

@@ -148,6 +160,7 @@

WAV — EggEncoder.Codecs.Wav

public int SampleRate { get; } public int BitsPerSample { get; } public long TotalSamples { get; } + public bool IsFloatFormat { get; } public int ReadInterleavedSamples(int[] buffer, int maxSamplesPerChannel); } @@ -156,6 +169,7 @@

WAV — EggEncoder.Codecs.Wav

public static WavWriter Create(string destFilePath, int channels, int sampleRate, int bitsPerSample, long totalFrames); public void WriteInterleavedSamples(int[] buffer, int frameCount); } +

Supports 8-bit unsigned, 16/24/32-bit signed integer, and (read-only) 32-bit IEEE float PCM.

WMA — EggEncoder.Codecs.Wma

public static class WmaDecoder
diff --git a/docs/Advanced-Features.html b/docs/Advanced-Features.html
index 5946fc7..c4eb947 100644
--- a/docs/Advanced-Features.html
+++ b/docs/Advanced-Features.html
@@ -58,12 +58,12 @@ 

Waveform Generation

WaveformCalculator streams — call AddBlock as many times as you like across however many decode callbacks the codec produces; it does not need the full signal in memory at once.

Sample-Accurate Cutting

-

NativeEncoder.CutFile (backed by AudioCutter.Cut) trims WAV, FLAC, MP3, and AAC files without re-encoding the untouched region where the format allows frame-boundary slicing:

+

NativeEncoder.CutFile (backed by AudioCutter.Cut) decodes any supported source (WAV, FLAC, MP3, AAC, WMA) and writes any supported destination format (WAV, FLAC, MP3, AAC) without re-encoding the untouched region where the format allows frame-boundary slicing:

using EggEncoder.Codecs;
 
 bool produced = AudioCutter.Cut(sourcePath, destPath, startInSeconds: 30, endInSeconds: 90);
 // false means the requested range was entirely outside the source's duration — no file was written
-

Cut requires the source and destination extensions to match — it trims in place, it does not transcode. Use AudioCutter.Convert (or NativeEncoder.ConvertFile) for format conversion.

+

Source and destination extensions no longer need to match — Cut can transcode while it trims (e.g. cut a WAV directly to MP3). Use AudioCutter.Convert (or NativeEncoder.ConvertFile) when you just need format conversion with no trimming.

MOV/MP4 Probing

MovProbe walks the ISO base media container's atom tree directly — no native dependency — to read duration, dimensions, and the video codec's four-character code:

diff --git a/docs/Getting-Started.html b/docs/Getting-Started.html index 91a5991..29e0c8c 100644 --- a/docs/Getting-Started.html +++ b/docs/Getting-Started.html @@ -80,20 +80,30 @@

Without DI

IMediaEncoder encoder = new NativeEncoder(NullLogger<NativeEncoder>.Instance); var probeResult = await encoder.Probe("track.flac"); -Console.WriteLine($"{probeResult.SampleRate}Hz, {probeResult.DurationInSeconds}s");
+Console.WriteLine($"{probeResult.SampleRate}Hz, {probeResult.DurationSeconds}s");

Reading a ProbeResult

-

Probe always returns the same ProbeResult shape:

+

Probe always returns the same ProbeResult shape. Only fields this library can genuinely compute are populated:

public class ProbeResult
 {
-    public int DurationInSeconds { get; set; }
-    public int? BitsPerSample { get; set; }
-    public int? BitRate { get; set; }
-    public int? SampleRate { get; set; }
-    public int? Height { get; set; }   // set for video containers (MOV/MP4), null for audio
-    public int? Width { get; set; }
-    public string? Result { get; set; }          // raw JSON detail from the probing engine
-    public string? WaveformResult { get; set; }   // JSON array of normalized peak windows, or null
+    public string FormatName { get; init; }        // e.g. "wav", "flac", "mp3", "aac", "asf", "mov", "mp4"
+    public string FormatLongName { get; init; }     // e.g. "WAV / WAVE (Waveform Audio)"
+    public long SizeBytes { get; init; }
+    public double DurationSeconds { get; init; }
+    public string CodecType { get; init; }          // "audio" or "video"
+    public string? CodecName { get; init; }         // e.g. "pcm_s16le", "flac", "mp3", "aac", "wmav2"
+    public string? CodecLongName { get; init; }
+    public int? SampleRate { get; init; }
+    public int? Channels { get; init; }
+    public string? ChannelLayout { get; init; }     // "mono", "stereo", or "{n} channels"
+    public int? BitsPerSample { get; init; }
+    public int? BitRate { get; init; }
+    public bool? IsVariableBitRate { get; init; }   // MP3 only
+    public long? DurationInSamples { get; init; }
+    public string? TimeBase { get; init; }          // e.g. "1/44100"
+    public int? Width { get; init; }                // set for video containers (MOV/MP4), null for audio
+    public int? Height { get; init; }
+    public string? WaveformResult { get; set; }     // JSON array of normalized peak windows, or null
 }

See Advanced Features for waveform generation and sample-accurate cutting details, or the API Reference for the full type list.

diff --git a/docs/index.html b/docs/index.html index 98067d8..9d7e129 100644 --- a/docs/index.html +++ b/docs/index.html @@ -75,7 +75,7 @@

Fully Native

External processNone SetupNothing — DLLs ship in the package Format coverageAAC, FLAC, MP3, WAV, WMA; MOV/MP4 metadata - Sample-accurate cutWAV, FLAC, MP3, AAC — no re-encode of the untouched region + Sample-accurate cutAny source (incl. WMA) to any dest format — no re-encode of the untouched region @@ -112,7 +112,7 @@

Key Features

Sample-Accurate Cutting
-

Trim WAV/FLAC/MP3/AAC without a full decode→encode round trip.

+

Trim any supported source, into any supported destination format, without a full decode→encode round trip on the untouched region.

🔍
diff --git a/llms-full.txt b/llms-full.txt index 6c493d3..4fcef59 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -30,17 +30,29 @@ public interface IMediaEncoder ```csharp public class ProbeResult { - public int DurationInSeconds { get; set; } - public int? BitsPerSample { get; set; } - public int? BitRate { get; set; } - public int? SampleRate { get; set; } - public int? Height { get; set; } // set for video containers (MOV/MP4), null for audio - public int? Width { get; set; } - public string? Result { get; set; } // raw JSON detail from the probing engine - public string? WaveformResult { get; set; } // JSON array of normalized peak windows in [0,1], or null + public string FormatName { get; init; } // e.g. "wav", "flac", "mp3", "aac", "asf", "mov", "mp4" + public string FormatLongName { get; init; } // e.g. "WAV / WAVE (Waveform Audio)" + public long SizeBytes { get; init; } + public double DurationSeconds { get; init; } + public string CodecType { get; init; } // "audio" or "video" + public string? CodecName { get; init; } // e.g. "pcm_s16le", "flac", "mp3", "aac", "wmav2" + public string? CodecLongName { get; init; } + public int? SampleRate { get; init; } + public int? Channels { get; init; } + public string? ChannelLayout { get; init; } // "mono", "stereo", or "{n} channels" + public int? BitsPerSample { get; init; } + public int? BitRate { get; init; } + public bool? IsVariableBitRate { get; init; } // MP3 only + public long? DurationInSamples { get; init; } + public string? TimeBase { get; init; } // e.g. "1/44100" + public int? Width { get; init; } // set for video containers (MOV/MP4), null for audio + public int? Height { get; init; } + public string? WaveformResult { get; set; } // JSON array of normalized peak windows in [0,1], or null } ``` +Only fields this library can genuinely compute are populated -- nothing is filled with ffprobe-style placeholders (e.g. no `probe_score`, no disposition flags). + ## Dependency Injection ```csharp @@ -96,7 +108,7 @@ public class TranscodeWorker(IServiceProvider serviceProvider) | WMA | yes | yes | no | | MOV/MP4 (metadata only) | yes | no | no | -`AudioCutter.Cut` (used by `NativeEncoder.CutFile`) supports WAV, FLAC, MP3, and AAC — sample-accurate, no re-encode of the untouched region. `WmaDecoder` is decode-only and mono-only: real-world WMAv2 stereo encoders (including ffmpeg's) default to mid/side stereo coding, which is unsupported and throws `NotSupportedException`. +`AudioCutter.Cut` (used by `NativeEncoder.CutFile`) decodes any supported source format (WAV, FLAC, MP3, AAC, WMA) and writes to any supported destination format, including WAV, FLAC, MP3, or AAC — it can transcode while trimming; source and destination extensions no longer need to match. Sample-accurate, no re-encode of the untouched region. `WmaDecoder` is decode-only and mono-only: real-world WMAv2 stereo encoders (including ffmpeg's) default to mid/side stereo coding, which is unsupported and throws `NotSupportedException`. ## Codec Reference @@ -169,14 +181,17 @@ public sealed class WavReader : IDisposable public int SampleRate { get; } public int BitsPerSample { get; } public long TotalSamples { get; } + public bool IsFloatFormat { get; } public int ReadInterleavedSamples(int[] buffer, int maxSamplesPerChannel); - // throws NotSupportedException for unsupported bit depths + // 8-bit unsigned, 16/24/32-bit signed, and 32-bit IEEE float PCM are supported; + // throws NotSupportedException for anything else } public sealed class WavWriter : IAudioSink, IDisposable { public static WavWriter Create(string destFilePath, int channels, int sampleRate, int bitsPerSample, long totalFrames); public void WriteInterleavedSamples(int[] buffer, int frameCount); + // writes 8-bit unsigned or 16/24/32-bit signed integer PCM } ``` @@ -224,9 +239,10 @@ public static class AudioCutter // dispatches by extension: .wav/.flac/.mp3/.aac/.wma source -> any supported dest extension public static bool Cut(string sourceFilePath, string destFilePath, int startInSeconds, int endInSeconds); - // requires source and dest extensions to match (trims, does not transcode) + // decodes any supported source (.wav/.flac/.mp3/.aac/.wma) and writes any supported dest + // extension (.wav/.flac/.mp3/.aac) -- source and dest extensions no longer need to match, + // so Cut can transcode while it trims // returns false (and writes no file) if the requested range is entirely outside the source duration - // supports .wav, .flac, .mp3, .aac } ``` @@ -267,7 +283,7 @@ Every codec's `Decode` method streams blocks through the same `AudioBlockDecoded - **Windows x64 only.** `NativeEncoder` and its codec bindings P/Invoke into bundled `win-x64` binaries. There is no cross-platform build or fallback engine — this library does not run on Linux/macOS/ARM. - **WMA is decode-only and mono-only.** Genuine stereo WMA files (mid/side coded, the real-world default) throw `NotSupportedException` by design rather than decoding incorrectly. -- **`AudioCutter.Cut` requires matching extensions.** It trims, it does not transcode; mismatched source/dest extensions throw `NotSupportedException`. Use `Convert` (or `ConvertFile`) to change format. +- **`AudioCutter.Cut` can transcode while it trims.** Source and destination extensions no longer need to match -- it decodes any supported source and writes any supported destination format. - **AAC encoding is mono-only** and restricted to a fixed set of MPEG-4 sample rates (see `AacTables.SampleRates`); other combinations throw `NotSupportedException`. ## License diff --git a/llms.txt b/llms.txt index 2064596..41f1907 100644 --- a/llms.txt +++ b/llms.txt @@ -55,7 +55,7 @@ var probeResult = await encoder.Probe("track.flac"); - `IMediaEncoder` — the abstraction (`Probe`, `ConvertFile`, `CutFile`) - `NativeEncoder` — the sole implementation, Windows x64 only (P/Invoke to libmp3lame/libFLAC) -- `ProbeResult` — duration, sample rate, bit depth, bitrate, dimensions (for video), waveform JSON +- `ProbeResult` — format name/long name, file size, duration, codec name/long name, sample rate, channels, channel layout, bit depth, bitrate, dimensions (for video), waveform JSON - `AudioCutter` — format-dispatching convert/cut, used internally by `NativeEncoder` - `WaveformCalculator` — streams decoded blocks into normalized peak windows @@ -67,7 +67,7 @@ WAV, FLAC, MP3, AAC, WMA (decode-only, mono-only); MOV/MP4 metadata probing via - Native codec binaries are Windows x64 only — there is no cross-platform fallback - `WmaDecoder` does not support mid/side stereo coding (the default for most real-world WMAv2 encoders) — throws `NotSupportedException` for genuine stereo files -- `AudioCutter.Cut` requires matching source/destination extensions (trims, does not transcode) — use `Convert` for format changes +- `AudioCutter.Cut` decodes any supported source and can write any supported destination format — it can transcode while trimming, source and destination extensions no longer need to match ## Links