如何在Android中下载和流式传输音频?

时间:2015-06-17 08:15:06

标签: android inputstream android-mediaplayer nanohttpd

我正在尝试在我正在制作的应用中实现一项功能,使用户可以收听在线信息流。我需要做的是下载文件并播放它。

我已经想到了我需要一个本地HTTP服务器,我使用NanoHTTPD。现在棘手的部分是如何实际下载和流式传输音频。

这是我到目前为止提出的代码:

the unexpected end of stream

问题是当它被送到MediaPlayer时,会发生{{1}}异常。

1 个答案:

答案 0 :(得分:2)

由于没有人发布我的问题的答案,我在这里带来了另一种解决方案,我曾用它来完成类似的任务。

我想我可以使用AsyncTask下载文件,当下载达到10%时,使用界面回调启动MediaPlayer。每当下载另外20%时,MediaPlayer会更新。

以下是AsyncTask的来源:https://gist.github.com/2hamed/63a31bd55fc6514d12b5

public class DownloadAndPlayAsyncTask extends AsyncTask<String, Integer, Integer> {
    private static final String TAG = "DownloadAndPlayAsync";
    DownloadCallback downloadCallback;
    File tempFile, fullFile;

    private void createFiles(String url) {
        tempFile = Util.getTempFilePath(url);
        fullFile = Util.getFilePath(url);
    }

    public void setOnDownloadCallback(DownloadCallback callback) {
        downloadCallback = callback;
    }

    @Override
    protected Integer doInBackground(String... strings) {

        if (Util.isFileDownloaded(strings[0])) {
            createFiles(strings[0]);
            return 1;
        }
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(strings[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                Log.d(TAG, "Server returned HTTP " + connection.getResponseCode()
                        + " " + connection.getResponseMessage());
                return -1;
            }

            // this will be useful to display download percentage
            // might be -1: server did not report the length
            int fileLength = connection.getContentLength();
            createFiles(strings[0]);
            // download the file
            input = connection.getInputStream();
            output = new FileOutputStream(tempFile);

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                // allow canceling with back button
                if (isCancelled()) {
                    input.close();
                    return null;
                }
                total += count;
                // publishing the progress....
                if (fileLength > 0) // only if total length is known
                    publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }

            if (connection != null)
                connection.disconnect();
        }
        return 0;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
        if (result == 0) {
            try {
                Util.copy(tempFile, fullFile);
                tempFile.delete();
                if (downloadCallback != null) {
                    downloadCallback.onFinished(fullFile.getAbsolutePath());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (result == 1) {
            if (downloadCallback != null) {
                downloadCallback.onFinished(fullFile.getAbsolutePath());
            }
        } else {
            if (downloadCallback != null) {
                downloadCallback.onFailed();
            }
        }
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        if (downloadCallback != null) {
            downloadCallback.onProgressUpdate(values[0], tempFile.getAbsolutePath());
        }
    }

    @Override
    protected void onCancelled(Integer result) {
        super.onCancelled(result);
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
    }

    public interface DownloadCallback {
        void onProgressUpdate(int progress, String filePath);

        void onFinished(String fullFile);

        void onFailed();
    }
}

如果您发现代码末尾有DownloadCallback