FileOutputStream最大允许排队缓冲区3。

4

当我尝试使用FileOutputStream将数据写入文件时,我遇到了这个错误,但我不知道该怎么处理它。这是错误来自的class。添加调用process的程序其余部分太长无法放在此处。

public class WriterProcessor implements AudioProcessor {
    File output;
    TarsosDSPAudioFormat audioFormat;
    FileOutputStream fos;

    /**
     *
     * @param audioFormat which this processor is attached to
     * @param output randomaccessfile of the output file
     */
    public WriterProcessor(TarsosDSPAudioFormat audioFormat,File output){
        this.output=output;
        this.audioFormat=audioFormat;
        deleteFile();
        openFileStream();
    }
    @Override
    public boolean process(AudioEvent audioEvent) {
        writeIntoOutputfile(audioEvent.getByteBuffer());
        return true;
    }

    @Override
    public void processingFinished() {
        try {
            fos.close();
        } catch (IOException ex) {
        }

        try {
            System.out.println("Buffer size: " + audioFormat.getFrameSize());
            byte[] bytes = new byte[audioFormat.getFrameSize()];


            RandomAccessFile raf = new RandomAccessFile(output.getPath(), "wr");
            raf.read(bytes, 0 ,audioFormat.getFrameSize());


        } catch (Exception ex){

        }
    }


    /**
     * Writes data into file
     * @param data
     */
    private void writeIntoOutputfile(byte[] data) {
        try {
            fos.write(data);
        } catch (IOException ioe) {
            Log.w("Audio processor", "failed writing debug data to file");
            throw new RuntimeException(ioe);
        }
    }

    private void openFileStream() {
        fos = null;
        try {
            fos = new FileOutputStream(output, false);
        } catch (FileNotFoundException e) {
            Log.e("AudioRecorder", e.getMessage());
        }
    }

    private void deleteFile(){
        if (output.exists()) {
            output.delete();
        }
    }

}

process()方法调用writeIntoOutputFile(),通常此错误来自于IOException

09-28 13:54:24.564 19533-19731/ E/[EGL-ERROR]: void __egl_platform_dequeue_buffer(egl_surface*):1851: failed to dequeue buffer from native window 0x98965808; err = -19, buf = 0x0,max_allowed_dequeued_buffers 3
09-28 13:54:24.569 19533-19731/com.starmenew.com E/CameraDeviceGLThread-1: Received exception on GL render thread: 
    java.lang.IllegalStateException: makeCurrent: EGL error: 0x300d
        at android.hardware.camera2.legacy.SurfaceTextureRenderer.checkEglError(SurfaceTextureRenderer.java:544)
        at android.hardware.camera2.legacy.SurfaceTextureRenderer.makeCurrent(SurfaceTextureRenderer.java:525)
        at android.hardware.camera2.legacy.SurfaceTextureRenderer.drawIntoSurfaces(SurfaceTextureRenderer.java:745)
        at android.hardware.camera2.legacy.GLThreadManager$1.handleMessage(GLThreadManager.java:105)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:203)
        at android.os.HandlerThread.run(HandlerThread.java:61)

也许有一种方法可以释放一个已出列的缓冲区,或者我并不真正理解这个错误。

这个异常似乎并非直接由这个类抛出(它只会抛出 IOException)。audioEvent 中的缓冲区从哪里来? - kamyar haqqani
1个回答

2

在尝试执行后台操作时,您遇到了渲染器错误。这很可能是由于您的应用程序在执行此操作时失去焦点(屏幕锁定或显示关闭)。

  • If you require your app to keep focus and display on while performing your background operation, try to add wake lock permission. From https://developer.android.com/training/scheduling/wakelock :

    public class MainActivity extends Activity {
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
      }
    }
    
  • If you are trying to perform an asynchronous background operation such as audio processing and data file writing, try AsyncTask:

    private class WriteIntoOutputfileTask extends AsyncTask <TarsosDSPAudioFormat, File, AudioEvent, Integer, Long> {
    
        protected Long doInBackground(TarsosDSPAudioFormat audioFormat, File output, AudioEvent audioEvent) {
            long processedFiles = 0;
            publishProgress(0);
            WriterProcessor myWriterProcessor = new WriterProcessor(audioFormat, output);
            myWriterProcessor.process(audioEvent);
            publishProgress(100);
            processedFiles = 1;
            return processedFiles;
        }
    
        protected void onProgressUpdate(Integer... progress) {
            setProgressPercent(progress[0]);
        }
    
        protected void onPostExecute(Long result) {
            showDialog(result + " streams processed successfully");
        }
    
    }
    // Then run this code to start the task:
    new WriteIntoOutputfileTask().execute(audioFormat, output, audioEvent);
    
这只是一个概念验证。实际实现中,您应将WriterProcessor重写为一个AsyncTask。您的public boolean process(AudioEvent audioEvent)方法将成为AsyncTask扩展的doInBackground方法的一部分。
对于更复杂的异步操作,您可以查看IntentServiceTaskScheduler
如果您希望任务同步(从您的代码中似乎不是这样),请从DownloadManagerSyncAdapter中找到最适合您需求的替代方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接