Получение одной строки ответа JSON с использованием Json.Parse или Regex в C # - PullRequest
2 голосов
/ 06 марта 2019

Я - младший Java-разработчик и не очень хорошо разбираюсь в C #, поэтому мне нужна помощь в решении проблемы.Я пытаюсь использовать существующий код, предоставленный на github, который принимает вход с микрофона, загружает его в Google Speech-to-Text API и затем возвращает ответ JSON с расшифровкой.Эта часть все работает нормально.

Что не работает, так это сохранение значения «Transcript:», возвращенного в JSON, в строковую переменную.

Я пытался сделать это несколькими способами, я искал способыпреобразовать ответ JSON в объект, используя SimpleJSON и Newtonsoft, и я также попытался использовать регулярное выражение для чтения строки JSON, начинающейся с «transcript».Я видел пример того, что я хотел сделать (ссылка ниже), но я получал ошибки компилятора.Если бы кто-то мог или помочь мне в этом, или указать мне на лучший результат, я был бы признателен за это.

Вот код, который я использую.

// Получено от https://github.com/steelejay/LowkeySpeech

using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Web;


[RequireComponent(typeof(AudioSource))]

public class GoogleVoiceSpeech : MonoBehaviour {

    public GUIText TextBox;

    struct ClipData {
        public int samples;
    }

    const int HEADER_SIZE = 44;

    private int minFreq;
    private int maxFreq;

    private bool micConnected = false;

    //A handle to the attached AudioSource
    private AudioSource goAudioSource;

    public string apiKey;

    // Use this for initialization
    void Start() {
        //Check if there is at least one microphone connected
        if (Microphone.devices.Length <= 0) {
            //Throw a warning message at the console if there isn't
            Debug.LogWarning("Microphone not connected!");
        } else //At least one microphone is present
          {
            //Set 'micConnected' to true
            micConnected = true;

            //Get the default microphone recording capabilities
            Microphone.GetDeviceCaps(null, out minFreq, out maxFreq);

            //According to the documentation, if minFreq and maxFreq are zero, the microphone supports any frequency...
            if (minFreq == 0 && maxFreq == 0) {
                //...meaning 44100 Hz can be used as the recording sampling rate
                maxFreq = 44100;
            }

            //Get the attached AudioSource component
            goAudioSource = this.GetComponent<AudioSource>();
        }
    }

    void OnGUI() {
        //If there is a microphone
        if (micConnected) {
            //If the audio from any microphone isn't being recorded
            if (!Microphone.IsRecording(null)) {
                //Case the 'Record' button gets pressed
                if (GUI.Button(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 25, 200, 50), "Record")) {
                    //Start recording and store the audio captured from the microphone at the AudioClip in the AudioSource
                    goAudioSource.clip = Microphone.Start(null, true, 7, maxFreq); //Currently set for a 7 second clip
                }
            } else //Recording is in progress
              {

                //Case the 'Stop and Play' button gets pressed
                if (GUI.Button(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 25, 200, 50), "Stop and Play!")) {
                    float filenameRand = UnityEngine.Random.Range(0.0f, 10.0f);

                    string filename = "testing" + filenameRand;

                    Microphone.End(null); //Stop the audio recording

                    Debug.Log("Recording Stopped");

                    if (!filename.ToLower().EndsWith(".wav")) {
                        filename += ".wav";
                    }

                    var filePath = Path.Combine("testing/", filename);
                    filePath = Path.Combine(Application.persistentDataPath, filePath);
                    Debug.Log("Created filepath string: " + filePath);

                    // Make sure directory exists if user is saving to sub dir.
                    Directory.CreateDirectory(Path.GetDirectoryName(filePath));
                    SavWav.Save(filePath, goAudioSource.clip); //Save a temporary Wav File
                    Debug.Log("Saving @ " + filePath);
                    //Insert your API KEY here.
                    string apiURL = "https://speech.googleapis.com/v1/speech:recognize?&key=AIzaSyAV65cThBBZAqmzW7MbWaccybtBrwY4Udc";
                    string Response;

                    Debug.Log("Uploading " + filePath);
                    Response = HttpUploadFile(apiURL, filePath, "file", "audio/wav; rate=44100");
                    Debug.Log("Response String: " + Response);

                    var jsonresponse = SimpleJSON.JSON.Parse(Response);

                    if (jsonresponse != null) {
                        string resultString = jsonresponse["result"][0].ToString();
                        var jsonResults = SimpleJSON.JSON.Parse(resultString);

                        string transcripts = jsonResults["alternative"][0]["transcript"].ToString();

                        Debug.Log("transcript string: " + transcripts);
                        TextBox.text = transcripts;

                    }
                    //goAudioSource.Play(); //Playback the recorded audio

                    File.Delete(filePath); //Delete the Temporary Wav file

                }

                GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 + 25, 200, 50), "Recording in progress...");
            }
        } else // No microphone
          {
            //Print a red "Microphone not connected!" message at the center of the screen
            GUI.contentColor = Color.red;
            GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 25, 200, 50), "Microphone not connected!");
        }
    }

    public string HttpUploadFile(string url, string file, string paramName, string contentType) {

        System.Net.ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;
        Debug.Log(string.Format("Uploading {0} to {1}", file, url));

        Byte[] bytes = File.ReadAllBytes(file);
        String file64 = Convert.ToBase64String(bytes,
                                         Base64FormattingOptions.None);

        Debug.Log(file64);

        try {

            var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.ContentType = "application/json";
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream())) {




                string json = "{ \"config\": { \"languageCode\" : \"en-US\" }, \"audio\" : { \"content\" : \"" + file64 + "\"}}";

                Debug.Log(json);
                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }

            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            Debug.Log(httpResponse);

            using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) {
                var result = streamReader.ReadToEnd();
                Debug.Log("Response:" + result);

            }

        }
        catch (WebException ex) {
            var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
            Debug.Log(resp);

        }


        return "empty";

    }

}

Я получаю верное консольное сообщение с результатом JSON.Мне просто нужно получить значение «transcript» в строку.Вот пример ответа от Google API.

Response:{
  "results": [
    {
      "alternatives": [
        {
          "transcript": "this is a test",
          "confidence": 0.98762906
        }
      ]
    }
  ]
}

Фактический создатель платформы SimpleJSON ответил кому-то с подобной проблемой несколько лет назад, но когда я пытаюсь реализовать подобное исправление, я получаю ошибки, потому что мой ответ является единственным.

https://answers.unity.com/questions/1443367/get-json-array-object-string-value.html

Буду признателен всем, кто поможет с этим.Я искал онлайн несколько дней, пытаясь заставить это работать, и попросил коллег (которые не могли мне помочь из-за своей неопытности в C #), прежде чем писать здесь.

1 Ответ

4 голосов
/ 06 марта 2019

Newtonsoft - лучший выбор, и я покажу вам, как его использовать.

Во-первых, создайте классы C # , вам нужно будет сохранить результат анализа. В вашем примере они будут выглядеть так:

public class SpeechResponse
{
    public Result[] results { get; set; }
}

public class Result
{
    public Alternative[] alternatives { get; set; }
}

public class Alternative
{
    public string transcript { get; set; }
    public float confidence { get; set; }
}

Вы уже знаете, как получить данные JSON, поэтому давайте предположим, что они были сохранены в String json. Вы можете превратить строку в классы C # с помощью этой команды:

var response = JsonConvert.DeserializeObject<SpeechResponse>( json );

А конкретный фрагмент данных, который вы ищете, можно получить так:

string phrase = response.results[0].alternatives[0].transcript;

Бонусный совет
Если вы используете Visual Studio, вы можете легко создать определения классов, скопировав данные примера JSON и выбрав «Правка -> Специальная вставка -> Вставить JSON как классы» ( Подробнее ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...