我正在为那些听不清声音的人制作一个助听器应用程序,想法是麦克风让用户可以改变其频率,使用滑块或其他东西调整其他设置,然后扬声器使用经过处理的设置播放音频,我面临的问题是先录制音频然后播放,我如何让它直接从麦克风到扬声器播放音频,扬声器可以是手机/耳机。
我希望与麦克风一起播放音频。
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:permission_handler/permission_handler.dart';
class VoiceChanger extends StatefulWidget {
@override
_VoiceChangerState createState() => _VoiceChangerState();
}
class _VoiceChangerState extends State<VoiceChanger> {
late final StreamController<Uint8List> _audioStreamController;
FlutterSoundRecorder? _recorder;
FlutterSoundPlayer? _player;
bool isRecording = false;
bool isPlayingBack = false;
@override
void initState() {
super.initState();
_recorder = FlutterSoundRecorder();
_player = FlutterSoundPlayer();
_audioStreamController = StreamController<Uint8List>();
initAudio();
}
Future<void> initAudio() async {
await _recorder!.openRecorder();
await _player!.openPlayer();
await _player!.setVolume(1.0);
}
Future<void> startRecording() async {
if (await Permission.microphone.request().isGranted) {
// Start recording to a stream
await _recorder!.startRecorder(
toStream: _audioStreamController.sink,
codec: Codec.pcm16,
);
// Listen to the stream and play audio data in real-time
_audioStreamController.stream.listen((data) async {
// Ensure playback continues smoothly
if (!isPlayingBack) {
isPlayingBack = true;
await _player!.startPlayer(
fromDataBuffer: data,
codec: Codec.pcm16,
whenFinished: () {
isPlayingBack = false; // Set playing flag to false when finished
},
);
} else {
// Feed the new audio data to the player without interruption
await _player!.feedFromStream(data);
}
});
setState(() {
isRecording = true;
});
} else {
print("Microphone permission is not granted");
}
}
Future<void> stopRecording() async {
await _recorder!.stopRecorder();
setState(() {
isRecording = false;
isPlayingBack = false; // Stop playback
});
}
@override
void dispose() {
_recorder?.closeRecorder();
_player?.closePlayer();
_audioStreamController.close(); // Ensure stream is closed
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Voice Changer'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: isRecording ? stopRecording : startRecording,
child: Text(isRecording ? 'Stop Recording' : 'Start Recording'),
),
],
),
),
);
}
}
要实现录音时实时音频播放,请考虑以下方法:
Future<void> startRecording() async {
// ...
_audioStreamController.stream.listen((data) async {
if (_player!.isPlaying) {
await _player!.feedFromStream(data);
} else {
await _player!.startPlayer(
fromDataBuffer: data,
codec: Codec.pcm16,
);
}
});
// ...
}