how to automatically trigger record - flutter

I have a audio recording page which starts when I tap in the button and stop when i tap the button once again
import 'package:flutter_sound/flutter_sound.dart';
import 'package:permission_handler/permission_handler.dart';
class AudioWidget extends StatefulWidget {
#override
State<AudioWidget> createState() => _AudioWidgetState();
}
``class _AudioWidgetState extends State<AudioWidget> {
final FirebaseAuth _auth = FirebaseAuth.instance;
String AudioUrl = '';
final recorder = FlutterSoundRecorder();
bool isRecorderReady = false;
#override
void initState() {
super.initState();
initRecorder();
record();
}
#override
void dispose() {
recorder.closeRecorder();
super.dispose();
}
Future initRecorder() async {
final status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
throw 'Microphone permission not granted';
}
await recorder.openRecorder();
isRecorderReady = true;
recorder.setSubscriptionDuration(const Duration(milliseconds: 500));
}
Future record() async {
if (!isRecorderReady) {
return;
}
await recorder.startRecorder(toFile: 'audio');
}
Future stop() async {
if (!isRecorderReady) {
return;
}
final path = await recorder.stopRecorder();
final audioFile = File(path!);
print('Recorder audio: $audioFile');
final ref = FirebaseStorage.instance
.ref()
.child('Audio')
.child(DateTime.now().toIso8601String() + ".mp3");
await ref.putData(audioFile.readAsBytesSync());
AudioUrl = await ref.getDownloadURL();
FirebaseFirestore.instance.collection('Audio').add({
'AudioUrl': AudioUrl,
'userId': _auth.currentUser!.email,
'createdAt': DateTime.now(),
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Audio"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
StreamBuilder<RecordingDisposition>(
stream: recorder.onProgress,
builder: (context, snapshot) {
final duration = snapshot.hasData
? snapshot.data!.duration
: Duration.zero;
String twoDigits(int n) => n.toString().padLeft(2, '0');
final twoDigitMinutes =
twoDigits(duration.inMinutes.remainder(60));
final twoDigitSeconds =
twoDigits(duration.inSeconds.remainder(60));
if (twoDigitSeconds ==
FFAppState().AudioMaxDuration.toString()) {
stop();
}
return Text('$twoDigitMinutes:$twoDigitSeconds',
style: const TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
));
}),
const SizedBox(height: 32),
ElevatedButton(
child: Icon(
recorder.isRecording ? Icons.stop : Icons.mic,
size: 80,
),
onPressed: () async {
if (recorder.isRecording) {
await stop();
context.pop();
} else {
await record();
}
setState(() {});
},
),
],
)),
),
);
}
}
how can I automatically start recording once I open the audio recording page and tap it to stop and tap again to start?
I tried to put the record function in initstate but it didn't work
void initState() {
super.initState();
initRecorder();
record();
}

Related

Unhandled Exception: type 'Null' is not a subtype of type 'LocationDto'

I am using [background_locator_2][1] plugin, However when I run it with some modification I get this error
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'LocationDto'
This is the code i am using
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ReceivePort port = ReceivePort();
String logStr = '';
bool? isRunning;
LocationDto? lastLocation;
#override
void initState() {
super.initState();
if (IsolateNameServer.lookupPortByName(
LocationServiceRepository.isolateName) !=
null) {
IsolateNameServer.removePortNameMapping(
LocationServiceRepository.isolateName);
}
IsolateNameServer.registerPortWithName(
port.sendPort, LocationServiceRepository.isolateName);
port.listen(
(dynamic data) async {
await updateUI(data);
},
);
initPlatformState();
}
#override
void dispose() {
super.dispose();
}
Future<void> updateUI(LocationDto data) async {
final log = await FileManager.readLogFile();
await _updateNotificationText(data);
setState(() {
lastLocation = data;
logStr = log;
});
}
Future<void> _updateNotificationText(LocationDto data) async {
if (data == null) {
return;
}
await BackgroundLocator.updateNotificationText(
title: "new location received",
msg: "${DateTime.now()}",
bigMsg: "${data.latitude}, ${data.longitude}");
}
Future<void> initPlatformState() async {
print('Initializing...');
await BackgroundLocator.initialize();
logStr = await FileManager.readLogFile();
print('Initialization done');
final _isRunning = await BackgroundLocator.isServiceRunning();
setState(() {
isRunning = _isRunning;
});
print('Running ${isRunning.toString()}');
}
#override
Widget build(BuildContext context) {
final start = SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: Text('Start'),
onPressed: () {
_onStart();
},
),
);
final stop = SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: Text('Stop'),
onPressed: () {
onStop();
},
),
);
final clear = SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: Text('Clear Log'),
onPressed: () {
FileManager.clearLogFile();
setState(() {
logStr = '';
});
},
),
);
String msgStatus = "-";
if (isRunning != null) {
if (isRunning!) {
msgStatus = 'Is running';
} else {
msgStatus = 'Is not running';
}
}
final status = Text("Status: $msgStatus");
final log = Text(
logStr,
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter background Locator'),
),
body: Container(
width: double.maxFinite,
padding: const EdgeInsets.all(22),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[start, stop, clear, status, log],
),
),
),
),
);
}
void onStop() async {
await BackgroundLocator.unRegisterLocationUpdate();
final _isRunning = await BackgroundLocator.isServiceRunning();
setState(() {
isRunning = _isRunning;
});
}
void _onStart() async {
//if (await isLocationAlwaysGranted()) {
await _startLocator();
final _isRunning = await BackgroundLocator.isServiceRunning();
setState(() {
isRunning = _isRunning;
lastLocation = null;
});
// } else {
// show error
}
}
Future<bool> isLocationAlwaysGranted() async =>
await Permission.locationAlways.isGranted;
/// Tries to ask for "location always" permissions from the user.
/// Returns `true` if successful, `false` othervise.
Future<bool> askForLocationAlwaysPermission() async {
bool granted = await Permission.locationAlways.isGranted;
if (!granted) {
granted =
await Permission.locationAlways.request() == PermissionStatus.granted;
}
return granted;
}
Future<void> _startLocator() async {
Map<String, dynamic> data = {'countInit': 1};
return await BackgroundLocator.registerLocationUpdate(
LocationCallbackHandler.callback,
initCallback: LocationCallbackHandler.initCallback,
initDataCallback: data,
disposeCallback: LocationCallbackHandler.disposeCallback,
iosSettings: IOSSettings(
accuracy: LocationAccuracy.NAVIGATION,
distanceFilter: 0,
stopWithTerminate: true),
autoStop: false,
androidSettings: AndroidSettings(
accuracy: LocationAccuracy.NAVIGATION,
interval: 5,
distanceFilter: 0,
client: LocationClient.google,
androidNotificationSettings: AndroidNotificationSettings(
notificationChannelName: 'Location tracking',
notificationTitle: 'Start Location Tracking',
notificationMsg: 'Track location in background',
notificationBigMsg:
'Background location is on to keep the app up-tp-date with your location. This is required for main features to work properly when the app is not running.',
notificationIconColor: Colors.grey,
notificationTapCallback:
LocationCallbackHandler.notificationCallback)));
}
The error is in this line under initState when I start or stop the plugin.
port.listen(
(dynamic data) async {
await updateUI(data);
},
);
The original code didn't have null safety so i tried to modify it. However it is pretty evident my knowledge is limited.
[1]: https://pub.dev/packages/background_locator_2
the data you are listening to from the port (dynamic data) can be null and you are sending it to the function updateUI which does not accept nullable type.
you can either check if the data is not null before calling await updateUI(data); or you can make the function updateUI accepts null, i.e (Future<void> updateUI(LocationDto? data) async {) and handle the case that the data is nullable inside the function

How convert material page as a dialog box on flutter?

when clicking this mic image then should show this recording material page as a dialog box.
That recording page I want add in this dialog box..
On the recording page, I tried it but that didn't worked.
I tried to change this page like as a dialog box but it didn't work.
dialog box code..
import 'dart:js';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:material_dialogs/material_dialogs.dart';
import 'package:material_dialogs/widgets/buttons/icon_outline_button.dart';
import '../../../../provider/sign_in_provider.dart';
import '../recorder/feature_buttons_view.dart';
String? downloadURL;
List<Reference> references = [];
#override
void initState() {
super.initState();
_onUploadComplete();
}
//snack bar for showing error
showSnackBar(String snackText, Duration d) {
final snackBar = SnackBar(content: Text(snackText), duration: d);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
RecorderDialogScreen(BuildContext context) {
Dialogs.materialDialog(
msg: 'Are you sure ? you can\'t undo this',
color: Colors.white,
context: context,
dialogWidth: kIsWeb ? 0.3 : null,
onClose: (value) => print("returned value is '$value'"),
actions: [
Expanded(
flex: 2,
child: FeatureButtonsView(
onUploadComplete: _onUploadComplete,
),
),
IconsOutlineButton(
onPressed: () {
Navigator.of(context).pop(['Test', 'List']);
},
text: 'Cancel',
iconData: Icons.cancel_outlined,
textStyle: TextStyle(color: Colors.grey),
iconColor: Colors.grey,
),
]);
}
Future<void> _onUploadComplete() async {
final sp = context.read<SignInProvider>();
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
ListResult listResult = await firebaseStorage
.ref()
.child("${sp.uid}/records")
.child("voices")
.list();
setState(() {
references = listResult.items;
});
}
error on dialog box
recording material page code
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:kathana/screens/voiceRecord/voiceRecord12/recorder/feature_buttons_view.dart';
import 'package:provider/provider.dart';
import '../../../provider/sign_in_provider.dart';
class Recorder12Screen extends StatefulWidget {
#override
State<Recorder12Screen> createState() => _Recorder12ScreenState();
}
class _Recorder12ScreenState extends State<Recorder12Screen> {
String? downloadURL;
List<Reference> references = [];
#override
void initState() {
super.initState();
_onUploadComplete();
}
//snack bar for showing error
showSnackBar(String snackText, Duration d) {
final snackBar = SnackBar(content: Text(snackText), duration: d);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
#override
Widget build(BuildContext context) {
final sp = context.read<SignInProvider>();
return Scaffold(
body: Column(
children: [
Expanded(
flex: 2,
child: FeatureButtonsView(
onUploadComplete: _onUploadComplete,
),
),
Text(
"${sp.uid}",
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
),
],
),
);
}
Future<void> _onUploadComplete() async {
final sp = context.read<SignInProvider>();
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
ListResult listResult = await firebaseStorage
.ref()
.child("${sp.uid}/records")
.child("voices")
.list();
setState(() {
references = listResult.items;
});
}
}
mic image code
Center(
child: Padding(
padding: const EdgeInsets.only(top: 1),
child: IconButton(
iconSize: 45,
icon: Ink.image(
image: const AssetImage('assets/mic.png'),
),
onPressed: () {
// do something when the button is pressed
RecorderDialogScreen(context);
},
),
),
),
If you are know how to solve it please provide a example.
FeatureButtonsView(onUploadComplete: _onUploadComplete,)
page
import 'dart:io';
import 'package:audioplayers/audioplayers.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_audio_recorder2/flutter_audio_recorder2.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import '../../../../provider/sign_in_provider.dart';
class FeatureButtonsView extends StatefulWidget {
final Function onUploadComplete;
FeatureButtonsView({
Key? key,
required this.onUploadComplete,
}) : super(key: key);
#override
_FeatureButtonsViewState createState() => _FeatureButtonsViewState();
String? userId;
}
class _FeatureButtonsViewState extends State<FeatureButtonsView> {
late bool _isPlaying;
late bool _isUploading;
late bool _isRecorded;
late bool _isRecording;
late AudioPlayer _audioPlayer;
late String _filePath;
late FlutterAudioRecorder2 _audioRecorder;
Future getData() async {
final sp = context.read<SignInProvider>();
sp.getDataFromSharedPreferences();
}
String downloadUrl = '';
Future<void> onsend() async {
//uploading to cloudfirestore
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
final sp = context.read<SignInProvider>();
await firebaseFirestore
.collection("users")
.doc("${sp.uid}")
.collection("reco")
.add({'downloadURL': downloadUrl}).whenComplete(() =>
showSnackBar("Voice uploaded successful", Duration(seconds: 2)));
}
//snackbar for showing error
showSnackBar(String snackText, Duration d) {
final snackBar = SnackBar(content: Text(snackText), duration: d);
}
#override
void initState() {
super.initState();
_isPlaying = false;
_isUploading = false;
_isRecorded = false;
_isRecording = false;
_audioPlayer = AudioPlayer();
final sp = context.read<SignInProvider>();
FirebaseFirestore.instance
.collection("users")
.doc(sp.uid)
.get()
.then((value) {
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Center(
child: _isRecorded
? _isUploading
? Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: LinearProgressIndicator()),
Text('Uplaoding to Firebase'),
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(
icon: Icon(Icons.replay),
onPressed: _onRecordAgainButtonPressed,
),
IconButton(
icon: Icon(_isPlaying ? Icons.pause : Icons.play_arrow),
onPressed: _onPlayButtonPressed,
),
IconButton(
icon: Icon(Icons.upload_file),
onPressed: _onFileUploadButtonPressed,
),
],
)
: IconButton(
icon: _isRecording
? Icon(Icons.pause)
: Icon(Icons.fiber_manual_record),
onPressed: _onRecordButtonPressed,
),
);
}
Future<void> _onFileUploadButtonPressed() async {
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
setState(() {
_isUploading = true;
});
try {
final sp = context.read<SignInProvider>();
Reference ref = firebaseStorage.ref().child("${sp.uid}/records1").child(
_filePath.substring(_filePath.lastIndexOf('/'), _filePath.length));
TaskSnapshot uploadedFile = await ref.putFile(File(_filePath));
if (uploadedFile.state == TaskState.success) {
downloadUrl = await ref.getDownloadURL();
}
widget.onUploadComplete();
onsend(); //send downloadURL after get it
} catch (error) {
print('Error occured while uplaoding to Firebase ${error.toString()}');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error occured while uplaoding'),
),
);
} finally {
setState(() {
_isUploading = false;
});
}
}
void _onRecordAgainButtonPressed() {
setState(() {
_isRecorded = false;
});
}
Future<void> _onRecordButtonPressed() async {
if (_isRecording) {
_audioRecorder.stop();
_isRecording = false;
_isRecorded = true;
} else {
_isRecorded = false;
_isRecording = true;
await _startRecording();
}
setState(() {});
}
void _onPlayButtonPressed() {
if (!_isPlaying) {
_isPlaying = true;
_audioPlayer.play(_filePath, isLocal: true);
_audioPlayer.onPlayerCompletion.listen((duration) {
setState(() {
_isPlaying = false;
});
});
} else {
_audioPlayer.pause();
_isPlaying = false;
}
setState(() {});
}
Future<void> _startRecording() async {
final bool? hasRecordingPermission =
await FlutterAudioRecorder2.hasPermissions;
if (hasRecordingPermission ?? false) {
Directory directory = await getApplicationDocumentsDirectory();
String filepath = directory.path +
'/' +
DateTime.now().millisecondsSinceEpoch.toString() +
'.aac';
_audioRecorder =
FlutterAudioRecorder2(filepath, audioFormat: AudioFormat.AAC);
await _audioRecorder.initialized;
_audioRecorder.start();
_filePath = filepath;
setState(() {});
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Center(child: Text('Please enable recording permission'))));
}
}
}

flutter - how to create voice record in popup when click mic image using flutter?

mic image code
Center(
child: Padding(
padding: const EdgeInsets.only(top: 1),
child: IconButton(
iconSize: 45,
icon: Ink.image(
image: const AssetImage('assets/mic.png'),
),
onPressed: () {
// do something when the button is pressed
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Recorder12Screen()),
);
// RecorderDialogScreen(context);
},
),
),
),
when click this mic image I want display voice recording page as a pop up window.
recording page image... my output
But I wanna like this
I my voice recording function has 2 pages
and this
2nd page is then the click pause button then display playback page
both pages I wanna display as pop up windows
1st page
2nd page
1st page code
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:kathana/screens/voiceRecord/voiceRecord12/recorder/feature_buttons_view.dart';
import 'package:provider/provider.dart';
import '../../../provider/sign_in_provider.dart';
class Recorder12Screen extends StatefulWidget {
#override
State<Recorder12Screen> createState() => _Recorder12ScreenState();
}
class _Recorder12ScreenState extends State<Recorder12Screen> {
String? downloadURL;
List<Reference> references = [];
#override
void initState() {
super.initState();
_onUploadComplete();
}
//snack bar for showing error
showSnackBar(String snackText, Duration d) {
final snackBar = SnackBar(content: Text(snackText), duration: d);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
#override
Widget build(BuildContext context) {
final sp = context.read<SignInProvider>();
return Scaffold(
body: Column(
children: [
Expanded(
flex: 2,
child: FeatureButtonsView(
onUploadComplete: _onUploadComplete,
),
),
Text(
"${sp.uid}",
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500),
),
],
),
);
}
Future<void> _onUploadComplete() async {
final sp = context.read<SignInProvider>();
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
ListResult listResult = await firebaseStorage
.ref()
.child("${sp.uid}/records")
.child("voices")
.list();
setState(() {
references = listResult.items;
});
}
}
2nd page code
import 'dart:io';
import 'package:audioplayers/audioplayers.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_audio_recorder2/flutter_audio_recorder2.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import '../../../../provider/sign_in_provider.dart';
class FeatureButtonsView extends StatefulWidget {
final Function onUploadComplete;
FeatureButtonsView({
Key? key,
required this.onUploadComplete,
}) : super(key: key);
#override
_FeatureButtonsViewState createState() => _FeatureButtonsViewState();
String? userId;
}
class _FeatureButtonsViewState extends State<FeatureButtonsView> {
late bool _isPlaying;
late bool _isUploading;
late bool _isRecorded;
late bool _isRecording;
late AudioPlayer _audioPlayer;
late String _filePath;
late FlutterAudioRecorder2 _audioRecorder;
Future getData() async {
final sp = context.read<SignInProvider>();
sp.getDataFromSharedPreferences();
}
String downloadUrl = '';
Future<void> onsend() async {
//uploading to cloudfirestore
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
final sp = context.read<SignInProvider>();
await firebaseFirestore
.collection("users")
.doc("${sp.uid}")
.collection("reco")
.add({'downloadURL': downloadUrl}).whenComplete(() =>
showSnackBar("Voice uploaded successful", Duration(seconds: 2)));
}
//snackbar for showing error
showSnackBar(String snackText, Duration d) {
final snackBar = SnackBar(content: Text(snackText), duration: d);
}
#override
void initState() {
super.initState();
_isPlaying = false;
_isUploading = false;
_isRecorded = false;
_isRecording = false;
_audioPlayer = AudioPlayer();
final sp = context.read<SignInProvider>();
FirebaseFirestore.instance
.collection("users")
.doc(sp.uid)
.get()
.then((value) {
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Center(
child: _isRecorded
? _isUploading
? Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: LinearProgressIndicator()),
Text('Uplaoding to Firebase'),
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(
icon: Icon(Icons.replay),
onPressed: _onRecordAgainButtonPressed,
),
IconButton(
icon: Icon(_isPlaying ? Icons.pause : Icons.play_arrow),
onPressed: _onPlayButtonPressed,
),
IconButton(
icon: Icon(Icons.upload_file, color: Colors.green),
onPressed: _onFileUploadButtonPressed,
),
],
)
: IconButton(
icon: _isRecording
? Icon(Icons.pause)
: Icon(Icons.fiber_manual_record),
onPressed: _onRecordButtonPressed,
),
);
}
Future<void> _onFileUploadButtonPressed() async {
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
setState(() {
_isUploading = true;
});
try {
final sp = context.read<SignInProvider>();
Reference ref = firebaseStorage.ref().child("${sp.uid}/records1").child(
_filePath.substring(_filePath.lastIndexOf('/'), _filePath.length));
TaskSnapshot uploadedFile = await ref.putFile(File(_filePath));
if (uploadedFile.state == TaskState.success) {
downloadUrl = await ref.getDownloadURL();
}
widget.onUploadComplete();
onsend(); //send downloadURL after get it
} catch (error) {
print('Error occured while uplaoding to Firebase ${error.toString()}');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error occured while uplaoding'),
),
);
} finally {
setState(() {
_isUploading = false;
});
}
}
void _onRecordAgainButtonPressed() {
setState(() {
_isRecorded = false;
});
}
Future<void> _onRecordButtonPressed() async {
if (_isRecording) {
_audioRecorder.stop();
_isRecording = false;
_isRecorded = true;
} else {
_isRecorded = false;
_isRecording = true;
await _startRecording();
}
setState(() {});
}
void _onPlayButtonPressed() {
if (!_isPlaying) {
_isPlaying = true;
_audioPlayer.play(_filePath, isLocal: true);
_audioPlayer.onPlayerCompletion.listen((duration) {
setState(() {
_isPlaying = false;
});
});
} else {
_audioPlayer.pause();
_isPlaying = false;
}
setState(() {});
}
Future<void> _startRecording() async {
final bool? hasRecordingPermission =
await FlutterAudioRecorder2.hasPermissions;
if (hasRecordingPermission ?? false) {
Directory directory = await getApplicationDocumentsDirectory();
String filepath = directory.path +
'/' +
DateTime.now().millisecondsSinceEpoch.toString() +
'.aac';
_audioRecorder =
FlutterAudioRecorder2(filepath, audioFormat: AudioFormat.AAC);
await _audioRecorder.initialized;
_audioRecorder.start();
_filePath = filepath;
setState(() {});
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Center(child: Text('Please enable recording permission'))));
}
}
}
Those 2 pages, how convert to like as a popup?
My voice recording functions work perfectly I'm asking to convert those two material pages to like popup windows.
You can use this package for recording the voice :
dependencies:
flutter_sound: ^9.2.13

Flutter Camera recorded Video are incompatible with browsers - how to convert to .mp4?

I'm trying to capture a video and upload it to firebase storage.
The problem is, the recorded video format is .mov and this format seems to be incompatible with browsers.
How could I convert the recorded file to .mp4?
Below is the code I use to record and upload my videos.
import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:video_player/video_player.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:path_provider/path_provider.dart';
class CameraTestPage extends StatefulWidget {
const CameraTestPage({Key? key}) : super(key: key);
#override
_CameraTestPageState createState() => _CameraTestPageState();
}
class _CameraTestPageState extends State<CameraTestPage> {
List<CameraDescription>? cameras;
CameraController? controller;
bool frontCamera = false;
XFile? videoFile;
VideoPlayerController? videoController;
VoidCallback? videoPlayerListener;
#override
void initState() {
initCamera();
super.initState();
}
initCamera() async {
if (cameras == null) {
cameras = await availableCameras();
}
if (controller?.value.isInitialized ?? false) {
controller!.dispose();
}
controller = CameraController(
cameras!.firstWhere(
(element) => element.lensDirection == (frontCamera ? CameraLensDirection.front : CameraLensDirection.back),
),
ResolutionPreset.medium,
enableAudio: false,
);
controller!.initialize().then((value) {
setState(() {});
});
}
void onVideoRecordButtonPressed() {
startVideoRecording().then((_) {
if (mounted) setState(() {});
});
}
void onStopButtonPressed() {
stopVideoRecording().then((file) {
if (mounted) setState(() {});
if (file != null) {
print('Video recorded to ${file.path}');
videoFile = file;
_startVideoPlayer();
}
});
}
Future<void> _startVideoPlayer() async {
if (videoFile == null) {
return;
}
final VideoPlayerController vController = VideoPlayerController.file(File(videoFile!.path));
videoPlayerListener = () {
if (videoController != null && videoController!.value.size != null) {
// Refreshing the state to update video player with the correct ratio.
if (mounted) setState(() {});
videoController!.removeListener(videoPlayerListener!);
}
};
vController.addListener(videoPlayerListener!);
await vController.setLooping(true);
await vController.initialize();
await videoController?.dispose();
if (mounted) {
setState(() {
videoController = vController;
});
}
await vController.play();
}
Future<void> startVideoRecording() async {
final CameraController? cameraController = controller;
if (cameraController == null || !cameraController.value.isInitialized) {
print('Error: select a camera first.');
return;
}
if (cameraController.value.isRecordingVideo) {
// A recording is already started, do nothing.
return;
}
try {
await cameraController.startVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return;
}
}
Future<XFile?> stopVideoRecording() async {
final CameraController? cameraController = controller;
if (cameraController == null || !cameraController.value.isRecordingVideo) {
return null;
}
try {
return cameraController.stopVideoRecording();
} on CameraException catch (e) {
_showCameraException(e);
return null;
}
}
void _showCameraException(CameraException e) {
print('Error: ${e.code}\n${e.description}');
}
_uploadVideo() async {
Reference ref = FirebaseStorage.instance.ref("test/test.mov");
UploadTask uploadTask = ref.putFile(File(videoFile!.path), SettableMetadata(contentType: 'video/mov'));
print("uploading");
uploadTask.whenComplete(() async {
String downloadUrl = await ref.getDownloadURL();
print("download url: $downloadUrl");
});
}
Widget _thumbnailWidget() {
final VideoPlayerController? localVideoController = videoController;
return Expanded(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
child: (localVideoController == null)
? Center(
child: Container(
child: Text("none"),
),
)
: Container(
child: AspectRatio(
aspectRatio: localVideoController.value.aspectRatio,
child: VideoPlayer(localVideoController),
),
decoration: BoxDecoration(
border: Border.all(color: Colors.pink),
),
),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Camera Test")),
body: Column(
children: [
if (controller != null)
Container(
child: CameraPreview(controller!),
height: 400,
),
Row(
children: [
ElevatedButton(
onPressed: () {
frontCamera = !frontCamera;
initCamera();
},
child: Text("Switch"),
),
ElevatedButton(
onPressed: () {
controller?.value.isRecordingVideo ?? false ? onStopButtonPressed() : onVideoRecordButtonPressed();
},
child: Text(controller?.value.isRecordingVideo ?? false ? "Stop" : "Record"),
),
ElevatedButton(
onPressed: videoFile != null ? _uploadVideo : null,
child: Text("Upload video"),
),
],
),
_thumbnailWidget(),
],
),
);
}
}
You can use the video_compress package to convert the video to mp4.
Here is your _uploadVideo() method updated to include this:
_uploadVideo() async {
Reference ref = FirebaseStorage.instance.ref("test/test.mp4");
MediaInfo? mediaInfo = await VideoCompress.compressVideo(
videoFile!.path,
quality: VideoQuality.DefaultQuality,
deleteOrigin: false, // It's false by default
);
UploadTask uploadTask = ref.putFile(
File(mediaInfo!.path!), SettableMetadata(contentType: 'video/mp4'));
print("uploading");
uploadTask.whenComplete(() async {
String downloadUrl = await ref.getDownloadURL();
print("download url: $downloadUrl");
});
}
Ensure you import the package by including this line:
import 'package:video_compress/video_compress.dart';

How To Pass Information From one Screen to another Screen

I wanted to Download a Image with its progress and message. I wanted to show it in a dialog. When ever I click Download Button the Image gets downloaded and the Container pops up, but it does not Show any value.
The below code uses Image_downloader package. Raised button downloads the image and display the Blank Container without any value;
import 'dart:async';
import 'dart:io';
import 'Download.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_downloader/image_downloader.dart';
void main() => runApp(HomePage());
class HomePage extends StatefulWidget {
#override
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
String message = "";
String path = "";
int _progress = 0;
#override
void initState() {
super.initState();
ImageDownloader.callback(onProgressUpdate: (String imageId, int progress) {
setState(() {
_progress = progress;
});
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RaisedButton(
onPressed: () {
_downloadImage(
"https://images.unsplash.com/photo-1503023345310-bd7c1de61c7d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80",
);
showDialog(
context: context,
builder: (_) => FunkyOverlay(progress: _progress, message: message,),
);
},
child: Text("default destination"),
),
],
),
),
),
);
}
Future<void> _downloadImage(String url,
{AndroidDestinationType destination, bool whenError = false}) async {
String fileName;
String path;
try {
String imageId;
if (whenError) {
imageId = await ImageDownloader.downloadImage(url).catchError((error) {
if (error is PlatformException) {
var path = "";
if (error.code == "404") {
print("Not Found Error.");
} else if (error.code == "unsupported_file") {
print("UnSupported FIle Error.");
path = error.details["unsupported_file_path"];
}
setState(() {
message = error.toString();
path = path;
});
}
print(error);
}).timeout(Duration(seconds: 10), onTimeout: () {
print("timeout");
});
} else {
if (destination == null) {
imageId = await ImageDownloader.downloadImage(url);
} else {
imageId = await ImageDownloader.downloadImage(
url,
destination: destination,
);
}
}
if (imageId == null) {
return;
}
fileName = await ImageDownloader.findName(imageId);
path = await ImageDownloader.findPath(imageId);
} on PlatformException catch (error) {
setState(() {
message = error.message;
});
return;
}
if (!mounted) return;
setState(() {
message = 'Image Downloaded';
});
}
}
This is the Pop up Container Part
import 'package:flutter/material.dart';
class FunkyOverlay extends StatefulWidget {
String message;
int progress;
FunkyOverlay({#required this.message, #required this.progress});
#override
State<StatefulWidget> createState() => FunkyOverlayState(message, progress);
}
class FunkyOverlayState extends State<FunkyOverlay>
with SingleTickerProviderStateMixin {
String message;
int progress;
FunkyOverlayState(this.message, this.progress);
AnimationController controller;
Animation<double> scaleAnimation;
#override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 450));
scaleAnimation =
CurvedAnimation(parent: controller, curve: Curves.elasticInOut);
controller.addListener(() {
setState(() {});
});
controller.forward();
}
#override
Widget build(BuildContext context) {
return Center(
child: Material(
color: Colors.transparent,
child: ScaleTransition(
scale: scaleAnimation,
child: Container(
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
),
child: Padding(
padding: const EdgeInsets.all(50.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Downloaded: $progress'),
Text(message)
],
),
),
),
),
),
);
}
}
You can copy paste run full code below
You can use StreamBuilder to receive progress from onProgressUpdate
class HomePageState extends State<HomePage> {
...
#override
void initState() {
super.initState();
_events = new StreamController<int>.broadcast();;
_events.add(0);
ImageDownloader.callback(onProgressUpdate: (String imageId, int progress) {
setState(() {
print("progress $progress");
_progress = progress;
_events.add(progress);
});
return StreamBuilder<int>(
stream: _events.stream,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Center(
...
children: <Widget>[
Text('Downloaded: ${snapshot.data.toString()}'),
Text(message)
working demo
full code
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:image_downloader/image_downloader.dart';
void main() => runApp(MaterialApp(home: HomePage()));
class HomePage extends StatefulWidget {
#override
HomePageState createState() => HomePageState();
}
StreamController<int> _events;
class HomePageState extends State<HomePage> {
String message = "";
String path = "";
int _progress = 0;
#override
void initState() {
super.initState();
_events = new StreamController<int>.broadcast();
;
_events.add(0);
ImageDownloader.callback(onProgressUpdate: (String imageId, int progress) {
setState(() {
print("progress $progress");
_progress = progress;
_events.add(progress);
if (progress == 100) {
Navigator.pop(context);
}
});
});
}
#override
void dispose() {
// TODO: implement dispose
_events.close();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RaisedButton(
onPressed: () {
_events.add(0);
_downloadImage(
"https://images.unsplash.com/photo-1503023345310-bd7c1de61c7d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80",
);
showDialog(
context: context,
builder: (_) => FunkyOverlay(
progress: _progress,
message: message,
),
);
},
child: Text("default destination"),
),
],
),
),
);
}
Future<void> _downloadImage(String url,
{AndroidDestinationType destination, bool whenError = false}) async {
String fileName;
String path;
try {
String imageId;
if (whenError) {
imageId = await ImageDownloader.downloadImage(url).catchError((error) {
if (error is PlatformException) {
var path = "";
if (error.code == "404") {
print("Not Found Error.");
} else if (error.code == "unsupported_file") {
print("UnSupported FIle Error.");
path = error.details["unsupported_file_path"];
}
setState(() {
message = error.toString();
path = path;
});
}
print(error);
}).timeout(Duration(seconds: 10), onTimeout: () {
print("timeout");
});
} else {
if (destination == null) {
imageId = await ImageDownloader.downloadImage(url);
} else {
imageId = await ImageDownloader.downloadImage(
url,
destination: destination,
);
}
}
if (imageId == null) {
print("imageId is null");
return;
}
fileName = await ImageDownloader.findName(imageId);
path = await ImageDownloader.findPath(imageId);
} on PlatformException catch (error) {
setState(() {
message = error.message;
});
return;
}
if (!mounted) return;
setState(() {
message = 'Image Downloaded';
});
}
}
class FunkyOverlay extends StatefulWidget {
String message;
int progress;
FunkyOverlay({#required this.message, #required this.progress});
#override
State<StatefulWidget> createState() => FunkyOverlayState(message, progress);
}
class FunkyOverlayState extends State<FunkyOverlay>
with SingleTickerProviderStateMixin {
String message;
int progress;
FunkyOverlayState(this.message, this.progress);
AnimationController controller;
Animation<double> scaleAnimation;
#override
void initState() {
super.initState();
controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 450));
scaleAnimation =
CurvedAnimation(parent: controller, curve: Curves.elasticInOut);
controller.addListener(() {
setState(() {});
});
controller.forward();
}
#override
Widget build(BuildContext context) {
print("StreamBuilder build");
return StreamBuilder<int>(
stream: _events.stream,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
print("snapshot.data ${snapshot.data.toString()}");
return Center(
child: Material(
color: Colors.transparent,
child: ScaleTransition(
scale: scaleAnimation,
child: Container(
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
),
child: Padding(
padding: const EdgeInsets.all(50.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Downloaded: ${snapshot.data.toString()}'),
Text(message)
],
),
),
),
),
),
);
});
}
}