Search code examples
c#asp.nettext-to-speech

No sound from Client side using Microsoft Translator


I am having some problems in using the microsoft translator Speak method of the HTTP interface.

This is my code:

public void Speak()
    {
        AdmAuthentication admAuth = new AdmAuthentication("clientID", "clientSecret");
        AdmAccessToken admToken;
        string headerValue;
        admToken = admAuth.GetAccessToken();
        // Create a header with the access_token property of the returned token
        headerValue = "Bearer " + admToken.access_token;
        string language = "zh-CHS";
        string uri = "https://api.microsofttranslator.com/v2/Http.svc/Speak?&text=" + System.Web.HttpUtility.UrlEncode(lblRead.Text) + "&language=" + language + "&format=" + HttpUtility.UrlEncode("audio/wav") + "&options=MaxQuality";
        WebRequest webRequest = WebRequest.Create(uri);
        webRequest.Headers.Add("Authorization", headerValue);
        WebResponse response = null;
        try
        {
            response = webRequest.GetResponse();
            using (Stream stream = response.GetResponseStream())
            {
                using (SoundPlayer player = new SoundPlayer(stream))
                {
                    player.PlaySync();
                }
            }
        }
        catch
        {

            throw;
        }
        finally
        {
            if (response != null)
            {
                response.Close();
                response = null;
            }
        }
    }
    }

    public class AdmAccessToken
    {
        [DataMember]
        public string access_token { get; set; }
        [DataMember]
        public string token_type { get; set; }
        [DataMember]
        public string expires_in { get; set; }
        [DataMember]
        public string scope { get; set; }
    }

    public class AdmAuthentication
    {
        public static readonly string DatamarketAccessUri = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
        private string clientId;
        private string cientSecret;
        private string request;

        public AdmAuthentication(string clientId, string clientSecret)
        {
            this.clientId = clientId;
            this.cientSecret = clientSecret;
            //If clientid or client secret has special characters, encode before sending request
            this.request = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientId), HttpUtility.UrlEncode(clientSecret));
        }

        public AdmAccessToken GetAccessToken()
        {
            return HttpPost(DatamarketAccessUri, this.request);
        }

        private AdmAccessToken HttpPost(string DatamarketAccessUri, string requestDetails)
        {
            //Prepare OAuth request 
            WebRequest webRequest = WebRequest.Create(DatamarketAccessUri);
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.Method = "POST";
            byte[] bytes = Encoding.ASCII.GetBytes(requestDetails);
            webRequest.ContentLength = bytes.Length;
            using (Stream outputStream = webRequest.GetRequestStream())
            {
                outputStream.Write(bytes, 0, bytes.Length);
            }
            using (WebResponse webResponse = webRequest.GetResponse())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(AdmAccessToken));
                //Get deserialized object from JSON stream
                AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());
                return token;
            }
        }

I removed the client ID and client secret.

The problem I am facing is that, I am unable to hear anything if I run the site on the server. Yes I do know that when a user click on a button, the SoundPlayer is produced on the server thus the client side does not hear anything.

I have searched through all kinds of search methods. But to no avail.

I have tried using a method to save the stream and update to the database. All is well if I run it from Visual Studio. But at the client side, it is unable to download the stream. Or even playing the sound file which I retrieve from the database.

Please help me

I'm using Visual Studio 2010 with .NET Framework 4.0 and the text I am trying to hear is in chinese.

UPDATE: I have use another way to complete this task. If anyone is interest. Could PM me and ask for the codes.


Solution

  • You can actually implement this process end to end in Silverlight, but no way I know how only in ASP.NET. However since you can anchor a Silverlight control on an ASP.NET page easily (see here), you could refactor the transaltion code API calls into a small Silverlight control and place it on your ASP.NET page.

    As pointed out in Tim Heuer's blog entry, the MediaElement cannot directly play lossless WAV format. However there is a 'WaveMediaStreamSource' object avalaible on Codeplex that was created by a member of the Silverlight team and will allow playing the stream on the client as you need.

    After receving the trasalated value from calling the Translator API via REST (or which ever methoid you choose: SOAP, HTTP, AJAX), you can load the WaveMediaStreamSource contructor with it's value to be played back to the client.

    Don't be afraid if you have never used Silverlight before as this solution begining to end should not be that difficult. The link from Tim's example and the associated WaveMediaStreamSource from CodePlex are below.

    Make your Silverlight applications Speak to you with Microsoft Translator

    WaveMediaStreamSource (Codeplex)