From dc973178c679f8f40a6106ea6f3acfbb15c9e4f4 Mon Sep 17 00:00:00 2001 From: sindhu Date: Sat, 22 Feb 2025 06:59:38 +0700 Subject: [PATCH] step 7 : convert .aac into .mp3 --- lib/repository/base_repository.dart | 52 ++++++++++++++++++- lib/screen/home/rekam_screen.dart | 27 ++++++++++ macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 16 ++++++ pubspec.yaml | 1 + 5 files changed, 97 insertions(+), 1 deletion(-) diff --git a/lib/repository/base_repository.dart b/lib/repository/base_repository.dart index a3496a2..82a55dd 100644 --- a/lib/repository/base_repository.dart +++ b/lib/repository/base_repository.dart @@ -7,6 +7,56 @@ abstract class BaseRepository { final Dio dio; BaseRepository({required this.dio}); + // POST audio + Future> postAudio({ + required String filePath, + required String service, + String? token, + }) async { + try { + FormData formData = FormData.fromMap({ + "audio": + await MultipartFile.fromFile(filePath, filename: "rekaman.mp3"), + }); + + final response = await dio.post( + // Constant.baseUrl + service, + service, + data: formData, + options: Options( + headers: token != null + ? { + HttpHeaders.contentTypeHeader: "multipart/form-data", + HttpHeaders.authorizationHeader: "Bearer $token", + } + : { + HttpHeaders.authorizationHeader: "Bearer $token" + }, + contentType: "application/json", + ), + ); + if (response.statusCode != 200) { + throw BaseRepositoryException( + message: "Invalid Http Response ${response.statusCode}", + ); + } + Map jsonData = jsonDecode(response.data); + if (jsonData["status"] != "OK") { + throw BaseRepositoryException( + message: jsonData["message"], + ); + } else { + return jsonData; + } + } on DioException catch (e) { + throw BaseRepositoryException(message: e.message ?? ""); + } on SocketException catch (e) { + throw BaseRepositoryException(message: e.message); + } on BaseRepositoryException catch (e) { + throw BaseRepositoryException(message: e.message); + } + } + // POST PAKE ContentType JSON Future> post({ required Map param, @@ -103,4 +153,4 @@ class BaseRepositoryException implements Exception { BaseRepositoryException({ required this.message, }); -} \ No newline at end of file +} diff --git a/lib/screen/home/rekam_screen.dart b/lib/screen/home/rekam_screen.dart index 5b84b3b..bb583b2 100644 --- a/lib/screen/home/rekam_screen.dart +++ b/lib/screen/home/rekam_screen.dart @@ -1,3 +1,4 @@ +import 'package:ffmpeg_kit_flutter_audio/ffmpeg_kit.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; @@ -64,6 +65,7 @@ class RekamScreen extends HookConsumerWidget { try { final dir = await getApplicationDocumentsDirectory(); final filePath = '${dir.path}/myFile.aac'; + // final filePath = '${dir.path}/myFile.mp3'; audioPath.value = filePath; await recorder.value.startRecorder( @@ -77,6 +79,22 @@ class RekamScreen extends HookConsumerWidget { } } + Future convertToMp3(String inputPath) async { + final dir = await getApplicationDocumentsDirectory(); + final outputPath = "${dir.path}/output.mp3"; + + // Jalankan perintah FFmpeg untuk konversi + await FFmpegKit.execute( + '-i $inputPath -codec:a libmp3lame -qscale:a 2 $outputPath'); + + // Pastikan file MP3 berhasil dibuat + if (File(outputPath).existsSync()) { + return outputPath; + } else { + return null; + } + } + Future berhentiRekaman() async { try { await recorder.value.stopRecorder(); @@ -84,6 +102,15 @@ class RekamScreen extends HookConsumerWidget { isRekam.value = false; // panggil fungsi untuk kirim ke BE + if (audioPath.value.isNotEmpty) { + String? mp3Path = await convertToMp3(audioPath.value); + if (mp3Path != null) { + // await uploadAudioFile(mp3Path); + print('mp3 convert $mp3Path'); + } else { + print("Konversi gagal!"); + } + } } catch (e) { print("Error stop record ${e.toString()}"); } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 3d6169d..3fbb018 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,11 +5,13 @@ import FlutterMacOS import Foundation +import ffmpeg_kit_flutter_audio import mobile_scanner import path_provider_foundation import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 0c20d8e..2bca9f2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -113,6 +113,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" + ffmpeg_kit_flutter_audio: + dependency: "direct main" + description: + name: ffmpeg_kit_flutter_audio + sha256: "1e6de4d6afdd1b842dde17ef55d9cfa8911d5c4a5858e80f4371487c29e42f8a" + url: "https://pub.dev" + source: hosted + version: "6.0.3" + ffmpeg_kit_flutter_platform_interface: + dependency: transitive + description: + name: ffmpeg_kit_flutter_platform_interface + sha256: addf046ae44e190ad0101b2fde2ad909a3cd08a2a109f6106d2f7048b7abedee + url: "https://pub.dev" + source: hosted + version: "0.2.1" file: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 91baee5..64dbae7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -49,6 +49,7 @@ dependencies: toastification: ^2.3.0 mobile_scanner: ^6.0.6 flutter_sound: ^9.23.1 + ffmpeg_kit_flutter_audio: ^6.0.3 dev_dependencies: flutter_test: