Skip to content

Commit

Permalink
auto stop voice
Browse files Browse the repository at this point in the history
  • Loading branch information
ankit-apk committed Mar 6, 2024
1 parent 1634771 commit 3fd2d9e
Show file tree
Hide file tree
Showing 3 changed files with 366 additions and 31 deletions.
81 changes: 80 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
//

import 'dart:async';
import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:flutter_voice_processor/flutter_voice_processor.dart';
import 'package:flutter_voice_processor_example/vu_meter_painter.dart';
import 'package:path_provider/path_provider.dart';
import 'package:record/record.dart';

void main() {
runApp(MyApp());
Expand All @@ -37,13 +42,23 @@ class _MyAppState extends State<MyApp> {
bool _isProcessing = false;
String? _errorMessage;
VoiceProcessor? _voiceProcessor;
final record = AudioRecorder();

@override
void initState() {
super.initState();
_initVoiceProcessor();
_initRecorder();
}

@override
void dispose() {
record.dispose();
super.dispose();
}

void _initRecorder() async {}

void _initVoiceProcessor() async {
_voiceProcessor = VoiceProcessor.instance;
}
Expand All @@ -62,6 +77,19 @@ class _MyAppState extends State<MyApp> {
setState(() {
_isProcessing = isRecording!;
});
final directory = await getApplicationDocumentsDirectory();
final path = directory.path;
final file = File('$path/file.wav');
// Start recording with flutter_sound
await record.start(
RecordConfig(
encoder: AudioEncoder.wav,
sampleRate: sampleRate,
bitRate: 96000,
numChannels: 1,
),
path: file.path,
);
} else {
setState(() {
_errorMessage = "Recording permission not granted";
Expand All @@ -85,6 +113,8 @@ class _MyAppState extends State<MyApp> {

try {
await _voiceProcessor?.stop();
// Stop recording with flutter_sound
await record.stop();
} on PlatformException catch (ex) {
setState(() {
_errorMessage = "Failed to stop recorder: " + ex.toString();
Expand Down Expand Up @@ -118,8 +148,12 @@ class _MyAppState extends State<MyApp> {
return normalizedValue.clamp(0.0, 1.0);
}

// Add a timer variable at the class level
Timer? _volumeCheckTimer;

void _onFrame(List<int> frame) {
double volumeLevel = _calculateVolumeLevel(frame);
print(volumeLevel);
if (_volumeHistory.length == volumeHistoryCapacity) {
_volumeHistory.removeAt(0);
}
Expand All @@ -129,6 +163,19 @@ class _MyAppState extends State<MyApp> {
_smoothedVolumeValue =
_volumeHistory.reduce((a, b) => a + b) / _volumeHistory.length;
});

// Check if volume is below the threshold
if (volumeLevel < 0.2) {
// If the timer is not running, start it
_volumeCheckTimer ??= Timer(Duration(seconds: 2), () {
// If the timer completes, stop the recording
_stopProcessing();
});
} else {
// If the volume is above the threshold, cancel the timer
_volumeCheckTimer?.cancel();
_volumeCheckTimer = null;
}
}

void _onError(VoiceProcessorException error) {
Expand All @@ -137,6 +184,29 @@ class _MyAppState extends State<MyApp> {
});
}

Future<void> _playAudio() async {
try {
// Assuming you're saving the file in the app's documents directory
final directory = await getApplicationDocumentsDirectory();
final path = directory.path;
final file = File('$path/file.wav');

if (await file.exists()) {
final _recorder = FlutterSound();
await _recorder.thePlayer.openPlayer();
await _recorder.thePlayer.startPlayer(fromURI: file.path);
} else {
setState(() {
_errorMessage = "No audio file found to play.";
});
}
} on PlatformException catch (ex) {
setState(() {
_errorMessage = "Failed to play audio: " + ex.toString();
});
}
}

Color picoBlue = Color.fromRGBO(55, 125, 255, 1);

@override
Expand All @@ -149,12 +219,21 @@ class _MyAppState extends State<MyApp> {
body: Column(children: [
buildVuMeter(context),
buildStartButton(context),
buildPlayButton(context), // Add this line

buildErrorMessage(context)
]),
),
);
}

buildPlayButton(BuildContext context) {
return ElevatedButton(
onPressed: _isProcessing || _errorMessage != null ? null : _playAudio,
child: Text("Play", style: TextStyle(fontSize: 20)),
);
}

buildVuMeter(BuildContext context) {
return Expanded(
flex: 2,
Expand All @@ -171,7 +250,7 @@ class _MyAppState extends State<MyApp> {

buildStartButton(BuildContext context) {
final ButtonStyle buttonStyle = ElevatedButton.styleFrom(
primary: picoBlue,
backgroundColor: picoBlue,
shape: CircleBorder(),
textStyle: TextStyle(color: Colors.white));

Expand Down
Loading

0 comments on commit 3fd2d9e

Please sign in to comment.