-
Notifications
You must be signed in to change notification settings - Fork 669
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
168 additions
and
288 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Additional information about this file can be found at | ||
# https://dart.dev/guides/language/analysis-options | ||
|
||
include: package:flutter_lints/flutter.yaml | ||
|
||
analyzer: | ||
exclude: [build/**] | ||
language: | ||
strict-casts: true | ||
strict-inference: true | ||
strict-raw-types: false | ||
|
||
linter: | ||
rules: | ||
cancel_subscriptions: true | ||
constant_identifier_names: false | ||
depend_on_referenced_packages: false | ||
avoid_print: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,3 @@ | ||
# audio_streamer_example | ||
# Audio Streamer Example | ||
|
||
Demonstrates how to use the audio_streamer plugin. | ||
|
||
## Getting Started | ||
|
||
This project is a starting point for a Flutter application. | ||
|
||
A few resources to get you started if this is your first Flutter project: | ||
|
||
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) | ||
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) | ||
|
||
For help getting started with Flutter, view our | ||
[online documentation](https://flutter.dev/docs), which offers tutorials, | ||
samples, guidance on mobile development, and a full API reference. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,102 @@ | ||
import 'dart:math'; | ||
import 'dart:async'; | ||
|
||
import 'package:flutter/material.dart'; | ||
import 'package:audio_streamer/audio_streamer.dart'; | ||
import 'dart:math'; | ||
import 'package:permission_handler/permission_handler.dart'; | ||
|
||
import 'package:flutter/services.dart'; | ||
void main() => runApp(new AudioStreamingApp()); | ||
|
||
void main() { | ||
runApp(new MyApp()); | ||
} | ||
|
||
class MyApp extends StatefulWidget { | ||
class AudioStreamingApp extends StatefulWidget { | ||
@override | ||
_MyAppState createState() => new _MyAppState(); | ||
AudioStreamingAppState createState() => new AudioStreamingAppState(); | ||
} | ||
|
||
class _MyAppState extends State<MyApp> { | ||
// Note that AudioStreamer works as a singleton. | ||
AudioStreamer streamer = AudioStreamer(); | ||
class AudioStreamingAppState extends State<AudioStreamingApp> { | ||
int? sampleRate; | ||
bool isRecording = false; | ||
List<double> audio = []; | ||
List<double>? latestBuffer; | ||
double? recordingTime; | ||
StreamSubscription<List<double>>? audioSubscription; | ||
|
||
bool _isRecording = false; | ||
List<double> _audio = []; | ||
/// Check if microphone permission is granted. | ||
Future<bool> checkPermission() async => await Permission.microphone.isGranted; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
} | ||
/// Request the microphone permission. | ||
Future<void> requestPermission() async => | ||
await Permission.microphone.request(); | ||
|
||
/// Call-back on audio sample. | ||
void onAudio(List<double> buffer) async { | ||
_audio.addAll(buffer); | ||
var sampleRate = await streamer.actualSampleRate; | ||
double secondsRecorded = _audio.length.toDouble() / sampleRate; | ||
print('Max amp: ${buffer.reduce(max)}'); | ||
print('Min amp: ${buffer.reduce(min)}'); | ||
print('$secondsRecorded seconds recorded.'); | ||
print('-' * 50); | ||
audio.addAll(buffer); | ||
|
||
// Get the actual sampling rate, if not already known. | ||
sampleRate ??= await AudioStreamer().actualSampleRate; | ||
recordingTime = audio.length / sampleRate!; | ||
|
||
setState(() => latestBuffer = buffer); | ||
} | ||
|
||
void handleError(PlatformException error) { | ||
setState(() { | ||
_isRecording = false; | ||
}); | ||
print(error.message); | ||
print(error.details); | ||
/// Call-back on error. | ||
void handleError(Object error) { | ||
setState(() => isRecording = false); | ||
print(error); | ||
} | ||
|
||
/// Start audio sampling. | ||
void start() async { | ||
try { | ||
// Start streaming using default sample rate of 44100 Hz | ||
streamer.start(onAudio, handleError); | ||
|
||
setState(() { | ||
_isRecording = true; | ||
}); | ||
} catch (error) { | ||
print(error); | ||
// Check permission to use the microphone. | ||
// | ||
// Remember to update the AndroidManifest file (Android) and the | ||
// Info.plist and pod files (iOS). | ||
if (!(await checkPermission())) { | ||
await requestPermission(); | ||
} | ||
|
||
// Set the sampling rate - works only on Android. | ||
AudioStreamer().sampleRate = 22100; | ||
|
||
// Start listening to the audio stream. | ||
audioSubscription = | ||
AudioStreamer().audioStream.listen(onAudio, onError: handleError); | ||
|
||
setState(() => isRecording = true); | ||
} | ||
|
||
/// Stop audio sampling. | ||
void stop() async { | ||
bool stopped = await streamer.stop(); | ||
setState(() { | ||
_isRecording = stopped; | ||
}); | ||
audioSubscription?.cancel(); | ||
setState(() => isRecording = false); | ||
} | ||
|
||
List<Widget> getContent() => <Widget>[ | ||
Container( | ||
margin: EdgeInsets.all(25), | ||
child: Column(children: [ | ||
Container( | ||
child: Text(_isRecording ? "Mic: ON" : "Mic: OFF", | ||
style: TextStyle(fontSize: 25, color: Colors.blue)), | ||
margin: EdgeInsets.only(top: 20), | ||
) | ||
])), | ||
]; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return MaterialApp( | ||
home: Scaffold( | ||
body: Center( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: getContent())), | ||
floatingActionButton: FloatingActionButton( | ||
backgroundColor: _isRecording ? Colors.red : Colors.green, | ||
onPressed: _isRecording ? stop : start, | ||
child: _isRecording ? Icon(Icons.stop) : Icon(Icons.mic)), | ||
), | ||
); | ||
} | ||
Widget build(BuildContext context) => MaterialApp( | ||
home: Scaffold( | ||
body: Center( | ||
child: Column( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: <Widget>[ | ||
Container( | ||
margin: EdgeInsets.all(25), | ||
child: Column(children: [ | ||
Container( | ||
child: Text(isRecording ? "Mic: ON" : "Mic: OFF", | ||
style: TextStyle(fontSize: 25, color: Colors.blue)), | ||
margin: EdgeInsets.only(top: 20), | ||
), | ||
Text(''), | ||
Text('Max amp: ${latestBuffer?.reduce(max)}'), | ||
Text('Min amp: ${latestBuffer?.reduce(min)}'), | ||
Text( | ||
'${recordingTime?.toStringAsFixed(2)} seconds recorded.'), | ||
])), | ||
])), | ||
floatingActionButton: FloatingActionButton( | ||
backgroundColor: isRecording ? Colors.red : Colors.green, | ||
child: isRecording ? Icon(Icons.stop) : Icon(Icons.mic), | ||
onPressed: isRecording ? stop : start, | ||
), | ||
), | ||
); | ||
} |
Oops, something went wrong.