diff --git a/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java b/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java index 1533e8d..6d2ded5 100644 --- a/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java +++ b/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java @@ -67,6 +67,15 @@ public void onMethodCall(MethodCall call, MethodChannel.Result response) { mute(muted); response.success(null); break; + case "getVolume": + int volume = getVolume(); + response.success(volume); + break; + case "setVolume": + int volumeToSet = call.arguments(); + setVolume(volumeToSet); + response.success(null); + break; default: response.notImplemented(); } @@ -80,6 +89,28 @@ private void mute(Boolean muted) { } } + private int getVolume() { +/* + //TODO: Replace volume getter with this logic to normalize to 0 to 100 + int maxVolume = getStreamMaxVolume(AudioManager.STREAM_MUSIC); + int minVolume = getStreamMinVolume(AudioManager.STREAM_MUSIC); + int volume = (am.getStreamVolume(AudioManager.STREAM_MUSIC) - minVolume) * 100 / (maxVolume - minVolume); +*/ + int volume = am.getStreamVolume(AudioManager.STREAM_MUSIC); + return volume; + } + + private void setVolume(int volume) { +/* + //TODO: Replace volume setter with this logic to normalize to 0 to 100 + int maxVolume = getStreamMaxVolume(AudioManager.STREAM_MUSIC); + int minVolume = getStreamMinVolume(AudioManager.STREAM_MUSIC); + int index = volume * (maxVolume - minVolume) / 100 + minVolume; +*/ + int index = volume; + am.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0); + } + private void seek(double position) { mediaPlayer.seekTo((int) (position * 1000)); } diff --git a/example/lib/main.dart b/example/lib/main.dart index d1c78bf..d1b2d44 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -26,6 +26,7 @@ class AudioApp extends StatefulWidget { class _AudioAppState extends State { Duration duration; Duration position; + int _volume; AudioPlayer audioPlayer; @@ -62,6 +63,7 @@ class _AudioAppState extends State { void initAudioPlayer() { audioPlayer = new AudioPlayer(); + audioPlayer.setVolume(10); _positionSubscription = audioPlayer.onAudioPositionChanged.listen( (p) => setState(() => position = p) ); @@ -88,6 +90,11 @@ class _AudioAppState extends State { setState(() { playerState = PlayerState.playing; }); + audioPlayer.getVolume().then((volume) { + setState(() { + _volume = volume; + }); + }); } Future _playLocal() async { @@ -206,19 +213,6 @@ class _AudioAppState extends State { audioPlayer.seek((value / 1000).roundToDouble()), min: 0.0, max: duration.inMilliseconds.toDouble()), - new Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - new IconButton( - onPressed: () => mute(true), - icon: new Icon(Icons.headset_off), - color: Colors.cyan), - new IconButton( - onPressed: () => mute(false), - icon: new Icon(Icons.headset), - color: Colors.cyan), - ], - ), new Row(mainAxisSize: MainAxisSize.min, children: [ new Padding( padding: new EdgeInsets.all(12.0), @@ -229,7 +223,7 @@ class _AudioAppState extends State { new CircularProgressIndicator( value: position != null && position.inMilliseconds > 0 ? (position?.inMilliseconds?.toDouble() ?? 0.0) / - (duration?.inMilliseconds?.toDouble() ?? 0.0) + (duration?.inMilliseconds?.toDouble() ?? 0.0) : 0.0, valueColor: new AlwaysStoppedAnimation(Colors.cyan), backgroundColor: Colors.yellow, @@ -240,6 +234,38 @@ class _AudioAppState extends State { ? "${positionText ?? ''} / ${durationText ?? ''}" : duration != null ? durationText : '', style: new TextStyle(fontSize: 24.0)) - ]) + ]), + new Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + new IconButton( + onPressed: () => mute(true), + icon: new Icon(Icons.headset_off), + color: Colors.cyan), + new IconButton( + onPressed: () => mute(false), + icon: new Icon(Icons.headset), + color: Colors.cyan), + ], + ), + new Row ( + children: [ + new Icon(Icons.volume_down), + new Expanded(child: + new Slider( + min: 0.0, + max: 100.0, + value: _volume?.toDouble() ?? 50.0, + onChanged: (double newValue) { + setState(() { + _volume = newValue.toInt(); + }); + audioPlayer.setVolume(_volume); + }, + ), + ), + new Icon(Icons.volume_up), + ], + ), ])); } diff --git a/ios/Classes/AudioplayerPlugin.m b/ios/Classes/AudioplayerPlugin.m index 062076a..715f463 100644 --- a/ios/Classes/AudioplayerPlugin.m +++ b/ios/Classes/AudioplayerPlugin.m @@ -12,6 +12,8 @@ @interface AudioplayerPlugin() -(void)pause; -(void)stop; -(void)mute:(BOOL)muted; +-(NSNumber *)getVolume; +-(void)setVolume:(int)volume; -(void)seek:(CMTime)time; -(void)onStart; -(void)onTimeInterval:(CMTime)time; @@ -61,6 +63,16 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self mute:[call.arguments boolValue]]; result(nil); }, + @"getVolume": + ^{ + NSNumber *volumeRef = [self getVolume]; + result(volumeRef); + }, + @"setVolume": + ^{ + [self setVolume:[call.arguments intValue]]; + result(nil); + }, @"seek": ^{ [self seek:CMTimeMakeWithSeconds([call.arguments doubleValue], 1)]; @@ -159,6 +171,16 @@ - (void)mute:(bool)muted { player.muted = muted; } +- (NSNumber *)getVolume { + int volume = (int)roundf(player.volume * 100.0); + NSNumber *volumeRef = [NSNumber numberWithInt:volume]; + return volumeRef; +} + +- (void)setVolume:(int)volume { + player.volume = (float)volume / 100.0; +} + - (void)seek:(CMTime)time { [playerItem seekToTime:time]; } diff --git a/lib/audioplayer.dart b/lib/audioplayer.dart index c254b96..fc0a76b 100644 --- a/lib/audioplayer.dart +++ b/lib/audioplayer.dart @@ -55,6 +55,12 @@ class AudioPlayer { /// Mute sound. Future mute(bool muted) async => await _channel.invokeMethod('mute', muted); + /// Get playing volume. Normalized integer range of 0 to 100. + Future getVolume() async => await _channel.invokeMethod('getVolume'); + + /// Set playing volume. Normalized integer range of 0 to 100. + Future setVolume(int volume) async => await _channel.invokeMethod('setVolume', volume); + /// Seek to a specific position in the audio stream. Future seek(double seconds) async => await _channel.invokeMethod('seek', seconds);