StreamWriter и StreamReader заставляют редактор на некоторое время зависать - PullRequest
0 голосов
/ 23 октября 2019

Я использую следующий код, чтобы отправить текст в службу Google text to voice, затем преобразовать ответ и сохранить его в формате mp3, чтобы я мог его воспроизвести.
Моя проблема заключается в том, что я вызываю функцию PlayAudioFromText, редакторповесить на 2-4 секунды, затем он воспроизводит звук. После некоторой отладки я обнаружил, что причиной проблемы являются StreamWriter и StreamReader в функции PlayAudioFromText.

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

public void PlayAudioFromText(string text)
{
    string url = "https://texttospeech.googleapis.com/v1/text:synthesize?&key=" + ApiKey;
    ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;
    try
    {
        var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";

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

            string json = "{ \"input\": { \"text\": \"" + text + "\" }, \"voice\": { \"languageCode\": \"en-gb\", \"name\": \"en-GB-Standard-A\", \"ssmlGender\": \"FEMALE\" }, \"audioConfig\": { \"audioEncoding\": \"MP3\" } }";
            streamWriter.Write(json);
            streamWriter.Flush();
            streamWriter.Close();
        }

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


        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            var result = streamReader.ReadToEnd();
            AudioContent audioContent = JsonUtility.FromJson<AudioContent>(result);
            string filePath = SaveMP3FromBase64String(audioContent.audioContent);
            StartCoroutine(PlayAudio(filePath));
        }
    }
    catch (WebException ex)
    {
        var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
        Debug.Log(resp);
    }
}

public string SaveMP3FromBase64String(string audioString)
{
    string filePath = Path.Combine(Application.persistentDataPath, "audioFiles");

    if (!Directory.Exists(filePath))
    {
        Directory.CreateDirectory(filePath);
    }

    filePath = Path.Combine(filePath, GetRandomString() + ".mp3");
    Debug.Log(filePath);

    byte[] bytes = System.Convert.FromBase64String(audioString);
    File.WriteAllBytes(filePath, bytes);

    Debug.Log("Created filepath string: " + filePath);

    return filePath;
}

IEnumerator PlayAudio(string path)
{
    WWW www = new WWW("file:///" + path);
    if (www.error != null)
    {
        Debug.Log(www.error);
    }
    else
    {
        audioSource.clip = www.GetAudioClip();
        while (audioSource.clip.loadState != AudioDataLoadState.Loaded)
        {
            Debug.Log(audioSource.clip.loadState);
            yield return new WaitForSeconds(0.5f);
        }
        audioSource.Play();
    }
}

1 Ответ

1 голос
/ 25 октября 2019

Как уже упоминалось в комментариях, вы должны использовать async / await и Async API, как показано ниже.

public async void PlayAudioFromText(string text)
{
    string url = "https://texttospeech.googleapis.com/v1/text:synthesize?&key=" + ApiKey;
    ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;

    try {
        var httpWebRequest = WebRequest.CreateHttp(url);
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Method = "POST";

        using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync()))
        {
            string json = "{ \"input\": { \"text\": \"" + text + "\" }, \"voice\": { \"languageCode\": \"en-gb\", \"name\": \"en-GB-Standard-A\", \"ssmlGender\": \"FEMALE\" }, \"audioConfig\": { \"audioEncoding\": \"MP3\" } }";
            await streamWriter.WriteAsync(json);
            await streamWriter.FlushAsync();
        }

        var httpResponse = await httpWebRequest.GetResponseAsync();

        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            string result = await streamReader.ReadToEndAsync();
            AudioContent audioContent = JsonUtility.FromJson<AudioContent>(result);
            string filePath = SaveMP3FromBase64String(audioContent.audioContent);
            StartCoroutine(PlayAudio(filePath));
        }
    }
    catch (WebException ex)
    {
        var resp = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
        Debug.Log(resp);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...