在 C# 中使用 Json.Parse 或正则表达式获取单行 JSON 响应
Obtaining single line of a JSON response, using either Json.Parse or Regex in C#
我是一名初级 Java 开发人员,对 C# 不太了解,所以我需要一些帮助来解决问题。我想做的是使用 github 上共享的现有代码,它接受麦克风输入,将其上传到 Google Speech-to-Text API,然后 returns JSON 回复文字记录。这部分一切正常。
不起作用的是将 JSON 中返回的 "Transcript:" 的值存储到字符串变量中。
我尝试过多种方法,我一直在寻找使用 SimpleJSON 和 Newtonsoft 将 JSON 响应转换为对象的方法,我也尝试过使用正则表达式阅读以 "transcript." 开头的 JSON 行,我看到了一个我想要完成的示例(链接如下),但我遇到了编译器错误。如果有人可以帮助我解决这个问题,或者指出更好的结果,我将不胜感激。
这是我正在使用的代码。
// 从 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# 缺乏经验而无法帮助我)。
Newtonsoft 是更好的选择,我将向您介绍如何使用它。
首先,create the C# classes您需要保留解析结果。在您的示例中,它们将如下所示:
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# classes:
var response = JsonConvert.DeserializeObject<SpeechResponse>( json );
而您要查找的具体数据可以这样获取:
string phrase = response.results[0].alternatives[0].transcript;
奖金提示
如果您使用 Visual Studio,您可以通过复制 JSON 示例数据并选择 "Edit -> Paste Special -> Paste JSON as Classes" (Read More).[=16 轻松创建 class 定义=]
我是一名初级 Java 开发人员,对 C# 不太了解,所以我需要一些帮助来解决问题。我想做的是使用 github 上共享的现有代码,它接受麦克风输入,将其上传到 Google Speech-to-Text API,然后 returns JSON 回复文字记录。这部分一切正常。
不起作用的是将 JSON 中返回的 "Transcript:" 的值存储到字符串变量中。
我尝试过多种方法,我一直在寻找使用 SimpleJSON 和 Newtonsoft 将 JSON 响应转换为对象的方法,我也尝试过使用正则表达式阅读以 "transcript." 开头的 JSON 行,我看到了一个我想要完成的示例(链接如下),但我遇到了编译器错误。如果有人可以帮助我解决这个问题,或者指出更好的结果,我将不胜感激。
这是我正在使用的代码。
// 从 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# 缺乏经验而无法帮助我)。
Newtonsoft 是更好的选择,我将向您介绍如何使用它。
首先,create the C# classes您需要保留解析结果。在您的示例中,它们将如下所示:
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# classes:
var response = JsonConvert.DeserializeObject<SpeechResponse>( json );
而您要查找的具体数据可以这样获取:
string phrase = response.results[0].alternatives[0].transcript;
奖金提示
如果您使用 Visual Studio,您可以通过复制 JSON 示例数据并选择 "Edit -> Paste Special -> Paste JSON as Classes" (Read More).[=16 轻松创建 class 定义=]