[flutter] 플러터 Riverpod를 사용하여 앱에 음성 인식 기능을 추가하는 방법은 어떻게 되나요?

플러터(Flutter) 앱에 음성 인식 기능을 추가하려면 Riverpod를 사용하여 간단하게 구현할 수 있습니다. Riverpod는 상태 관리와 의존성 주입을 위한 효과적인 라이브러리입니다. 아래에 음성 인식 기능을 구현하는 방법을 안내하겠습니다.

1. 플러터 프로젝트 설정

먼저, 플러터 프로젝트를 만들고 음성 인식 기능을 추가하기 위해 필요한 의존성 패키지를 설치해야 합니다. 프로젝트의 pubspec.yaml 파일에 다음 의존성을 추가합니다:

dependencies:
  flutter:
    sdk: flutter
  speech_to_text: ^4.2.0
  riverpod: ^0.14.0+3

의존성을 추가한 후 패키지를 가져오기 위해 터미널에서 flutter pub get 명령을 실행합니다.

2. 음성 인식 기능 구현

main.dart 파일 수정:

main.dart 파일에서 아래 내용으로 수정해주세요:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:speech_to_text/speech_to_text.dart' as stt;

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '음성 인식',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const HomePage(),
    );
  }
}

final speechProvider = Provider<stt.SpeechToText>((ref) => stt.SpeechToText());

class HomePage extends ConsumerWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final speech = ref.watch(speechProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('음성 인식')),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {},
                child: const Text('음성 입력 시작'),
              ),
              const SizedBox(height: 16),
              Text(
                '입력된 텍스트: ',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

음성 인식 기능 추가:

이제 음성 입력을 시작하는 버튼을 누를 때 음성 인식 기능을 실행하도록 구현해보겠습니다. HomePage 위젯 내에 있는 버튼 위젯의 onPressed 핸들러를 다음과 같이 수정합니다:

ElevatedButton(
  onPressed: () async {
    if (!await speech.initialize()) {
      print('음성 인식 초기화 실패');
      return;
    }
    speech.listen(
      onResult: (result) {
        final text = result.recognizedWords;
        print('인식된 텍스트: $text');
        // 인식된 텍스트 처리 로직을 추가하세요.
      },
    );
  },
  child: const Text('음성 입력 시작'),
),

위 코드에서는 음성 인식 객체를 초기화한 후 listen 메서드를 호출하여 음성 인식을 시작합니다. onResult 콜백에서 인식된 텍스트를 처리하는 로직을 추가하면 됩니다.

3. 음성 인식 결과 처리

onResult 콜백에서 인식된 텍스트를 처리하기 위해 예를 들어 텍스트를 화면에 표시하고자 한다면, HomePage 위젯 STATE에 관리하는 변수를 사용하면 됩니다. 아래와 같이 코드를 수정하세요:

class HomePage extends ConsumerWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final speech = ref.watch(speechProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('음성 인식')),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () async {
                  if (!await speech.initialize()) {
                    print('음성 인식 초기화 실패');
                    return;
                  }
                  speech.listen(
                    onResult: (result) {
                      final text = result.recognizedWords;
                      print('인식된 텍스트: $text');
                      ref.read(speechTextProvider).state = text;
                    },
                  );
                },
                child: const Text('음성 입력 시작'),
              ),
              const SizedBox(height: 16),
              Consumer(builder: (context, ref, _) {
                final speechText = ref.watch(speechTextProvider).state;
                return Text(
                  '입력된 텍스트: $speechText',
                  style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                );
              }),
            ],
          ),
        ),
      ),
    );
  }
}

final speechTextProvider = StateProvider<String>((ref) => '');

위 코드에서는 speechTextProvider라는 StateProvider를 사용하여 음성으로 인식된 텍스트를 관리합니다. 사용자가 음성 입력 시작 버튼을 누르면 인식된 텍스트가 이 프로바이더에 저장되고, 화면에 표시됩니다.

4. 실행 테스트

앱을 실행하고 음성 입력 시작 버튼을 누르면, 앱은 사용자의 음성을 듣고 인식된 텍스트를 화면에 표시합니다. 텍스트는 speechTextProvider를 통해 관리되며, 필요한 로직을 추가하여 원하는 방식으로 처리할 수 있습니다.

결론

이제 플러터 Riverpod를 사용하여 플러터 앱에 음성 인식 기능을 추가하는 방법을 알게 되었습니다. Riverpod의 강력한 기능을 활용하여 앱의 음성 인터랙션을 더욱 풍부하게 만들 수 있습니다.

참고: 위 코드는 일부 편의를 위해 간략하게 작성되었으며, 실제 앱에는 에러 처리, 권한 요청과 같은 추가 로직이 필요할 수 있습니다.

참고 자료