I'm building a ChatBot app using Dialogflow and I want to implement Voice Recognition feature in my app. As you know Dialogflow provide us a feature to detect intent on the basis of audio but it only accepts audio in the form of base64. The problem for me is that I'm unable to encode the audio file into Base64. I'm new to Flutter Development so if in case I'm missing something or doing it in a wrong way then please let me know. Thanks!
I've tried this method but it's not giving me the proper output:
Future<String> makeBase64(String path) async {
try {
if (!await fileExists(path)) return null;
File file = File(path);
file.openRead();
var contents = await file.readAsBytes();
var base64File = base64.encode(contents);
return base64File;
} catch (e) {
print(e.toString());
return null;
}
}
You could do this:
List<int> fileBytes = await file.readAsBytes();
String base64String = base64Encode(fileBytes);
The converted string doesn't include mimetype, so you might need to include like this
final fileString = 'data:audio/mp3;base64,$base64String';
Related
I am using dio package to make a GET request to a server to retrieve a PDF file.
The request is working fine, I get the PDF in base64.
I get the response.data, and I use base64Decode to get the Uint8List, I save the file in the storage.
class FileSaverHelper {
Future<String> save({required String filename, required Uint8List bytes}) async {
final String tempDir = (await getTemporaryDirectory()).path;
final filePath = "$tempDir/$filename";
await File(filePath).writeAsBytes(bytes);
return filePath;
}
}
class OpenFileHelper {
final FileSaverHelper fileSaverHelper = Get.find();
Future<void> open({
required String filename,
required Future<Uint8List> Function() onDownload
}) async {
final Uint8List bytes = await onDownload();
final filePath = await fileSaverHelper.save(
filename: filename,
bytes: bytes
);
if(await File(filePath).exists()){
OpenFilex.open(filePath);
}
}
}
When I open the PDF it has only the first page and when I test the base64 that the server sends in the site Base64 to PDF, the PDF decoded has the amount of pages correctly (which is two).
Why after I use base64Decode(response.data), save the PDF to the storage, open it, it has only the first page but in the site the amount of pages is correct?
I found the problem is with the GET request, since the base64 retrieve by the server only through flutter, the file is retrieved incomplete.
I have a question regarding how to view a PDF from URL.
I’m using flutter_pdfview library and I try to get a PDF from an URL and to view it in my Flutter app.
The problem is that my URL can be accessed ONLY with a token (session ID/header), but I don’t know how to pass it because is not working on the way I do it at the moment.
Here is an example of how the owner of the flutter_pdfview library is getting the PDF from an URL (without a Header): https://github.com/endigo/flutter_pdfview/blob/master/example/lib/main.dart#L49
And here is my code where I don’t know how else to pass the header than like this:
Future<File> createFileOfPdfUrl() async {
Completer<File> completer = Completer();
if (kDebugMode) {
print("Start download file from internet!");
}
try {
String url =
"$customURL.pdf";
if (kDebugMode) {
print("url: $url");
}
final filename = url.substring(url.lastIndexOf("/") + 1);
var client = HttpClient();
HttpClientRequest request = await client.getUrl(Uri.parse(url));
request.headers.add(
HttpHeaders.acceptHeader,
HeaderValue(
"text/plain", {'APPAUTH': '${widget.authService.loginToken}'})); // this method doesn't seems to work for me. I'm getting an empty PDF.
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
var dir = await getApplicationDocumentsDirectory();
if (kDebugMode) {
print("Download files");
print("${dir.path}/$filename");
}
File file = File("${dir.path}/$filename");
await file.writeAsBytes(bytes, flush: true);
completer.complete(file);
} catch (e) {
throw Exception('Error parsing asset file!');
}
return completer.future;
}
DO NOT do this:
request.headers.add(
HttpHeaders.acceptHeader, // here is the problem
HeaderValue(
"text/plain", {'APPAUTH': '${widget.authService.loginToken}'}));
SOLUTION for me:
request.headers.add("APPAUTH", "12345abcde67890defgh");
For some reason if you provide a HeaderValue you also need to provide a string value before it, which can be HttpHeaders.acceptHeader or HttpHeaders.serverHeader etc. I tried a lot of them from that enum list and none worked for me so I used the above solution where you don't need to pass that HttpHeader value type.
I have a pdf file. I want to write that file in phone memory? Below is the code.
First I am scanning then I am converting the image to pdf, Now I want to save that pdf to phone memory. Please help me.
void onDocumentScanner(BuildContext context) async {
try {
File scannedDocumentFile;
var doc = await DocumentScannerFlutter.launchForPdf(context);
if (doc != null) {
refreshDownloadedFiles();
scannedDocumentFile = doc;
String fileName = basename(scannedDocumentFile.path);
final directory = (await getExternalStorageDirectory())!.path;
File saveFilePath = File('$directory/$fileName');
saveFilePath.openWrite(); //Here I want to save to the file
print("Path = $fileName");
Get.toNamed(AppRoutes.viewDownloadedFile,
arguments: [scannedDocumentFile.path, fileName, folderId])!
.whenComplete(() {
refreshFetchedData();
});
}
} catch (e) {
print(e);
}
}
I haven't seen the .openWrite() method before, but the documentation says that it has 2 named arguments FileMode and encoding - try to specify them.
If it won't work, I can only share my solution, with .writeAsBytes method.
Instead of saveFilePath.openWrite() you can bundle the data first and then save it.
final byteData = await rootBundle.load(fileName);
await saveFilePath.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
I am working with Flutter and developing module like offline download media.
I got some solution for Video DRM tools like https://www.vdocipher.com/ but I want to implement it for audio.
The simplest way that I know about to store and hide the media as follow but it will be visible if I turn on show hidden files.
static Future<File> downloadAudioFile(String audioUrl) async {
var hiddenFolder = '.nomedia';
var directoryExternal = await getExternalStorageDirectory();
final dir = Directory('${directoryExternal!.path}/$hiddenFolder');
if ((await dir.exists())) {
} else {
dir.create();
}
final http.Response responseData = await http.get(Uri.parse(audioUrl));
var uint8list = responseData.bodyBytes;
var buffer = uint8list.buffer;
ByteData byteData = ByteData.view(buffer);
String fileName = audioUrl.split('/').last;
File file = await File('${dir.path}/.${fileName}').writeAsBytes(
buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
I want to do it for audio & video files, Please let me know if anyone have idea about it.
I'm developing an app using Flutter that implementing Dialogflow api. I want to add voice recognation feature but the Dialogflow api only accept audio file in base64 format. I'm stuck at encoding the audio file. Please help me I'm new to Flutter.
This is the error:
FileSystemException: Cannot open file, path = 'assets/book_a_room.wav' (OS Error: No such file or directory, errno = 2)
String path = 'assets/book_a_room.wav';
Future<String> Base64(String path) async {
try {
File file = File(path);
file.openRead();
List<int> fileBytes = await file.readAsBytes();
String base64String = base64Encode(fileBytes);
return base64String;
} catch (e) {
print(e.toString());
return null;
}
}