Итак, я пытаюсь записать аудио с микрофона и воспроизвести его на динамике в режиме реального времени, используя библиотеку Taudio для записи с MIC и использования библиотеки Just_audio для воспроизведения звука. Теперь все отлично работает на Flutter Web, но когда я пытаюсь запустить и тестировать его на моем устройстве Android, он записывает только на второе или меньше, и приложение резко закрывается. Ниже мой полный код: < /p>
/*
* Copyright 2018, 2019, 2020, 2021 Dooboolab.
*
* This file is part of Flutter-Sound.
*
* Flutter-Sound is free software: you can redistribute it and/or modify
* it under the terms of the Mozilla Public License version 2 (MPL2.0),
* as published by the Mozilla organization.
*
* Flutter-Sound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MPL General Public License for more details.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import 'dart:async';
import 'package:flutter/foundation.dart' show kIsWeb, Uint8List;
import 'package:flutter/material.dart';
import 'package:taudio/taudio.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:audio_session/audio_session.dart';
/*
This is a very simple example for Flutter Sound beginners,
hat shows how to record, and then playback a file.
This example is really basic.
*/
void main() {
runApp(const MaterialApp(
home: PlayFromMic(),
));
}
typedef _Fn = void Function();
const theSource = AudioSource.microphone;
// Example app.
class PlayFromMic extends StatefulWidget {
const PlayFromMic({super.key});
@override
State
createState() => _PlayFromMic();
}
class _PlayFromMic extends State {
/// Our player
final FlutterSoundPlayer _mPlayer = FlutterSoundPlayer();
/// Our recorder
final FlutterSoundRecorder _mRecorder = FlutterSoundRecorder();
var recordingDataControllerUint8 = StreamController();
Future init() async {
final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration(
avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
avAudioSessionCategoryOptions:
AVAudioSessionCategoryOptions.allowBluetooth |
AVAudioSessionCategoryOptions.defaultToSpeaker,
avAudioSessionMode: AVAudioSessionMode.spokenAudio,
avAudioSessionRouteSharingPolicy:
AVAudioSessionRouteSharingPolicy.defaultPolicy,
avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
androidAudioAttributes: const AndroidAudioAttributes(
contentType: AndroidAudioContentType.speech,
flags: AndroidAudioFlags.none,
usage: AndroidAudioUsage.voiceCommunication,
),
androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
androidWillPauseWhenDucked: true,
));
_mPlayer.openPlayer().then((value) {
setState(() {
_mPlayerIsInited = true;
});
});
openTheRecorder().then((value) {
setState(() {
_mRecorderIsInited = true;
});
});
}
@override
void initState() {
super.initState();
init();
}
@override
void dispose() {
_mPlayer.closePlayer();
_mRecorder.closeRecorder();
super.dispose();
}
// ------------------------------ This is the recorder stuff -----------------------------
static const Codec _codec = Codec.pcm16;
static const int _sampleRate = 48000;
bool _mRecorderIsInited = false;
double _dbLevel = 0.0;
StreamSubscription? _recorderSubscription;
bool bNoiseSuppression = false;
bool bEchoCancellation = false;
/// Request permission to record something and open the recorder
Future openTheRecorder() async {
if (!kIsWeb) {
var status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
throw RecordingPermissionException('Microphone permission not granted');
}
}
await _mRecorder.openRecorder();
/*_recorderSubscription = */ _mRecorder.onProgress!.listen((e) {
// pos = e.duration.inMilliseconds; // We do not need this information in this example.
setState(() {
_dbLevel = e.decibels as double;
});
});
await _mRecorder.setSubscriptionDuration(
const Duration(milliseconds: 100)); // DO NOT FORGET THIS CALL !!!
_mRecorderIsInited = true;
}
/// Begin to record.
/// This is our main function.
/// We ask Flutter Sound to record to a File.
void record() async {
try {
assert(_mPlayerIsInited && _mRecorder.isStopped && _mPlayer.isStopped);
await _mPlayer.startPlayerFromStream(
codec: _codec,
sampleRate: _sampleRate,
interleaved: true,
bufferSize: 1024,
numChannels: 2,
);
await _mRecorder.startRecorder(
codec: _codec,
audioSource: theSource,
//toStreamFloat32: _mPlayer.float32Sink,
toStream: recordingDataControllerUint8,
sampleRate: _sampleRate,
numChannels: 2,
enableNoiseSuppression: bNoiseSuppression,
enableEchoCancellation: bEchoCancellation,
);
recordingDataControllerUint8.stream.listen((Uint8List buf) {
//In actual production usage, Uint8List buf will be provided by websocket for _player.feedUint8FromStream(buf); on receiver end
_mPlayer.feedUint8FromStream(buf);
//print("===========$buf");
},
onError: (error) {
print('Recorder error: $error');
},
onDone: () {
print('Recorder stopped');
},);
setState(() {});
} catch (e) {
print('AAAAAAAAAAAAAAAAAAA----------Error starting recorder: $e -----------------BBBBBBBBBBBBBBBBBB------');
}
}
/// Stop the recorder
void stopRecorder() async {
await _mPlayer.stopPlayer();
await _mRecorder.stopRecorder().then((value) {
setState(() {
//var url = value;
});
});
}
// ----------------------------- This is the player stuff ---------------------------------
bool _mPlayerIsInited = false;
/// Begin to play the recorded sound
void play() {}
/// Stop the player
void stopPlayer() {
_mPlayer.stopPlayer().then((value) {
setState(() {});
});
}
// ----------------------------- UI --------------------------------------------
// The user changed its selection. Reset the 3 buffers
Future reinit() async {
await _mPlayer.stopPlayer();
await _mRecorder.stopRecorder();
setState(() {});
}
_Fn? getRecorderFn() {
if (!_mRecorderIsInited || !_mPlayerIsInited) {
return null;
}
return _mRecorder.isStopped ? record : stopRecorder;
}
@override
Widget build(BuildContext context) {
Widget makeBody() {
return Column(
children: [
Container(
margin: const EdgeInsets.all(3),
padding: const EdgeInsets.all(3),
height: 200,
width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0xFFFAF0E6),
border: Border.all(
color: Colors.indigo,
width: 3,
),
),
child: Column(children: [
Row(children: [
ElevatedButton(
onPressed: getRecorderFn(),
//color: Colors.white,
//disabledColor: Colors.grey,
child: Text(_mRecorder.isRecording ? 'Stop' : 'Record'),
),
const SizedBox(
width: 20,
),
Text(_mRecorder.isRecording
? 'Recording in progress'
: 'Recorder is stopped'),
]),
const SizedBox(
height: 20,
),
_mRecorder.isRecording
? LinearProgressIndicator(
value: _dbLevel / 100,
valueColor:
const AlwaysStoppedAnimation(Colors.indigo),
backgroundColor: Colors.limeAccent)
: Container(),
CheckboxListTile(
tileColor: const Color(0xFFFAF0E6),
title: const Text("Noise Suppression"),
value: bNoiseSuppression,
onChanged: (newValue) {
reinit();
setState(() {
bNoiseSuppression = newValue!;
});
},
),
CheckboxListTile(
tileColor: const Color(0xFFFAF0E6),
title: const Text("Echo Cancellation"),
value: bEchoCancellation,
onChanged: (newValue) {
reinit();
setState(() {
bEchoCancellation = newValue!;
});
},
),
]),
),
],
);
}
return Scaffold(
backgroundColor: Colors.blue,
appBar: AppBar(
title: const Text('Play from Mic'),
),
body: makeBody(),
);
}
}
< /code>
Вот что я знаю о проблеме до сих пор, когда я пытаюсь отлаживать: < /p>
Когда я уменьшаю размер буфера от 1024 на нечто менее, похожее на 200 или 500, он все еще разбивается. /> < /ol>
Примечание, мое действие в 1 и 2 было сделано, чтобы уменьшить следум _mplayer.feeduint8fromStream (buf);
, приложение не сбоя, и я могу наблюдать аудио, записанный в uint8list, когда я регистрирую его с помощью print ("=========== $ buf"); . В этот момент я пришел к выводу, что библиотека Flutter Taudio все в порядке, и приложение довольно сбоило из -за того, как я реализовал воспроизведение в прямом эфире с использованием библиотеки just_audio < /li>
< /ol>
Любой толчок в правильном направлении поможет. Заранее большое спасибо.
Итак, я пытаюсь записать аудио с микрофона и воспроизвести его на динамике в режиме реального времени, используя библиотеку Taudio для записи с MIC и использования библиотеки Just_audio для воспроизведения звука. Теперь все отлично работает на Flutter Web, но когда я пытаюсь запустить и тестировать его на моем устройстве Android, он записывает только на второе или меньше, и приложение резко закрывается. Ниже мой полный код: < /p> [code]/* * Copyright 2018, 2019, 2020, 2021 Dooboolab. * * This file is part of Flutter-Sound. * * Flutter-Sound is free software: you can redistribute it and/or modify * it under the terms of the Mozilla Public License version 2 (MPL2.0), * as published by the Mozilla organization. * * Flutter-Sound is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MPL General Public License for more details. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/// Request permission to record something and open the recorder Future openTheRecorder() async { if (!kIsWeb) { var status = await Permission.microphone.request(); if (status != PermissionStatus.granted) { throw RecordingPermissionException('Microphone permission not granted'); } } await _mRecorder.openRecorder();
/*_recorderSubscription = */ _mRecorder.onProgress!.listen((e) { // pos = e.duration.inMilliseconds; // We do not need this information in this example. setState(() { _dbLevel = e.decibels as double; }); }); await _mRecorder.setSubscriptionDuration( const Duration(milliseconds: 100)); // DO NOT FORGET THIS CALL !!!
_mRecorderIsInited = true; }
/// Begin to record. /// This is our main function. /// We ask Flutter Sound to record to a File. void record() async { try { assert(_mPlayerIsInited && _mRecorder.isStopped && _mPlayer.isStopped);
//In actual production usage, Uint8List buf will be provided by websocket for _player.feedUint8FromStream(buf); on receiver end _mPlayer.feedUint8FromStream(buf); //print("===========$buf");
return Scaffold( backgroundColor: Colors.blue, appBar: AppBar( title: const Text('Play from Mic'), ), body: makeBody(), ); } } < /code> Вот что я знаю о проблеме до сих пор, когда я пытаюсь отлаживать: < /p>
Когда я уменьшаю размер буфера от 1024 на нечто менее, похожее на 200 или 500, он все еще разбивается. /> < /ol> Примечание, мое действие в 1 и 2 было сделано, чтобы уменьшить следум _mplayer.feeduint8fromStream (buf); [/code], приложение не сбоя, и я могу наблюдать аудио, записанный в uint8list, когда я регистрирую его с помощью print ("=========== $ buf"); . В этот момент я пришел к выводу, что библиотека Flutter Taudio все в порядке, и приложение довольно сбоило из -за того, как я реализовал воспроизведение в прямом эфире с использованием библиотеки just_audio < /li> < /ol> Любой толчок в правильном направлении поможет. Заранее большое спасибо.
Итак, я пытаюсь записать аудио с микрофона и воспроизвести его на динамике в режиме реального времени, используя библиотеку Taudio для записи с MIC и использования библиотеки Taudio для воспроизведения звука. Теперь все отлично работает на Flutter...
В нашем проекте для записи входного аудио используется приведенный ниже код:
let request = SFSpeechAudioBufferRecognitionRequest()
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, when in
request.append(buffer)...
В нашем проекте для записи входного аудио используется приведенный ниже код:
let request = SFSpeechAudioBufferRecognitionRequest()
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, when in
request.append(buffer)...
В нашем проекте для записи входного аудио используется приведенный ниже код:
let request = SFSpeechAudioBufferRecognitionRequest()
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, when in
request.append(buffer)...
Я пытаюсь записывать звук только из динамика только с использованием TypeScript или JavaScript.
ожидается: это записывает звук из динамика, не микрофон. /> let audioChunks: any = [];
navigator.mediaDevices.getUserMedia({ audio: true })...