Skip to content
This repository was archived by the owner on Feb 26, 2021. It is now read-only.

Commit c8ff0f5

Browse files
committed
feat: flutter volume dart volume API
1 parent fa60e2a commit c8ff0f5

File tree

1 file changed

+185
-1
lines changed

1 file changed

+185
-1
lines changed

lib/flutter_volume.dart

Lines changed: 185 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,197 @@
1+
//MIT License
2+
//
3+
//Copyright (c) [2019] [Befovy]
4+
//
5+
//Permission is hereby granted, free of charge, to any person obtaining a copy
6+
//of this software and associated documentation files (the "Software"), to deal
7+
//in the Software without restriction, including without limitation the rights
8+
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
//copies of the Software, and to permit persons to whom the Software is
10+
//furnished to do so, subject to the following conditions:
11+
//
12+
//The above copyright notice and this permission notice shall be included in all
13+
//copies or substantial portions of the Software.
14+
//
15+
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
//SOFTWARE.
22+
123
import 'dart:async';
224

325
import 'package:flutter/services.dart';
26+
import 'package:flutter/widgets.dart';
27+
28+
@immutable
29+
class VolumeVal {
30+
final double vol;
31+
final int type;
32+
33+
VolumeVal({
34+
@required this.vol,
35+
@required this.type,
36+
}) : assert(vol != null),
37+
assert(type != null);
38+
39+
@override
40+
bool operator ==(Object other) =>
41+
identical(this, other) ||
42+
(other is VolumeVal && hashCode == other.hashCode);
43+
44+
@override
45+
int get hashCode => hashValues(vol, type);
46+
}
47+
48+
class _VolumeValueNotifier extends ValueNotifier<VolumeVal> {
49+
_VolumeValueNotifier(VolumeVal value) : super(value);
50+
}
51+
52+
typedef VolumeCallback = void Function(VolumeVal value);
453

554
class FlutterVolume {
55+
static const int STREAM_VOICE_CALL = 0;
56+
static const int STREAM_SYSTEM = 1;
57+
static const int STREAM_RING = 2;
58+
static const int STREAM_MUSIC = 3;
59+
static const int STREAM_ALARM = 4;
60+
61+
static const double _step = 1.0 / 16.0;
662
static const MethodChannel _channel =
7-
const MethodChannel('flutter_volume');
63+
const MethodChannel('com.befovy.flutter_volume');
64+
65+
static _VolumeValueNotifier _notifier =
66+
_VolumeValueNotifier(VolumeVal(vol: 0, type: 0));
67+
68+
static StreamSubscription _eventSubs;
869

970
static Future<String> get platformVersion async {
1071
final String version = await _channel.invokeMethod('getPlatformVersion');
1172
return version;
1273
}
74+
75+
void enableWatcher() {
76+
if (_eventSubs == null) {
77+
_eventSubs = EventChannel('com.befovy.flutter_volume/event')
78+
.receiveBroadcastStream()
79+
.listen(_eventListener, onError: _errorListener);
80+
_channel.invokeMethod("enable_watch");
81+
}
82+
}
83+
84+
void disableWatcher() {
85+
_channel.invokeMethod("disable_watch");
86+
_eventSubs?.cancel();
87+
_eventSubs = null;
88+
}
89+
90+
static void _eventListener(dynamic event) {
91+
final Map<dynamic, dynamic> map = event;
92+
switch (map['event']) {
93+
case 'vol':
94+
double vol = map['v'];
95+
int type = map['t'];
96+
_notifier.value = VolumeVal(vol: vol, type: type);
97+
break;
98+
default:
99+
break;
100+
}
101+
}
102+
103+
static void _errorListener(Object obj) {
104+
print("errorListener: $obj");
105+
}
106+
107+
static Future<double> up({
108+
double step = _step,
109+
int type = STREAM_MUSIC,
110+
}) {
111+
return _channel.invokeMethod("up", <String, dynamic>{
112+
'step': step,
113+
'type': type,
114+
});
115+
}
116+
117+
static Future<double> down({
118+
double step = _step,
119+
int type = STREAM_MUSIC,
120+
}) {
121+
return _channel.invokeMethod("down", <String, dynamic>{
122+
'step': step,
123+
'type': type,
124+
});
125+
}
126+
127+
static Future<double> mute({
128+
int type = STREAM_MUSIC,
129+
}) {
130+
return _channel.invokeMethod("mute", <String, dynamic>{
131+
'type': type,
132+
});
133+
}
134+
135+
static Future<double> get({
136+
int type = STREAM_MUSIC,
137+
}) {
138+
return _channel.invokeMethod("get", <String, dynamic>{
139+
'type': type,
140+
});
141+
}
142+
143+
static Future<double> set(double vol, {int type = STREAM_MUSIC}) {
144+
return _channel.invokeMethod("set", <String, dynamic>{
145+
'vol': vol,
146+
'type': type,
147+
});
148+
}
149+
150+
static void addVolListener(VoidCallback listener) {
151+
_notifier.addListener(listener);
152+
}
153+
154+
static void removeVolListener(VoidCallback listener) {
155+
_notifier.removeListener(listener);
156+
}
157+
158+
static VolumeVal get value => _notifier.value;
159+
}
160+
161+
class VolumeWatcher extends StatefulWidget {
162+
final VolumeCallback watcher;
163+
final Widget child;
164+
165+
VolumeWatcher({
166+
@required this.watcher,
167+
@required this.child,
168+
}) : assert(child != null),
169+
assert(watcher != null);
170+
171+
@override
172+
_VolumeWatcherState createState() => _VolumeWatcherState();
173+
}
174+
175+
class _VolumeWatcherState extends State<VolumeWatcher> {
176+
@override
177+
void initState() {
178+
super.initState();
179+
FlutterVolume.addVolListener(_volListener);
180+
}
181+
182+
void _volListener() {
183+
VolumeVal value = FlutterVolume.value;
184+
widget.watcher(value);
185+
}
186+
187+
@override
188+
void dispose() {
189+
super.dispose();
190+
FlutterVolume.removeVolListener(_volListener);
191+
}
192+
193+
@override
194+
Widget build(BuildContext context) {
195+
return widget.child;
196+
}
13197
}

0 commit comments

Comments
 (0)