device_volume 0.1.0 copy "device_volume: ^0.1.0" to clipboard
device_volume: ^0.1.0 copied to clipboard

Control the device volume from Flutter. Provides getVolume, setVolume, incrementVolume, decrementVolume and streamVolume with synchronous and compute-based async variants. Uses JNIgen on Android and F [...]

device_volume #

pub.dev CI

Control the device volume from Flutter. Provides read, write, increment, decrement and a live stream — with both synchronous and compute-based async variants.

Platform support #

Platform Read Write Stream Notes
Android Per-channel (media, ring, alarm…) via AudioManager
iOS Write via MPVolumeView; simulator shows correct value but write is ignored by the OS
macOS CoreAudio + AudioToolbox (VirtualMainVolume)
Windows IAudioEndpointVolume (WASAPI)
Linux PulseAudio / PipeWire

Installation #

dependencies:
  device_volume: ^0.1.0

Quick start #

import 'package:device_volume/device_volume.dart';

// Read current volume
final state = DeviceVolume.getVolume();
print('${state.value} / ${state.max}  (${(state.normalized * 100).round()}%)');

// Set volume
DeviceVolume.setVolume(50);

// Increment / decrement
DeviceVolume.incrementVolume(showSystemUi: true);
DeviceVolume.decrementVolume(showSystemUi: true);

// Mute (set to minimum)
DeviceVolume.setVolume(state.min);

// Observe changes
DeviceVolume.streamVolume().listen((s) {
  print('Volume changed: ${s.value}');
});

API reference #

DeviceVolume #

All methods are static. Every synchronous method has an async *Compute counterpart that runs on a background isolate via flutter/foundation.dart compute().

Synchronous

// Returns the current volume state.
VolumeState getVolume({ VolumeChannel channel = VolumeChannel.media })

// Sets volume to [value] (absolute, in platform units: min–max).
VolumeState setVolume(int value, { VolumeChannel channel, bool showSystemUi })

// Increases by one platform step (5 units on most platforms).
VolumeState incrementVolume({ VolumeChannel channel, bool showSystemUi })

// Decreases by one platform step.
VolumeState decrementVolume({ VolumeChannel channel, bool showSystemUi })

Async (background isolate)

Future<VolumeState> getVolumeCompute({ VolumeChannel channel })
Future<VolumeState> setVolumeCompute(int value, { VolumeChannel channel, bool showSystemUi })
Future<VolumeState> incrementVolumeCompute({ VolumeChannel channel, bool showSystemUi })
Future<VolumeState> decrementVolumeCompute({ VolumeChannel channel, bool showSystemUi })

Stream

// Emits the current state immediately, then on every change.
Stream<VolumeState> streamVolume({ VolumeChannel channel })

VolumeState #

Immutable snapshot returned by all API methods.

Property Type Description
value int Current absolute volume level
min int Minimum level reported by the platform
max int Maximum level reported by the platform
normalized double value mapped to [0.0, 1.0]
isMuted bool Whether the stream is muted
channel VolumeChannel The channel this state refers to

VolumeChannel #

Represents the audio stream to control. Not all channels are supported on every platform — unsupported channels throw UnsupportedOperationException.

Value Description
media Music, video, games (default)
ring Ringtone
alarm Alarm
notification Notification sounds
voiceCall In-call voice
system System UI sounds

Android only supports per-channel control. On iOS/macOS/Windows/Linux there is a single output volume; passing any channel reads/writes that same volume.

Error handling #

All errors extend DeviceVolumeException. Catch the base class or a specific subclass:

try {
  DeviceVolume.setVolume(80);
} on UnsupportedOperationException catch (e) {
  // Operation not available on this platform
} on InvalidVolumeValueException catch (e) {
  // Value out of range (below min or above max)
} on PermissionDeniedException catch (e) {
  // OS denied the request
} on BackendNotAvailableException catch (e) {
  // No audio backend found (e.g. headless Linux without PulseAudio)
} on NativeBackendException catch (e) {
  // Unexpected native error
} on DeviceVolumeException catch (e) {
  // Catch-all
  print(e.code);     // stable machine-readable code
  print(e.message);  // human-readable description
  print(e.details);  // structured diagnostic data
}
Exception Code When
UnsupportedOperationException unsupported_operation Operation not available on this platform
InvalidVolumeValueException invalid_volume_value Value outside min–max range
PermissionDeniedException permission_denied OS denied the request
BackendNotAvailableException backend_not_available No audio backend present
NativeBackendException native_backend_failure Unexpected native error
VolumeObservationException volume_observation_failure Stream setup failed

Platform-specific notes #

iOS #

Write operations use MPVolumeView (MediaPlayer framework) placed off-screen. This is the standard App Store-compliant workaround — AVAudioSession.outputVolume is read-only by design.

On the simulator the hardware volume stack is not emulated, so reads return a fixed value and writes are silently discarded by the OS. Test write operations on a real device.

Android #

Requires no additional permissions for media, alarm, notification, and system streams. Modifying the ring stream may require android.permission.ACCESS_NOTIFICATION_POLICY on Android 6+ if Do Not Disturb is active.

Linux #

Requires PulseAudio or a PipeWire PulseAudio compatibility layer (pipewire-pulse). On headless systems without a running audio server, all calls throw BackendNotAvailableException.

Windows #

Uses WASAPI (IAudioEndpointVolume). Controls the default output device. COM is initialized automatically per call. For example, see sum in lib/device_volume.dart.

Longer-running functions should be invoked on a helper isolate to avoid dropping frames in Flutter applications. For example, see sumAsync in lib/device_volume.dart.

Flutter help #

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

1
likes
150
points
28
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Control the device volume from Flutter. Provides getVolume, setVolume, incrementVolume, decrementVolume and streamVolume with synchronous and compute-based async variants. Uses JNIgen on Android and FFI + FFIgen on iOS, macOS, Linux and Windows.

Repository (GitHub)
View/report issues

Topics

#volume #audio #ffi #platform

License

MIT (license)

Dependencies

flutter, jni, plugin_platform_interface

More

Packages that depend on device_volume

Packages that implement device_volume