使用MediaRecorder将视图中的位图编码为视频

时间:2017-11-21 19:19:32

标签: java android bitmap mediarecorder surface

我一直在尝试将视图中的位图图像编码为mp4视频。我使用MediaRecorder设置与Surface作为输入。代码在循环中的第二次迭代时失败。看来画布未成功解锁,然后lockCanvas失败并抛出错误。

可能导致此异常的原因是什么?

public class ViewRecorder
{
    private View recordView;
    private boolean run = true;
    private String filename;

    public ViewRecorder(View recordView, String filename)
    {
        this.recordView = recordView;
        this.filename = filename;

        Thread thread = new Thread(new Task());
        thread.start();
    }

    /*
     * Stops the recording
     */
    public void Stop()
    {
        this.run = false;
    }

    /*
     * Encodes a frame every 100 mS
     */
    private class Task implements Runnable
    {
        @Override
        public void run()
        {
            try
            {
                MediaRecorder mediaRecorder = new MediaRecorder();
                mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
                mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                mediaRecorder.setVideoFrameRate(10);
                //this.mediaRecorder.setVideoEncodingBitRate(20000);
                mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
                mediaRecorder.setOutputFile(filename + ".mp4");

                recordView.setDrawingCacheEnabled(true);
                Bitmap bitmap = Bitmap.createBitmap(recordView.getDrawingCache());
                recordView.setDrawingCacheEnabled(false);

                mediaRecorder.setVideoSize(bitmap.getWidth(), bitmap.getHeight());

                mediaRecorder.prepare();
                mediaRecorder.start();   // Recording is now started

                while(run)
                {
                    Thread.sleep(100);

                    recordView.setDrawingCacheEnabled(true);
                    bitmap = Bitmap.createBitmap(recordView.getDrawingCache());
                    recordView.setDrawingCacheEnabled(false);

                    Surface surface = mediaRecorder.getSurface();
                    Canvas canvas = surface.lockCanvas(null);
                    canvas.drawBitmap(bitmap, 0, 0, new Paint());
                    surface.unlockCanvasAndPost(canvas);
                }

                mediaRecorder.stop();
                mediaRecorder.reset();
                mediaRecorder.release();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}

这是一个例外:

11-21 18:59:35.220 26737-27432/ W/System.err: java.lang.IllegalArgumentException
11-21 18:59:35.220 26737-27432/ W/System.err:     at android.view.Surface.nativeLockCanvas(Native Method)
11-21 18:59:35.220 26737-27432/ W/System.err:     at android.view.Surface.lockCanvas(Surface.java:322)
11-21 18:59:35.221 26737-27432/ W/System.err:     at .ViewRecorder$Task.run(ViewRecorder.java:77)
11-21 18:59:35.221 26737-27432/ W/System.err:     at java.lang.Thread.run(Thread.java:762)
11-21 19:00:47.783 26737-26744/ W/art: Suspending all threads took: 35.361ms
11-21 19:01:25.983 26737-26744/ W/art: Suspending all threads took: 22.830ms

1 个答案:

答案 0 :(得分:-1)

不确定您是否仍在寻找解决方案,但是我发现了这一点:

移动-Surface surface = mediaRecorder.getSurface();

在循环之外,因此仅被调用一次。第二次调用时出现错误