From bd6cbe766cd7a9ff4f758a5b7943ec143c6aa6f0 Mon Sep 17 00:00:00 2001 From: David Klingenberg Date: Sat, 24 Mar 2018 09:46:47 +0100 Subject: [PATCH 1/5] Add volume control --- .../java/bz/rxla/audioplayer/AudioplayerPlugin.java | 11 ++++++++++- example/lib/main.dart | 2 ++ lib/audioplayer.dart | 2 ++ pubspec.yaml | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java b/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java index d6ec502..d1d195f 100644 --- a/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java +++ b/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java @@ -64,11 +64,20 @@ public void onMethodCall(MethodCall call, MethodChannel.Result response) { Boolean muted = call.arguments(); mute(muted); response.success(1); + } else if (call.method.equals("setVolume")) { + int volume = call.arguments(); + setVolume(volume); } else { response.notImplemented(); } } - + + private void setVolume(int volume) { + if (AudioplayerPlugin.am == null) return; + + AudioplayerPlugin.am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0); +} + private void mute(Boolean muted) { if(AudioplayerPlugin.am == null) return; if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { diff --git a/example/lib/main.dart b/example/lib/main.dart index 69ed367..b51e477 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -52,6 +52,8 @@ class _AudioAppState extends State { void initAudioPlayer() { audioPlayer = new AudioPlayer(); + audioPlayer.setVolume(10); + audioPlayer.setDurationHandler((d) => setState(() { duration = d; })); diff --git a/lib/audioplayer.dart b/lib/audioplayer.dart index ef9fc08..05e2384 100644 --- a/lib/audioplayer.dart +++ b/lib/audioplayer.dart @@ -33,6 +33,8 @@ class AudioPlayer { Future mute(bool muted) => channel.invokeMethod('mute', muted); + Future setVolume(int volume) => channel.invokeMethod('setVolume', volume); + Future seek(double seconds) => channel.invokeMethod('seek', seconds); void setDurationHandler(TimeChangeHandler handler) { diff --git a/pubspec.yaml b/pubspec.yaml index ee33283..129bc59 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: audioplayer description: A flutter plugin to play audio files -version: 0.4.0 +version: 0.5.0 author: Erick Ghaumez homepage: https://github.com/rxlabz/audioplayer From 4ad4627cb785894183f688231b49218332143a43 Mon Sep 17 00:00:00 2001 From: Joel Faul Date: Fri, 15 Jun 2018 11:27:09 -0700 Subject: [PATCH 2/5] Add getVolume() method to Android --- .../rxla/audioplayer/AudioplayerPlugin.java | 26 ++++++++++++++++--- lib/audioplayer.dart | 5 +++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java b/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java index d14cbd9..0d1f71d 100644 --- a/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java +++ b/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java @@ -67,9 +67,13 @@ 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 volume = call.arguments(); - setVolume(volume); + int volumeToSet = call.arguments(); + setVolume(volumeToSet); response.success(null); break; default: @@ -85,8 +89,24 @@ private void mute(Boolean muted) { } } + private int getVolume() { +/* + 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) { - am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0); +/* + 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) { diff --git a/lib/audioplayer.dart b/lib/audioplayer.dart index 4108861..b206c10 100644 --- a/lib/audioplayer.dart +++ b/lib/audioplayer.dart @@ -55,7 +55,10 @@ class AudioPlayer { /// Mute sound. Future mute(bool muted) async => await _channel.invokeMethod('mute', muted); - /// Set playing volume. + /// Set 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. From a0b49b074e64a7755d979ab66dc48ee0ce88c6a4 Mon Sep 17 00:00:00 2001 From: Joel Faul Date: Fri, 15 Jun 2018 11:55:42 -0700 Subject: [PATCH 3/5] Add volume control to sample app --- example/lib/main.dart | 23 +++++++++++++++++++++++ lib/audioplayer.dart | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 91e78bb..2117511 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; @@ -50,6 +51,9 @@ class _AudioAppState extends State { void initState() { super.initState(); initAudioPlayer(); + audioPlayer.getVolume().then((volume) { + _volume = volume; + }); } @override @@ -220,6 +224,25 @@ class _AudioAppState extends State { 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), + ], + ), new Row(mainAxisSize: MainAxisSize.min, children: [ new Padding( padding: new EdgeInsets.all(12.0), diff --git a/lib/audioplayer.dart b/lib/audioplayer.dart index b206c10..fc0a76b 100644 --- a/lib/audioplayer.dart +++ b/lib/audioplayer.dart @@ -55,7 +55,7 @@ class AudioPlayer { /// Mute sound. Future mute(bool muted) async => await _channel.invokeMethod('mute', muted); - /// Set playing volume. Normalized integer range of 0 to 100. + /// 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. From 7ca1f59e71ab187eacc092f42fc99185754bfc53 Mon Sep 17 00:00:00 2001 From: Joel Faul Date: Fri, 15 Jun 2018 12:00:46 -0700 Subject: [PATCH 4/5] Reordered elements on demo app to group volume influencing items (volume and mute) and to group playback position items (seek slider and circle progress indicator) --- example/lib/main.dart | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 2117511..8bb73f7 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -211,6 +211,28 @@ class _AudioAppState extends State { audioPlayer.seek((value / 1000).roundToDouble()), min: 0.0, max: duration.inMilliseconds.toDouble()), + new Row(mainAxisSize: MainAxisSize.min, children: [ + new Padding( + padding: new EdgeInsets.all(12.0), + child: new Stack(children: [ + new CircularProgressIndicator( + value: 1.0, + valueColor: new AlwaysStoppedAnimation(Colors.grey[300])), + new CircularProgressIndicator( + value: position != null && position.inMilliseconds > 0 + ? (position?.inMilliseconds?.toDouble() ?? 0.0) / + (duration?.inMilliseconds?.toDouble() ?? 0.0) + : 0.0, + valueColor: new AlwaysStoppedAnimation(Colors.cyan), + backgroundColor: Colors.yellow, + ), + ])), + new Text( + position != null + ? "${positionText ?? ''} / ${durationText ?? ''}" + : duration != null ? durationText : '', + style: new TextStyle(fontSize: 24.0)) + ]), new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -243,27 +265,5 @@ class _AudioAppState extends State { new Icon(Icons.volume_up), ], ), - new Row(mainAxisSize: MainAxisSize.min, children: [ - new Padding( - padding: new EdgeInsets.all(12.0), - child: new Stack(children: [ - new CircularProgressIndicator( - value: 1.0, - valueColor: new AlwaysStoppedAnimation(Colors.grey[300])), - new CircularProgressIndicator( - value: position != null && position.inMilliseconds > 0 - ? (position?.inMilliseconds?.toDouble() ?? 0.0) / - (duration?.inMilliseconds?.toDouble() ?? 0.0) - : 0.0, - valueColor: new AlwaysStoppedAnimation(Colors.cyan), - backgroundColor: Colors.yellow, - ), - ])), - new Text( - position != null - ? "${positionText ?? ''} / ${durationText ?? ''}" - : duration != null ? durationText : '', - style: new TextStyle(fontSize: 24.0)) - ]) ])); } From 0270298c77ed31ceac4e1464fd182fed35aa73f3 Mon Sep 17 00:00:00 2001 From: Joel Faul Date: Fri, 15 Jun 2018 13:53:45 -0700 Subject: [PATCH 5/5] Added iOS support for setVolume and getVolume --- .../rxla/audioplayer/AudioplayerPlugin.java | 2 ++ example/lib/main.dart | 8 ++++--- ios/Classes/AudioplayerPlugin.m | 22 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java b/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java index 0d1f71d..6d2ded5 100644 --- a/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java +++ b/android/src/main/java/bz/rxla/audioplayer/AudioplayerPlugin.java @@ -91,6 +91,7 @@ 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); @@ -101,6 +102,7 @@ private int getVolume() { 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; diff --git a/example/lib/main.dart b/example/lib/main.dart index 8bb73f7..d1b2d44 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -51,9 +51,6 @@ class _AudioAppState extends State { void initState() { super.initState(); initAudioPlayer(); - audioPlayer.getVolume().then((volume) { - _volume = volume; - }); } @override @@ -93,6 +90,11 @@ class _AudioAppState extends State { setState(() { playerState = PlayerState.playing; }); + audioPlayer.getVolume().then((volume) { + setState(() { + _volume = volume; + }); + }); } Future _playLocal() async { 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]; }