开发者

How do I use Bing translation service to play audio for specific words on android?

开发者 https://www.devze.com 2023-03-17 08:03 出处:网络
I am trying to port my WP7 app to android.I was using Bing translation service to download & play audio for specific words/phrases.How can I do this in android? in bing, the stream comes as a .wav

I am trying to port my WP7 app to android. I was using Bing translation service to download & play audio for specific words/phrases. How can I do this in android? in bing, the stream comes as a .wav file. Here was my WP7 code:

private void button1_Click(object sender, RoutedEventArgs e)  
    {  
        this.Speak();  
    }  

    public void Speak()  
    {  
        string appId = "Your ID";  
        string text = "Speak this for me";  
        string language = "en";  

        string uri = "http://api.microsofttranslator.com/v2/Http.svc/Speak?appId=" + appId +  
                "&text=" + text + "&language=" + language + "&file=speak.wav";  

        WebClient client = new WebClient();  
        client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);  
        client.OpenReadAsync(new Uri(uri));  
    }  

    void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)  
    {  
        if (e.Error != null) return;  

        var sound = e.Result;  
        Player.Source = null;  
        string filename = "MyAudio";  
        using (IsolatedStorageFile userStoreForApplication = IsolatedStorageFile.GetUserStoreForApplication())  
        {  
            bool fileExists = userStoreForApplication.FileExists(filename);  

            if (fileExists)  
            {  
                userStoreForApplication.DeleteFile(filename);  
            }  

            var isolatedStorageFileStream = userStoreForApplication.CreateFile(filename);  

            using (isolatedStorageFileStream)  
            {  
                SaveFile(e.Result, isolatedStorageFileStream);  

                if (e.Error == null)  
                {  
                    Player.SetSource(isolatedStorageFileStream);  
                }  
            }  
        }    
    }  

    public static void SaveFile(System.IO.Stream input, System.IO.Stream output)  
    {  
        try 
        {  
            byte[] buffer = new byte[32768];  

            while (true)  
            {  
                int read = input.Read(buffer, 0, buffer.Length);  

                if (read <= 0)  
                {  
                    return;  
                }  

                output.Write(buffer, 0, read);  
            }  
        }  
        catch (Exception ex)  
        {  
            MessageBox.Show(ex.ToString());  
        }  
    }   


    void mysound_MediaFailed(object sender, ExceptionRoutedEventArgs e)  
    {  
        MessageBox.Show(e.ErrorException.Message);  
    }  

    void mysound_MediaOpened(object sender, RoutedEvent开发者_如何学运维Args e)  
    {  
        Player.Play();  
    } 


I thought I'd just drop a generic response about executing HTTP requests and downloading files, but the more troublesome thing I ran into is how Microsoft Azure wants to do authentication. Evidently using an App ID is deprecated and their API is extremely picky about the request headers and parameters.

In any case, I'd suggest starting with writing an AsyncTask that handles executing a HttpURLConnection. I ended up with:

/**
 * Tailor-made HTTP request for Microsoft Azure, downloading a file to a
 * specified location.
 */
private class HttpDownloadFile extends AsyncTask<String, Integer, String> {

    private String mDir;

    @Override
    protected String doInBackground(String... params) {
        if (params.length < 2) {
            throw new IllegalArgumentException(
                    "Two arguments required for "
                            + getClass().getSimpleName());
        }
        String response = null;
        String uri = params[0];
        String query = params[1];
        try {
            if (query.length() > 0) {
                uri += "?" + query;
            }
            URL url = new URL(uri);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded");
            if (params.length > 2) {
                connection.setRequestProperty("Authorization", "Bearer "
                        + params[2]);
            }
            connection.connect();
            int fileLength = connection.getContentLength();
            String charset = PREFERRED_CHARSET;
            if (connection.getContentEncoding() != null) {
                charset = connection.getContentEncoding();
            }

            InputStream input;
            OutputStream output;
            boolean isError = false;
            try {
                input = connection.getInputStream();
                output = new FileOutputStream(mDir);
            } catch (IOException e) {
                input = connection.getErrorStream();
                output = new ByteArrayOutputStream();
                isError = true;
            }

            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }

            output.flush();
            if (!isError) {
                response = mDir;
            } else {
                response = ((ByteArrayOutputStream) output).toString(charset);
                Log.e(TAG, response);
                response = null;
            }
            output.close();
            input.close();
        } catch (Exception e) {
            Log.e(TAG, "Failed requesting " + uri, e);
        }
        return response;
    }
}

You can then execute the task with the correct parameters:

HttpDownloadFile task = new HttpDownloadFile();
task.execute(
        getString(R.string.url_speak),
        getString(R.string.url_speak_query,
                text, toLanguage, file),
        accessToken,
        Environment.getExternalStorageDirectory().getPath()
                + "/temp.wav");

My strings.xml contains:

<string 
    name="url_speak" 
    formatted="false" 
    translate="false">http://api.microsofttranslator.com/v2/Http.svc/Speak</string>
<string 
    name="url_speak_query" 
    formatted="false" 
    translate="false">text=%s&amp;language=%s&amp;file=%s</string>

Unfortunately, this implies that you have to code for obtaining the authentication token already done. No worries! I've written the complete code for all of that, too:

  1. MainActivity.java
  2. strings.xml


This seems pretty Straight Forward to me, first use HttpUrlConnection to make call to the web service, and then handle the response as a wav file, either you can first save the file locally and then load it in a Mediaplayer instance or you can directly load it as a live stream.

0

精彩评论

暂无评论...
验证码 换一张
取 消