Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

WWW on PC OK but android failed

Discussion in 'Android' started by Handsome-Wisely, Oct 19, 2017.

  1. Handsome-Wisely

    Handsome-Wisely

    Joined:
    Mar 20, 2013
    Posts:
    102
    i use www to get microsoft speech recongnize like this:
    Code (CSharp):
    1.  public IEnumerator IERecSound(AudioClip _clip, RecRes _res)
    2.     {
    3.         debugLog = new StringBuilder();
    4.         byte[] bClip = null;
    5.         try
    6.         {
    7.             bClip = SavWav.getByte(_clip);
    8.         }
    9.         catch (Exception _ex)
    10.         {
    11.             debugLog.AppendFormat("读取错误:{0}\n", _ex.ToString());
    12.         }
    13.         debugLog.AppendFormat("读取成功,len={0}\n",bClip.Length);
    14.         Dictionary<string, string> headers = new Dictionary<string, string>();
    15.         headers.Add("ContentType", "application/x-www-form-urlencoded");
    16.         headers.Add("Ocp-Apim-Subscription-Key", key);
    17.         WWW postData = new WWW(logInUrl, new byte[] { 0 }, headers);
    18.         while (!postData.isDone)
    19.         {
    20.             yield return new WaitForSeconds(0.1f);
    21.         }
    22.         if (!string.IsNullOrEmpty(postData.error))
    23.         {
    24.             Debug.LogError(postData.error);
    25.             debugLog.AppendFormat("授权错误:{0}\n", postData.error);
    26.             yield break;
    27.         }
    28.         debugLog.AppendFormat("授权成功\n");
    29.         string kAu = postData.text;
    30.         headers = new Dictionary<string, string>();
    31.         headers.Add("ContentType", "audio/wav; codec=audio/pcm; samplerate=16000");
    32.         headers.Add("Transfer-Encoding", "chunked");
    33.         headers.Add("User-Agent", "VirtualShopping");
    34.         headers.Add("Authorization", "Bearer " + kAu);
    35.  
    36.         WWW recTex = new WWW(recUrl, bClip, headers);
    37.         while (!recTex.isDone)
    38.         {
    39.             yield return new WaitForSeconds(0.1f);
    40.         }
    41.         if (!string.IsNullOrEmpty(recTex.error))
    42.         {
    43.             Debug.LogError(recTex.error);
    44.             debugLog.AppendFormat("获取错误:{0}\n", recTex.error);
    45.             yield break;
    46.         }
    47.         debugLog.AppendFormat("获取成功\n");
    48.         //_res.text = recTex.text;
    49.         JObject jo = JObject.Parse(recTex.text);
    50.         if (((string)jo["RecognitionStatus"]).Contains("Success"))
    51.         {
    52.             _res.text = (string)jo["DisplayText"];
    53.         }
    54.         else
    55.         {
    56.             _res.text = "";
    57.         }
    58.     }
    on PC it is ok. i recongnize my clipok.but when i make a "*.apk", it is failed. www.erro = "400 bad requirest"!

    i also make a text to speech test. it is run pc and andriod ok!

    how can i do? unitors thanks!
     
  2. Handsome-Wisely

    Handsome-Wisely

    Joined:
    Mar 20, 2013
    Posts:
    102
    text to speech code like this:
    Code (CSharp):
    1.  private IEnumerator IEGetSound(string _text, AdClip _clip)
    2.     {
    3.         //string key = "89e8b92180c743e2af527d3aa7b2fe8b";
    4.         Dictionary<string, string> headers = new Dictionary<string, string>();
    5.         headers.Add("ContentType", "application/x-www-form-urlencoded");
    6.         headers.Add("Ocp-Apim-Subscription-Key", key);
    7.         WWW postData = new WWW(logInUrl, new byte[] { 0 }, headers);
    8.         while (!postData.isDone)
    9.         {
    10.             yield return new WaitForSeconds(0.1f);
    11.         }
    12.         if (!string.IsNullOrEmpty(postData.error))
    13.         {
    14.             Debug.LogError(postData.error);
    15.             yield break;
    16.         }
    17.         string kAu = postData.text;
    18.         headers = new Dictionary<string, string>();
    19.         headers.Add("ContentType", "application/ssml+xml");
    20.         headers.Add("X-Microsoft-OutputFormat", "riff-16khz-16bit-mono-pcm");
    21.         headers.Add("User-Agent", "VirtualShopping");
    22.         headers.Add("Authorization", "Bearer " + kAu);
    23.      
    24.         string postdata = string.Format("{0}{1}{2}{3}", rStr, vStr, _text, eStr);
    25.         WWW getSound = new WWW(e2pUrl, Encoding.UTF8.GetBytes(postdata), headers);
    26.         while (!getSound.isDone)
    27.         {
    28.             yield return new WaitForSeconds(0.1f);
    29.         }
    30.         if (!string.IsNullOrEmpty(getSound.error))
    31.         {
    32.             Debug.LogError(getSound.error);
    33.             yield break;
    34.         }
    35.         _clip.ac = getSound.GetAudioClip(true, false, AudioType.WAV);
    36.         //AudioSource ads = ProcBasic.AddIndependentComponent<AudioSource>(gameObject);
    37.     }
    it is run ok on pc and andriod!
     
  3. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,722
    Can you tell which of your WWW requests fail?
    My suspect is that failure happens because of this line:
    headers.Add("Transfer-Encoding", "chunked");

    Try removing it, if it is of course the failing requests, as you do multiple requests.
     
  4. Handsome-Wisely

    Handsome-Wisely

    Joined:
    Mar 20, 2013
    Posts:
    102
    i removed "headers.Add("Transfer-Encoding", "chunked");" . it is failed on PC.

    i upload my script, can you help me to check it!
    thank you !

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Text;
    5. using System.IO;
    6. using System.Net;
    7. using System;
    8. using Newtonsoft.Json;
    9. using Newtonsoft.Json.Linq;
    10.  
    11. [System.Serializable]
    12. public class BVData : System.Object
    13. {
    14.     public string str;
    15.     [System.NonSerialized]
    16.     public AudioClip clip;
    17.     public string fileName;
    18. }
    19.  
    20. [System.Serializable]
    21. public class BVDtCtrl : System.Object
    22. {
    23.     public string path;
    24.     public string resPath;
    25.     public List<BVData> bvdts;
    26.     public BVDtCtrl()
    27.     {
    28.         bvdts = new List<BVData>();
    29.     }
    30. }
    31.  
    32. public class BingVoice : MonoBehaviour
    33. {
    34.     // Use this for initialization
    35.     void Start()
    36.     {
    37.         if (load)
    38.         {
    39.             preloadDVDtCtrl();
    40.         }
    41.         else if (text != null)
    42.         {
    43.             loadDataBVDCtrl();
    44.             StartCoroutine(IEPlay(text));
    45.         }
    46.         //testRes = new RecRes();
    47.         //yield return StartCoroutine(IERecSound(testClip, testRes));
    48.         //Debug.Log(testRes.text);
    49.     }
    50.     StringBuilder debugLog;
    51.     //string testTx;
    52.     RecRes testRes;
    53.     public bool isDebug=true;
    54.     public GUIStyle debugStyle;
    55.     public GUIStyle infoStyle;
    56.     public GUIStyle uiStyle;
    57.     void OnGUI()
    58.     {
    59.         if (isDebug)
    60.         {
    61.             if (GUILayout.Button("rectTest", uiStyle))
    62.             {
    63.                 testRes = new RecRes();
    64.                 StartCoroutine(IERecSound(testClip, testRes));
    65.             }
    66.             if (testRes != null && testRes.text != null)
    67.             {
    68.                 GUILayout.Label(testRes.text, infoStyle);
    69.             }
    70.             //GUI.color = Color.red;
    71.             if (debugLog != null)
    72.             {
    73.                 GUILayout.Label(debugLog.ToString(), debugStyle);
    74.             }
    75.         }
    76.         //GUI.color = Color.white;
    77.     }
    78.  
    79.     public string key = "89e8b92180c743e2af527d3aa7b2fe8b";
    80.     public bool load;
    81.  
    82.     public BVDtCtrl dtCtrl;
    83.  
    84.     public void loadDataBVDCtrl()
    85.     {
    86.         for (int i = 0; i < dtCtrl.bvdts.Count; i++)
    87.         {
    88.             BVData dt = dtCtrl.bvdts[i];
    89.             if (!string.IsNullOrEmpty(dt.fileName))
    90.             {
    91.                 string path = dt.fileName;
    92.                 if (!string.IsNullOrEmpty(dtCtrl.resPath))
    93.                 {
    94.                     path = string.Format("{0}/{1}", dtCtrl.resPath, dt.fileName);
    95.                 }
    96.                 UnityEngine.Object obj = Resources.Load(path);
    97.                 if (obj != null && obj is AudioClip)
    98.                 {
    99.                     dt.clip = obj as AudioClip;
    100.                     //Debug.LogFormat("load {0} ok", dt.str);
    101.                 }
    102.             }
    103.         }
    104.        
    105.     }
    106.  
    107.     public void preloadDVDtCtrl()
    108.     {
    109.         if (dtCtrl != null && !string.IsNullOrEmpty(dtCtrl.path) && Directory.Exists(dtCtrl.path))
    110.         {
    111.             StartCoroutine(IEPreLoadBVDtCtrl());
    112.         }
    113.     }
    114.    
    115.     private IEnumerator IEPreLoadBVDtCtrl()
    116.     {
    117.         for (int i = 0; i < dtCtrl.bvdts.Count; i++)
    118.         {
    119.             BVData dt = dtCtrl.bvdts[i];
    120.             if (!string.IsNullOrEmpty(dt.str) &&
    121.                 !string.IsNullOrEmpty(dt.fileName))
    122.             {
    123.                 string fp = string.Format("{0}.wav", Path.Combine(dtCtrl.path, dt.fileName));
    124.                
    125.                 if (!File.Exists(fp))
    126.                 {
    127.                     AdClip clip = new AdClip();
    128.                     yield return StartCoroutine(IEGetSound(dt.str, clip));
    129.                     if (clip.ac != null)
    130.                     {
    131.                         SavWav.Save(fp, clip.ac);
    132.                         Debug.LogFormat("load {0} success!", dt.str);
    133.                     }
    134.                     else
    135.                     {
    136.                         Debug.LogFormat("load {0} failed!", dt.str);
    137.                     }
    138.                     yield return new WaitForSeconds(0.2f);
    139.                 }
    140.                 else
    141.                 {
    142.                     Debug.LogFormat("{0} existed!", dt.str);
    143.                 }
    144.             }
    145.         }
    146.         yield return new WaitForSeconds(0.1f);
    147.     }
    148.     // Update is called once per frame
    149.     void Update()
    150.     {
    151.  
    152.     }
    153.     public string text;
    154.     public string rStr;
    155.     public string vStr;
    156.     public string eStr;
    157.     public string logInUrl = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
    158.     public string e2pUrl= "https://speech.platform.bing.com/synthesize";
    159.     public string recUrl= "https://speech.platform.bing.com/speech/recognition/interactive/cognitiveservices/v1?language=zh-CN";
    160.     public AudioSource ads;
    161.     public AudioClip testClip;
    162.  
    163.     public class AdClip
    164.     {
    165.         public AudioClip ac;
    166.     }
    167.  
    168.     public class RecRes
    169.     {
    170.         public string text;
    171.     }
    172.  
    173.     public void play(string _text, bool _isTitle = false)
    174.     {
    175.         StartCoroutine(IEPlay(_text, _isTitle));
    176.     }
    177.  
    178.     public IEnumerator IEPlay(string _text, bool _isTitle = false)
    179.     {
    180.         BVData b = null;
    181.         if (!_isTitle)
    182.         {
    183.             b = dtCtrl.bvdts.Find(element => element.str == _text);
    184.         }
    185.         else
    186.         {
    187.             b = dtCtrl.bvdts.Find(element => element.fileName == _text);
    188.         }
    189.         if (b != null && b.clip != null)
    190.         {
    191.             ads.clip = b.clip;
    192.             ads.Play();
    193.             Debug.LogFormat("play {0} from res", _text);
    194.         }
    195.         else if(!_isTitle)
    196.         {
    197.             AdClip clip = new AdClip();
    198.             yield return StartCoroutine(IEGetSound(_text, clip));
    199.             if (clip.ac != null)
    200.             {
    201.                 ads.clip = clip.ac;
    202.                 ads.Play();
    203.                 //添加到下载记录
    204.                 BVData newDt = new BVData();
    205.                 newDt.clip = clip.ac;
    206.                 newDt.str = _text;
    207.                 dtCtrl.bvdts.Add(newDt);
    208.             }
    209.         }
    210.     }
    211.  
    212.     //https://docs.microsoft.com/zh-cn/azure/cognitive-services/Speech/api-reference-rest/bingvoiceoutput 参考资料
    213.     //string postdata = "<speak version='1.0' xml:lang='zh - CN'><voice name='Microsoft Server Speech Text to Speech Voice(zh - CN, HuihuiRUS)' xml:gender='Female' xml:lang='zh - CN'>" + text + "</voice></speak>";
    214.  
    215.     private IEnumerator IEGetSound(string _text, AdClip _clip)
    216.     {
    217.         //string key = "89e8b92180c743e2af527d3aa7b2fe8b";
    218.         Dictionary<string, string> headers = new Dictionary<string, string>();
    219.         headers.Add("ContentType", "application/x-www-form-urlencoded");
    220.         headers.Add("Ocp-Apim-Subscription-Key", key);
    221.         WWW postData = new WWW(logInUrl, new byte[] { 0 }, headers);
    222.         while (!postData.isDone)
    223.         {
    224.             yield return new WaitForSeconds(0.1f);
    225.         }
    226.         if (!string.IsNullOrEmpty(postData.error))
    227.         {
    228.             Debug.LogError(postData.error);
    229.             yield break;
    230.         }
    231.         string kAu = postData.text;
    232.         headers = new Dictionary<string, string>();
    233.         headers.Add("ContentType", "application/ssml+xml");
    234.         headers.Add("X-Microsoft-OutputFormat", "riff-16khz-16bit-mono-pcm");
    235.         headers.Add("User-Agent", "VirtualShopping");
    236.         headers.Add("Authorization", "Bearer " + kAu);
    237.      
    238.         string postdata = string.Format("{0}{1}{2}{3}", rStr, vStr, _text, eStr);
    239.         WWW getSound = new WWW(e2pUrl, Encoding.UTF8.GetBytes(postdata), headers);
    240.         while (!getSound.isDone)
    241.         {
    242.             yield return new WaitForSeconds(0.1f);
    243.         }
    244.         if (!string.IsNullOrEmpty(getSound.error))
    245.         {
    246.             Debug.LogError(getSound.error);
    247.             yield break;
    248.         }
    249.         _clip.ac = getSound.GetAudioClip(true, false, AudioType.WAV);
    250.         //AudioSource ads = ProcBasic.AddIndependentComponent<AudioSource>(gameObject);
    251.     }
    252.  
    253.     public IEnumerator IERecSound(AudioClip _clip, RecRes _res)
    254.     {
    255.         debugLog = new StringBuilder();
    256.         byte[] bClip = null;
    257.         try
    258.         {
    259.             bClip = SavWav.getByte(_clip);
    260.         }
    261.         catch (Exception _ex)
    262.         {
    263.             debugLog.AppendFormat("读取错误:{0}\n", _ex.ToString());
    264.         }
    265.         debugLog.AppendFormat("读取成功,len={0}\n",bClip.Length);
    266.         Dictionary<string, string> headers = new Dictionary<string, string>();
    267.         headers.Add("ContentType", "application/x-www-form-urlencoded");
    268.         headers.Add("Ocp-Apim-Subscription-Key", key);
    269.         WWW postData = new WWW(logInUrl, new byte[] { 0 }, headers);
    270.         while (!postData.isDone)
    271.         {
    272.             yield return new WaitForSeconds(0.1f);
    273.         }
    274.         if (!string.IsNullOrEmpty(postData.error))
    275.         {
    276.             Debug.LogError(postData.error);
    277.             debugLog.AppendFormat("授权错误:{0}\n", postData.error);
    278.             yield break;
    279.         }
    280.         debugLog.AppendFormat("授权成功\n");
    281.         string kAu = postData.text;
    282.         headers = new Dictionary<string, string>();
    283.         headers.Add("ContentType", "audio/wav; codec=audio/pcm; samplerate=16000");
    284.         //headers.Add("Transfer-Encoding", "chunked");
    285.         headers.Add("User-Agent", "VirtualShopping");
    286.         headers.Add("Authorization", "Bearer " + kAu);
    287.  
    288.         WWW recTex = new WWW(recUrl, bClip, headers);
    289.         while (!recTex.isDone)
    290.         {
    291.             yield return new WaitForSeconds(0.1f);
    292.         }
    293.         if (!string.IsNullOrEmpty(recTex.error))
    294.         {
    295.             Debug.LogError(recTex.error);
    296.             debugLog.AppendFormat("获取错误:{0}\n", recTex.error);
    297.             yield break;
    298.         }
    299.         debugLog.AppendFormat("获取成功\n");
    300.         //_res.text = recTex.text;
    301.         JObject jo = JObject.Parse(recTex.text);
    302.         if (((string)jo["RecognitionStatus"]).Contains("Success"))
    303.         {
    304.             _res.text = (string)jo["DisplayText"];
    305.         }
    306.         else
    307.         {
    308.             _res.text = "";
    309.         }
    310.     }
    311. }
    312.  
    313.  
    314.  
     
  5. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,722
    It looks more like a server-side issue. Your server does not support non-chunked requests?
     
  6. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    You should probably remove your API key/s from your post

    Otherwise someone might copypasta your code and reuse it (and perhaps if their app/use is badly behaved your app would be penalised)

    Anyway if the server needs chunked data saying you will send it chunked data with a header and then not actually sending chunked data seems like the kind of thing that will fail randomly. Might be down to payload size of tests rather than platform perhaps?

    For troubleshoot networking issues capturing what is sent and comparing it can be helpful.