플러터:마이크 입력: 두 판 사이의 차이
보이기
잔글편집 요약 없음 |
|||
| 3번째 줄: | 3번째 줄: | ||
== 개요 == | == 개요 == | ||
기기에서 마이크를 사용하는 법. | 기기에서 마이크를 사용하는 법. | ||
== 플랫폼 지원 현황 == | |||
noise_meter를 이용할건데, 모바일에서만 사용 가능하다. | |||
{| class="wikitable" | |||
! 플랫폼 !! 지원 여부 !! 이유 | |||
|- | |||
| '''Android''' || ✅ || 완전 지원 | |||
|- | |||
| '''iOS''' || ✅ || 완전 지원 | |||
|- | |||
| '''Windows''' || ❌ || noise_meter 미지원 | |||
|- | |||
| '''Web''' || ❌ || 마이크 API 제한 | |||
|- | |||
| '''macOS''' || ❓ || | |||
|- | |||
| '''Linux''' || ❓ || | |||
|} | |||
== 사전준비 권한 설정 == | == 사전준비 권한 설정 == | ||
| 22번째 줄: | 40번째 줄: | ||
|<key>NSMicrophoneUsageDescription</key> | |<key>NSMicrophoneUsageDescription</key> | ||
<string>앱에서 음성 입력을 사용합니다.</string> | <string>앱에서 음성 입력을 사용합니다.</string> | ||
iOS에선 메시지도 직접 입력할 수 있음.(여기에 사용 목적 명시해야 함.) | |||
|- | |- | ||
|Windows, | |Windows, | ||
| 36번째 줄: | 56번째 줄: | ||
|- | |- | ||
|패키지 설치 | |패키지 설치 | ||
|dependencies: | |# pubspec.yaml | ||
dependencies: | |||
flutter: | flutter: | ||
| 42번째 줄: | 63번째 줄: | ||
sdk: flutter | sdk: flutter | ||
permission_handler: ^11. | permission_handler: ^11.3.1 | ||
noise_meter: ^5.0. | noise_meter: ^5.0.1 | ||
|noise_meter는 db를 읽는다. | |noise_meter는 db를 읽는다. | ||
아마 시간이 지나면 오래된 버전이라 문제가 발생할 수 있음. | 아마 시간이 지나면 오래된 버전이라 문제가 발생할 수 있음. | ||
flutter pub get | flutter pub get | ||
|} | |} | ||
== 동작 흐름 == | |||
# 앱 시작 | |||
# 마이크 권한 요청 | |||
# 권한 허용 시 NoiseMeter 시작 | |||
# 실시간 데시벨 스트림 수신 | |||
# UI 업데이트 (setState) | |||
# 정지 버튼으로 스트림 취소 | |||
== 데시벨 측정 예시 코드 == | == 데시벨 측정 예시 코드 == | ||
마찬가지로 패키지 버전에 따라 함수명이 달라지기도 함. 오래되면 문제가 발생할 수 있음. | 마찬가지로 패키지 버전에 따라 함수명이 달라지기도 함. 오래되면 문제가 발생할 수 있음.<syntaxhighlight lang="dart">// filepath: c:\Temp\for device\decibel_app\lib\main.dart | ||
<syntaxhighlight lang="dart"> | |||
// filepath: c:\Temp\for device\decibel_app\lib\main.dart | |||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||
import 'package:noise_meter/noise_meter.dart'; | import 'package:noise_meter/noise_meter.dart'; | ||
| 166번째 줄: | 160번째 줄: | ||
); | ); | ||
} | } | ||
} | }</syntaxhighlight> | ||
</syntaxhighlight> | |||
== 코드 구조 분석 == | == 코드 구조 분석 == | ||
| 193번째 줄: | 186번째 줄: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== 주요 학습 포인트 == | == 주요 학습 포인트 == | ||
| 276번째 줄: | 261번째 줄: | ||
) | ) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== 다음 단계 학습 == | == 다음 단계 학습 == | ||
2025년 11월 19일 (수) 07:19 기준 최신판
- 플러터:개요
- 플러터:실행
- 플러터:개념 잡기
- 권한 사용
- 위젯
- 플러터:DB연결
- 플러터:Firebase(미완)
- 플러터:MySQL(미완)
- 디자인
- 플러터:배포
- 플러터:배포(안드로이드)(미완)
- 플러터:참고자료
- 플러터:위젯
- 플러터:구글 AdMob(미완)
- 플러터:라이브러리
기기에서 마이크를 사용하는 법.
noise_meter를 이용할건데, 모바일에서만 사용 가능하다.
| 플랫폼 | 지원 여부 | 이유 |
|---|---|---|
| Android | ✅ | 완전 지원 |
| iOS | ✅ | 완전 지원 |
| Windows | ❌ | noise_meter 미지원 |
| Web | ❌ | 마이크 API 제한 |
| macOS | ❓ | |
| Linux | ❓ |
| 항목 | 설명 | 비고 |
|---|---|---|
| 안드로이드 | android/app/src/main/AndroidManifest.xml 에 넣는다. |
|
| 아이폰 | ios/Runner/Info.plist에 넣는다. | <key>NSMicrophoneUsageDescription</key>
<string>앱에서 음성 입력을 사용합니다.</string> iOS에선 메시지도 직접 입력할 수 있음.(여기에 사용 목적 명시해야 함.) |
| Windows,
Web |
별도 설정 불필요. 자동으로 팝업이 뜸. |
| 항목 | 설명 | 비고 |
|---|---|---|
| 패키지 설치 | # pubspec.yaml
dependencies: flutter: sdk: flutter permission_handler: ^11.3.1 noise_meter: ^5.0.1 |
noise_meter는 db를 읽는다.
아마 시간이 지나면 오래된 버전이라 문제가 발생할 수 있음. flutter pub get |
- 앱 시작
- 마이크 권한 요청
- 권한 허용 시 NoiseMeter 시작
- 실시간 데시벨 스트림 수신
- UI 업데이트 (setState)
- 정지 버튼으로 스트림 취소
마찬가지로 패키지 버전에 따라 함수명이 달라지기도 함. 오래되면 문제가 발생할 수 있음.
// filepath: c:\Temp\for device\decibel_app\lib\main.dart
import 'package:flutter/material.dart';
import 'package:noise_meter/noise_meter.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '데시벨 측정기',
home: DecibelMeter(),
);
}
}
class DecibelMeter extends StatefulWidget {
@override
_DecibelMeterState createState() => _DecibelMeterState();
}
class _DecibelMeterState extends State<DecibelMeter> {
double _currentDB = 0.0;
bool _isListening = false;
StreamSubscription<NoiseReading>? _noiseSubscription;
Future<void> _startListening() async {
// 마이크 권한 요청
var status = await Permission.microphone.request();
if (status.isGranted) {
_noiseSubscription = NoiseMeter().noise.listen(
(NoiseReading noiseReading) {
setState(() {
_currentDB = noiseReading.meanDecibel;
});
},
onError: (error) {
print('오류: $error');
},
);
setState(() {
_isListening = true;
});
}
}
void _stopListening() {
_noiseSubscription?.cancel();
setState(() {
_isListening = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('데시벨 측정기'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'${_currentDB.toInt()} dB',
style: TextStyle(fontSize: 48),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _isListening ? _stopListening : _startListening,
child: Text(_isListening ? '정지' : '시작'),
),
],
),
),
);
}
}
// 📊 데시벨 읽기
NoiseMeter().noise.listen((NoiseReading reading) {
double db = reading.meanDecibel; // 평균 데시벨
});
// 🔒 권한 요청
Permission.microphone.request();
// 🎛️ 스트림 제어
StreamSubscription<NoiseReading>? subscription;
class _DecibelMeterState extends State<DecibelMeter> {
double _currentDB = 0.0; // 현재 데시벨 값
bool _isListening = false; // 측정 중인지 상태
StreamSubscription<NoiseReading>? _noiseSubscription; // 스트림 구독 객체
}
// 스트림 구독
_subscription = NoiseMeter().noise.listen(
(data) => setState(() => _currentDB = data.meanDecibel),
onError: (error) => print('에러: $error'),
);
// 메모리 누수 방지
_subscription?.cancel();
Future<void> _requestPermission() async {
var status = await Permission.microphone.request();
if (status.isGranted) {
// 권한 허용됨
} else if (status.isDenied) {
// 권한 거부됨
} else if (status.isPermanentlyDenied) {
// 영구 거부됨 - 설정으로 유도
openAppSettings();
}
}
@override
void dispose() {
_noiseSubscription?.cancel(); // 위젯 해제 시 스트림 정리
super.dispose();
}
| 데시벨(dB) | 소음 수준 | 예시 |
|---|---|---|
| 0-20 | 매우 조용 | 도서관, 속삭임 |
| 20-40 | 조용 | 조용한 사무실 |
| 40-60 | 보통 | 일반 대화 |
| 60-80 | 시끄러움 | TV, 음악 |
| 80-100 | 매우 시끄러움 | 지하철, 공사장 |
| 100+ | 위험 | 콘서트, 제트기 |
Color _getDecibelColor(double db) {
if (db < 40) return Colors.green; // 조용
if (db < 70) return Colors.yellow; // 보통
return Colors.red; // 시끄러움
}
LinearProgressIndicator(
value: _currentDB / 120.0, // 120dB 기준
backgroundColor: Colors.grey[300],
valueColor: AlwaysStoppedAnimation(_getDecibelColor(_currentDB)),
)
- 📈 실시간 그래프 (charts_flutter)
- 💾 측정값 저장 (shared_preferences)
- 🔔 임계값 알림 (flutter_local_notifications)
- 🎵 주파수 분석 (FFT)
- 📊 통계 분석 (평균, 최대, 최소)
- 🌐 데이터 공유 (Firebase)
- ✅ 실시간 데시벨 측정
- ✅ 마이크 권한 관리
- ✅ 간단한 시작/정지 제어
- ✅ 크로스 플랫폼 (Android/iOS)
- ✅ 메모리 안전 (스트림 정리)
이 프로젝트로 Flutter의 스트림, 권한, 네이티브 패키지 사용법을 모두 학습할 수 있습니다! 🎉