WaveformData class final Visualizer and analysis
Mono min, max and RMS amplitude envelope of the audio currently loaded.
Emitted on PlayerStream.waveform for the loaded track. The track is mixed down to mono and binned into a fixed ~2000-entry envelope. A local file is decoded in the background: partial envelopes (decoding true) come first, then the final one. An HTTP file that plays from its start is decoded the same way from mpv's cache as it downloads. Other network sources grow with playback (unfilled bins in filled), and a live stream is a sliding window of up to 131072 bins.
Bin i spans the time slice
[start + i / bins * duration, start + (i + 1) / bins * duration).
min and max hold the lowest and highest sample value seen in each
bin, range [-1.0, +1.0], and rms the root mean square of the bin.
On loud, heavily limited masters the peaks sit near full scale for most
of the track, so drawing rms as the body of the waveform, with the
peaks as a lighter outline, keeps the sections readable.
For a normal (known-length) track start is zero and duration is the
whole track, so bins map onto [0, duration]. For a live stream
(live == true) there is no total length: the envelope is a sliding
window kept in lockstep with the demuxer's seekable cache, so start is
the absolute media time of bin 0 (the oldest still-cached moment) and
duration is the span currently held (it grows while you listen and
only drops its oldest bins once the demuxer evicts that audio from its
back-buffer). The newest bin is "now". Map bins with start and duration
in absolute media time and you can scrub anywhere the cache still
covers.
Example: paint a bar per bin:
player.stream.waveform.listen((wave) {
if (wave == null) return;
for (var i = 0; i < wave.bins; i++) {
final yMin = wave.min[i] * canvasHeight / 2;
final yMax = wave.max[i] * canvasHeight / 2;
// draw bar i from yMin to yMax …
}
});
Constructors
- WaveformData({required Duration duration, required Float32List min, required Float32List max, required Uint8List filled, Float32List? rms, Duration start = Duration.zero, bool live = false, bool decoding = false, int? coverageBins, int? totalBins})
-
Creates a waveform. Used internally by the waveform pipeline.
const
Properties
- bins → int
-
Number of bins. Convenience accessor: equal to
min.length.no setter - coverageBins → int?
-
Number of bins decoded ("sealed") so far, across all worker regions, or
nullwhen not decoding. Together with totalBins this is the decode progress; see decodeFraction.final - decodeFraction → double?
-
Decode progress in
[0, 1]while decoding, ornullwhen it is not known (not decoding, or the engine did not report bin counts). Drives a determinate progress indicator; anullvalue means show an indeterminate one.no setter - decoding → bool
-
True while the analyzer is still decoding the file: this envelope is a
partial snapshot that grows on every poll until the final one arrives
(a last emission with
decoding == false). Set while a file is decoded apart from playback: a local file, or a remote one read from mpv's cache as it downloads or opened a second time. When a pass from the cache hands over to a second open, the coverage starts again from 0. The bins are safe to draw: filled== 1marks the regions decoded so far (a local file is decoded in several regions in parallel, so coverage is not strictly left-to-right);0bins render as a baseline. Use decodeFraction for a progress indicator. Never set for an envelope that grows from playback, nor together with live.final - duration → Duration
-
Duration the bin axis spans. For a normal track this is the whole
track; for a live window it's the span currently held (see start).
final
- end → Duration
-
Absolute media time at the end of the bin axis (
start + duration).no setter - filled → Uint8List
-
Per-bin coverage flag (one byte per bin, length matches min):
1for a bin that has real data,0for one not yet covered.final - hashCode → int
-
The hash code for this object.
no setterinherited
- live → bool
-
True for a live stream of unknown total length: the envelope is a
sliding window anchored to the demuxer cache rather than a fixed
[0, duration]track axis (see the class docs and start). A renderer places the playhead at the true playback position (it does NOT pin to "now" or auto-follow the newest bin) and allows scrubbing only within[start, start + duration].final - max → Float32List
-
Per-bin maximum sample value, range
[-1.0, +1.0].final - min → Float32List
-
Per-bin minimum sample value, range
[-1.0, +1.0]. Length matches max.final - rms → Float32List?
-
Per-bin RMS of the mono signal, range
[0.0, 1.0], same length as min. It follows the loudness of each bin even where the peaks stay flat at full scale.nullwhen mpv does not report it.final - runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- start → Duration
-
Absolute media time of bin 0. Zero for a normal track; for a live
rolling window it's the oldest still-cached moment, so bins sit at
their true media time and seeks land where they're drawn.
final
- totalBins → int?
-
Total bins on the full axis during a decoding pass (the emitted arrays
hold the full axis, with filled marking the decoded part), or
nullwhen not decoding.final
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited