如何实现互联网音频流缓冲?

时间:2013-12-16 14:11:12

标签: java android buffer

我有这种doInBackground方法来记录来自互联网的音频流。主要工作是在while (len != -1) { }内完成的。这工作正常,但buffer = new byte[]不能正常工作 - 当连接中断时,IOException被立即调用,缓冲区不再使用。如何让这个缓冲区“提供”我的代码,直到它为空?我希望像音频播放器一样具有相同的行为;所以首先连接到流(它正在缓冲),然后播放,如果连接中断,它仍然从缓冲区播放(直到它为空)。

录像机:

  protected Boolean doInBackground(String... StringUrls) {

        boolean fdetermined = false;
        Environment env = new Environment();
        Calendar c = Calendar.getInstance();
        BufferedOutputStream bufOutstream = null;

      buffer = new byte[1024 * 10];
        int len=-1;

        InputStream in = null;

        URLConnection conn = null;


        try{

            conn = new URL(StringUrls[0]).openConnection();
            conn.setConnectTimeout(5000);
            in = conn.getInputStream();
            len = in.read(buffer);

            File dir = new File(env.getExternalStorageDirectory() + "/somewhere");
            if (!dir.exists()) {
                dir.mkdir();
            }


            filename = env.getExternalStorageDirectory()+"/somewhere/file";
            bufOutstream = new BufferedOutputStream(new FileOutputStream(new File(filename)));

        } catch (IOException e) {
            System.err.println("Caught IOException: " + e.getMessage());


        }



        while (len != -1) {

            if(in != null && buffer != null && bufOutstream != null) {
                try {

                bufOutstream.write(buffer, 0, len);

                 len = in.read(buffer);

                if (Recorder.this.isCancelled)  {

                    Recorder.this.stopSelf();
                    break;
                }

            } catch (IOException e) {
                e.printStackTrace();

                conn = null;
                in = null;


            }
        }

            }

            try{

                if(bufOutstream != null)    {
            bufOutstream.close();
                }

        } catch (IOException e) {
            e.printStackTrace();


        }


        return true;
        }

IO异常:

12-16 14:37:16.999  31950-32021/com.app.example W/System.err﹕ java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)
12-16 14:37:17.059  31950-32021/com.app.example W/System.err﹕ at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:542)
12-16 14:37:17.109  31950-32021/com.app.example W/System.err﹕ at libcore.io.IoBridge.recvfrom(IoBridge.java:506)
12-16 14:37:17.109  31950-32021/com.app.example W/System.err﹕ at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
12-16 14:37:17.109  31950-32021/com.app.example W/System.err﹕ at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
12-16 14:37:17.119  31950-32021/com.app.example W/System.err﹕ at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
12-16 14:37:17.119  31950-32021/com.app.example W/System.err﹕ at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
12-16 14:37:17.149  31950-32021/com.app.example W/System.err﹕ at libcore.net.http.UnknownLengthHttpInputStream.read(UnknownLengthHttpInputStream.java:41)
12-16 14:37:17.149  31950-32021/com.app.example W/System.err﹕ at java.io.InputStream.read(InputStream.java:163)
12-16 14:37:17.189  31950-32021/com.app.example W/System.err﹕ at com.app.example.Recorder$RecordTask.doInBackground(Recorder.java:376)
12-16 14:37:17.189  31950-32021/com.app.example W/System.err﹕ at com.app.example.Recorder$RecordTask.doInBackground(Recorder.java:288)
12-16 14:37:17.189  31950-32021/com.app.example W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:264)
12-16 14:37:17.189  31950-32021/com.app.example W/System.err﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-16 14:37:17.199  31950-32021/com.app.example W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-16 14:37:17.199  31950-32021/com.app.example W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
12-16 14:37:17.199  31950-32021/com.app.example W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
12-16 14:37:17.199  31950-32021/com.app.example W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
12-16 14:37:17.199  31950-32021/com.app.example W/System.err﹕ at java.lang.Thread.run(Thread.java:856)
12-16 14:37:17.199  31950-32021/com.app.example W/System.err﹕ Caused by: libcore.io.ErrnoException: recvfrom failed: ETIMEDOUT (Connection timed out)
12-16 14:37:17.199  31950-32021/com.app.example W/System.err﹕ at libcore.io.Posix.recvfromBytes(Native Method)
12-16 14:37:17.199  31950-32021/com.app.example W/System.err﹕ at libcore.io.Posix.recvfrom(Posix.java:131)
12-16 14:37:17.209  31950-32021/com.app.example W/System.err﹕ at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
12-16 14:37:17.209  31950-32021/com.app.example W/System.err﹕ at libcore.io.IoBridge.recvfrom(IoBridge.java:503)

1 个答案:

答案 0 :(得分:0)

我在下面添加了finally块:

  while (len != -1) {

                if(in != null && buffer != null && bufOutstream != null) {
                    try {

                        bufOutstream.write(buffer, 0, len);

                        len = in.read(buffer);

                        if (Recorder.this.isCancelled)  {

                            Recorder.this.stopSelf();
                            break;
                        }

                    } catch (IOException e) {
                        e.printStackTrace();

                        conn = null;
                        in = null;


                    }
                    finally{

                        //do your work here. This block will execute no matter of what exception is thrown
                        try{

                            if(bufOutstream != null)    {
                                bufOutstream.close();
                            }

                        } catch (IOException e) {
                            e.printStackTrace();


                        }
                    }
                }

            }