인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

김성욱님의 프로필 이미지
김성욱

작성한 질문수

[Python 초보] Flutter로 만드는 ChatGPT 음성번역앱

음성 인식 후 마이크 색깔이 변하지 않아요.

해결된 질문

작성

·

162

1

안녕하세요.

강의를 보면서 쭈욱 진행하고 있는데, 에뮬레이터에서 음성인식을 테스트하면 음성인식이 완료되었음에도 마이크 색깔이 검정색으로 변하지 않습니다. 강의 내용대로 코드를 쳤는데 확인 부탁드립니다. (혹시 소스코드가 깃헙에는 없나요?..)

import 'package:dash_chat_2/dash_chat_2.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:speech_to_text/speech_to_text.dart';
import 'package:speech_to_text/speech_recognition_result.dart';


class BasicScreen extends StatefulWidget {
  @override
  _BasicState createState() => _BasicState();
}

class _BasicState extends State<BasicScreen> {

  bool isListening = false;
  SpeechToText _speechToText = SpeechToText();
  bool _speechEnabled = false;
  String _lastWords = '';

  @override
  void initState() {
    super.initState();
    _initSpeech();
  }

  ChatUser user1 = ChatUser(
    id: '1',
    firstName: 'me',
    lastName: 'me',
  );

  ChatUser user2 = ChatUser(
    id: '2',
    firstName: 'chatGPT',
    lastName: 'openAI',
    profileImage: "assets/img/gpt_icon.png"
  );

  late List<ChatMessage> messages = <ChatMessage>[
    ChatMessage(
      text: '반갑습니다. 어서오세요. 무엇을 도와드릴까요?',
      user: user2,
      createdAt: DateTime.now(),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Basic example'),
      ),
      body: DashChat(
        currentUser: user1,
        onSend: (ChatMessage m) {
          setState(() {
            messages.insert(0, m);
          });
          Future<String> data = sendMessageToServer(m.text);
          data.then((value){
            setState(() {
              messages.insert(0, ChatMessage(
                text: value,
                user: user2, 
                createdAt: DateTime.now(),
                ));
            });
          });
        },
        messages: messages,
        inputOptions: InputOptions(
          leading: [
            IconButton(
              icon: Icon(Icons.mic, color: isListening? Colors.red: Colors.black),
              onPressed: (){
                setState(() {
                  isListening = !isListening;
                  if (isListening == true){
                    print('음성인식 시작');
                    _startListening();
                  }else{
                    print('음성인식 끝');
                    _stopListening();
                  }
                });
              },
            )
          ]
          ) ,
      ),
    );
  }

  Future<String> sendMessageToServer(String message) async{

    var headers = {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer sk-proj-b2yCBjZ7jwkR7nmWl4NLT3BlbkFJmm0iaZMBGPJHHy3b3I4J',
    };
    var request = http.Request('POST', Uri.parse('https://api.openai.com/v1/chat/completions'));
    request.body = json.encode({
      "model": "gpt-3.5-turbo",
      "messages": [
        {
          "role": "user",
          "content": message,
        }
      ]
    });
    request.headers.addAll(headers);

    http.StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      String responseString = await response.stream.bytesToString();
      Map<String, dynamic> jsonResponse = json.decode(responseString);
      String result = jsonResponse['choices'] != null? jsonResponse['choices'][0]['message']['content']: "No result found";
      print(responseString);
      return result;
    }
    else {
      print(response.reasonPhrase);
      return "ERROR";
    }
  }
  /// This has to happen only once per app
  void _initSpeech() async {
    print("음성인식 기능을 시작합니다.");
    _speechEnabled = await _speechToText.initialize();
    // setState(() {});
  }

  /// Each time to start a speech recognition session
  void _startListening() async {
    print("음성인식을 시작합니다.");
    await _speechToText.listen(onResult: _onSpeechResult);
    // setState(() {});
  }

  /// Manually stop the active speech recognition session
  /// Note that there are also timeouts that each platform enforces
  /// and the SpeechToText plugin supports setting timeouts on the
  /// listen method.
  void _stopListening() async {
    print("음성인식을 종료합니다.");
    await _speechToText.stop();
    // setState(() {});
  }

  /// This is the callback that the SpeechToText plugin calls when
  /// the platform returns recognized words.
  void _onSpeechResult(SpeechRecognitionResult result) {
    _lastWords = "";
    if(result.finalResult){
      _lastWords = result.recognizedWords;
      print("최종 인식된 문장: $_lastWords");
      setState(() {
        messages.insert(0, ChatMessage(
          text: _lastWords,
          user: user1, 
          createdAt: DateTime.now(),
        ));
      });

      Future<String> data = sendMessageToServer(_lastWords);
      data.then((value){
        setState(() {
          messages.insert(0, ChatMessage(
            text: value,
            user: user2, 
            createdAt: DateTime.now(),
            ));
        });
      });
    }    
  }
}

답변 1

1

다비님의 프로필 이미지
다비
지식공유자

안녕하세요?

 

우선 불편을 드려 죄송합니다.

코드는 섹션4 Flutter 환경세팅 소개 [링크] 오른쪽 상단 '수업자료'에 있으니 참고하시기 바랍니다.

 

제가 강의에서 구현한 기능은

버튼이 기본값이 false였다가, 한번 누르면 true로 바뀌고, 음성인식이 시작되고, 빨간색으로 바뀝니다.

다시 한번 누르면 값이 다시 false로 바뀌고, 음성인식이 종료되고, 검정색으로 바뀝니다.

 

올려주신 코드로 테스트했을 때, 정상적으로 버튼이 빨간색과 검정색으로 바뀌는 것을 확인했는데요. 만약 마이크 버튼을 2번째로 눌러서 음성인식을 종료시켜도 계속 빨간색으로 남아있는 상황이라면 번거로우시더라도 다시 한 번 상황을 알려주시면 감사하겠습니다.(예:flutter run 이 후 터미널에 출력된 메시지)

 

감사합니다.

 

김성욱님의 프로필 이미지
김성욱
질문자

아, 저는 발화를 하고 자동으로 발화가 종료됨을 인식(End point detecting)하기 때문에 버튼을 누르지 않아도 색이 바뀔것을 기대했었습니다. 설명 감사합니다.

김성욱님의 프로필 이미지
김성욱

작성한 질문수

질문하기