amr_plugin 0.0.1
amr_plugin: ^0.0.1 copied to clipboard
A Flutter plugin that provides AMR (Adaptive Multi-Rate) audio format conversion capabilities for iOS platform. Supports bidirectional conversion between AMR-NB/AMR-WB and WAV audio formats.
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:amr_plugin/amr_plugin.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _amrPlugin = AmrPlugin();
final _urlController = TextEditingController();
String? _downloadedFilePath;
String? _convertedFilePath;
int? _downloadedFileSize;
int? _convertedFileSize;
String _status = '';
bool _isConverting = false;
bool _isWavToAmr = true;
final AudioPlayer _audioPlayer = AudioPlayer();
Future<void> _downloadFile(String url) async {
setState(() {
_status = '正在下载...';
_downloadedFilePath = null;
_convertedFilePath = null;
_downloadedFileSize = null;
_convertedFileSize = null;
});
try {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final ext = url.toLowerCase().endsWith('.amr') ? 'amr' : 'wav';
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/input.$ext');
await file.writeAsBytes(response.bodyBytes);
final fileSize = await file.length();
setState(() {
_downloadedFilePath = file.path;
_downloadedFileSize = fileSize;
_status = '下载完成: ${file.path} ($fileSize bytes)';
});
} else {
setState(() {
_status = '下载失败: ${response.statusCode}';
});
}
} catch (e) {
setState(() {
_status = '下载异常: $e';
});
}
}
Future<void> _convert() async {
if (_downloadedFilePath == null) return;
setState(() {
_isConverting = true;
_status = '正在转换...';
_convertedFilePath = null;
_convertedFileSize = null;
});
try {
String? resultPath;
if (_isWavToAmr) {
resultPath = await _amrPlugin.convertWavToAmr(_downloadedFilePath!, sampleRate: 8000, bitRate: 12200);
} else {
resultPath = await _amrPlugin.convertAmrToWav(_downloadedFilePath!, sampleRate: 8000);
}
if (resultPath != null) {
final fileSize = await File(resultPath).length();
setState(() {
_convertedFilePath = resultPath;
_convertedFileSize = fileSize;
_status = '转换完成: $resultPath ($fileSize bytes)';
});
} else {
setState(() {
_status = '转换失败';
});
}
} catch (e) {
setState(() {
_status = '转换异常: $e';
});
} finally {
setState(() {
_isConverting = false;
});
}
}
Future<void> _playConverted() async {
if (_convertedFilePath == null) return;
await _audioPlayer.stop();
await _audioPlayer.play(DeviceFileSource(_convertedFilePath!));
}
Future<void> _uploadConvertedFile() async {
if (_convertedFilePath == null) return;
setState(() {
_status = '正在上传...';
});
try {
var uri = Uri.parse('http://10.98.7.15:8080/upload');
var request = http.MultipartRequest('POST', uri);
request.files.add(
await http.MultipartFile.fromPath('file', _convertedFilePath!),
);
var response = await request.send();
if (response.statusCode == 200) {
final respStr = await response.stream.bytesToString();
setState(() {
_status = '上传成功: $respStr';
});
} else {
setState(() {
_status = '上传失败: \\${response.statusCode}';
});
}
} catch (e) {
setState(() {
_status = '上传异常: $e';
});
}
}
@override
void dispose() {
_audioPlayer.dispose();
_urlController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('AMR/WAV 转换与播放 Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
controller: _urlController,
decoration: const InputDecoration(
labelText: '输入 wav/amr 文件的 URL',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () {
if (_urlController.text.isNotEmpty) {
_downloadFile(_urlController.text);
}
},
child: const Text('下载'),
),
),
const SizedBox(width: 12),
Expanded(
child: DropdownButton<bool>(
value: _isWavToAmr,
items: const [
DropdownMenuItem(value: true, child: Text('WAV → AMR')),
DropdownMenuItem(value: false, child: Text('AMR → WAV')),
],
onChanged: (v) {
setState(() {
_isWavToAmr = v ?? true;
});
},
),
),
],
),
const SizedBox(height: 12),
ElevatedButton(
onPressed: (_downloadedFilePath != null && !_isConverting)
? _convert
: null,
child: _isConverting ? const CircularProgressIndicator() : const Text('转换'),
),
const SizedBox(height: 12),
if (_convertedFilePath != null)
ElevatedButton(
onPressed: _playConverted,
child: const Text('播放转换后文件'),
),
if (_convertedFilePath != null)
ElevatedButton(
onPressed: _uploadConvertedFile,
child: const Text('上传转换后文件'),
),
const SizedBox(height: 12),
Text(_status),
if (_downloadedFilePath != null)
Text('下载文件大小: ${_downloadedFileSize ?? '-'} bytes'),
if (_convertedFilePath != null)
Text('转换后文件大小: ${_convertedFileSize ?? '-'} bytes'),
],
),
),
),
);
}
}