MediaRecorder - 固件升级后代码停止工作

发布于 2025-01-02 04:46:03 字数 7795 浏览 2 评论 0原文

我有一个在 Android 2.2 上运行的三星 Galaxy Tab。我开发了一个简单的程序来分别录制音频和视频。它在我的 Galaxy 选项卡上运行良好。但是,当我将其升级到 android 2.3.3 后,一切都改变了。从那一刻起我的代码就停止工作了。这是我的代码,显示了这种意外的(对我来说:))行为:

// import statements

public class CameraPreview extends Activity implements SurfaceHolder.Callback {
    Camera camera;
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    boolean previewing = false;
    LayoutInflater controlInflater = null;
    Button recordButton;

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        getWindow().setFormat(PixelFormat.UNKNOWN);
        surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        controlInflater = LayoutInflater.from(getBaseContext());
        View viewControl = controlInflater.inflate(R.layout.control, null);
        LayoutParams layoutParamsControl = new LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        this.addContentView(viewControl, layoutParamsControl);

        recordButton = (Button)viewControl.findViewById(R.id.start_recording);
        recordButton.setOnClickListener(new View.OnClickListener() {            
            public void onClick(View v) {
                startRecording();
            }
        });

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (previewing) {
            camera.stopPreview();
            previewing = false;
        }

        if (camera != null) {
            try {
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();
                previewing = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {
        camera = Camera.open();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        camera.release();
        camera = null;
        previewing = false;
    }

    private void startRecording() {
        try {
            stopPreview();

            Thread video = new Thread(new Runnable() {
                public void run() {
                    videoRecorder = new MediaRecorder();
                    videoRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
                    videoRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
                    videoRecorder.setOutputFormat(2);
                    videoRecorder.setVideoEncodingBitRate(56 * 8 * 1024);
                    videoRecorder.setVideoSize(176, 144);
                    videoRecorder.setVideoFrameRate(12);
                    videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
                    videoRecorder.setOutputFile("/sdcard/video.m4e");
                    try {
                        videoRecorder.prepare();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    videoRecorder.start();
                }
            });
            video.start();

            Thread audio = new Thread(new Runnable() {              
                public void run() {
                    audioRecorder = new MediaRecorder();
                    audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
                    audioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                    audioRecorder.setOutputFile("/sdcard/audio.amr");
                    try {
                        audioRecorder.prepare();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    audioRecorder.start();
                }
            });
            audio.start();
        } catch (Exception e) {
            Log.e("streamer", "Unable to start recording", e);
        }
    }

    private void stopPreview() {
        if (camera == null) {
            throw new RuntimeException();           
        }
        camera.stopPreview();
        camera.release();
        camera = null;
    }
}

以下是日志输出:

     PID     TAG                MESSAGE

D    75      CameraHardwareSec  MemoryHeapBase(fd(27), size(5760128), width(800), height(600))
E    75      AuthorDriver       Command 13 completed with error -17
E    7169    MediaRecorder      prepare failed: -17
W    7169    System.err         java.io.IOException: prepare failed.
W    7169    System.err         at android.media.MediaRecorder._prepare(Native Method)
W    7169    System.err         at android.media.MediaRecorder.prepare(MediaRecorder.java:592)
W    7169    System.err         at com.video.streamer.view.CameraPreview$2.run(CameraPreview.java:121)
W    7169    System.err         at java.lang.Thread.run(Thread.java:1019)
E    7169    MediaRecorder      start called in an invalid state: 0
W    7169    dalvikvm           threadid=10: thread exiting with uncaught exception (group=0x40015578)
E    7169    AndroidRuntime     FATAL EXCEPTION: Thread-11
E    7169    AndroidRuntime     java.lang.IllegalStateException
E    7169    AndroidRuntime     at android.media.MediaRecorder.start(Native Method)
E    7169    AndroidRuntime     at com.video.streamer.view.CameraPreview$2.run(CameraPreview.java:127)
E    7169    AndroidRuntime     at java.lang.Thread.run(Thread.java:1019)
W    118     ActivityManager    Force finishing activity com.video.streamer.view/.CameraPreview

以下是用于布局目的的 XML 文件。 camera.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<SurfaceView
    android:id="@+id/camerapreview"  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
</LinearLayout>

control.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="bottom"
    >
<Button
    android:id="@+id/start_recording"  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text=" * Start Recording" 
    android:layout_gravity="right"
    android:layout_margin="10px"
    />
</LinearLayout>

我在 AndroidManifest.xml 上使用了以下权限

<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

我从 roman10 家伙博客获得的视频录制示例:Android 视频录制 API – 以示例进行说明 在我的 android 2.2 上也运行良好。但是,由于我的升级,这也停止了工作。

使用 android 2.3.3 录制视频时是否缺少任何内容?我该如何解决这个问题?

I have a samsung galaxy tab that was running on android 2.2. I developed an simple program to record the audio and video seperately. It was working fine on my galaxy tab. But, everything changed after I upgraded it to android 2.3.3. My code stopped working from that moment on. Here is my code that is showing this unexpected(for me :)) behaviour:

// import statements

public class CameraPreview extends Activity implements SurfaceHolder.Callback {
    Camera camera;
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    boolean previewing = false;
    LayoutInflater controlInflater = null;
    Button recordButton;

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        getWindow().setFormat(PixelFormat.UNKNOWN);
        surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        controlInflater = LayoutInflater.from(getBaseContext());
        View viewControl = controlInflater.inflate(R.layout.control, null);
        LayoutParams layoutParamsControl = new LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        this.addContentView(viewControl, layoutParamsControl);

        recordButton = (Button)viewControl.findViewById(R.id.start_recording);
        recordButton.setOnClickListener(new View.OnClickListener() {            
            public void onClick(View v) {
                startRecording();
            }
        });

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (previewing) {
            camera.stopPreview();
            previewing = false;
        }

        if (camera != null) {
            try {
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();
                previewing = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {
        camera = Camera.open();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        camera.release();
        camera = null;
        previewing = false;
    }

    private void startRecording() {
        try {
            stopPreview();

            Thread video = new Thread(new Runnable() {
                public void run() {
                    videoRecorder = new MediaRecorder();
                    videoRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
                    videoRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
                    videoRecorder.setOutputFormat(2);
                    videoRecorder.setVideoEncodingBitRate(56 * 8 * 1024);
                    videoRecorder.setVideoSize(176, 144);
                    videoRecorder.setVideoFrameRate(12);
                    videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
                    videoRecorder.setOutputFile("/sdcard/video.m4e");
                    try {
                        videoRecorder.prepare();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    videoRecorder.start();
                }
            });
            video.start();

            Thread audio = new Thread(new Runnable() {              
                public void run() {
                    audioRecorder = new MediaRecorder();
                    audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
                    audioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                    audioRecorder.setOutputFile("/sdcard/audio.amr");
                    try {
                        audioRecorder.prepare();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    audioRecorder.start();
                }
            });
            audio.start();
        } catch (Exception e) {
            Log.e("streamer", "Unable to start recording", e);
        }
    }

    private void stopPreview() {
        if (camera == null) {
            throw new RuntimeException();           
        }
        camera.stopPreview();
        camera.release();
        camera = null;
    }
}

Following is the log output:

     PID     TAG                MESSAGE

D    75      CameraHardwareSec  MemoryHeapBase(fd(27), size(5760128), width(800), height(600))
E    75      AuthorDriver       Command 13 completed with error -17
E    7169    MediaRecorder      prepare failed: -17
W    7169    System.err         java.io.IOException: prepare failed.
W    7169    System.err         at android.media.MediaRecorder._prepare(Native Method)
W    7169    System.err         at android.media.MediaRecorder.prepare(MediaRecorder.java:592)
W    7169    System.err         at com.video.streamer.view.CameraPreview$2.run(CameraPreview.java:121)
W    7169    System.err         at java.lang.Thread.run(Thread.java:1019)
E    7169    MediaRecorder      start called in an invalid state: 0
W    7169    dalvikvm           threadid=10: thread exiting with uncaught exception (group=0x40015578)
E    7169    AndroidRuntime     FATAL EXCEPTION: Thread-11
E    7169    AndroidRuntime     java.lang.IllegalStateException
E    7169    AndroidRuntime     at android.media.MediaRecorder.start(Native Method)
E    7169    AndroidRuntime     at com.video.streamer.view.CameraPreview$2.run(CameraPreview.java:127)
E    7169    AndroidRuntime     at java.lang.Thread.run(Thread.java:1019)
W    118     ActivityManager    Force finishing activity com.video.streamer.view/.CameraPreview

Following are my XML files used for layout purpose.
camera.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<SurfaceView
    android:id="@+id/camerapreview"  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
</LinearLayout>

control.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="bottom"
    >
<Button
    android:id="@+id/start_recording"  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text=" * Start Recording" 
    android:layout_gravity="right"
    android:layout_margin="10px"
    />
</LinearLayout>

I used the following permissions on AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

A video recording example I got from roman10 guys blog: Android Video Recording API–Illustrated with an Example was also working fine with my android 2.2. But, that also stopped working as a result of my upgrade.

Is there anything I am missing when recording video with android 2.3.3. How can I solve this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥有 2025-01-09 04:46:03

android SDK不断改变他们的API,所以当你对路径进行硬编码时,事情就会出错:

videoRecorder.setOutputFile("/sdcard/video.m4e");//or
audioRecorder.setOutputFile("/sdcard/audio.amr");

如果API改变目录,你的应用程序就会被破坏。获取文件路径的更好方法是使用API​​函数:

mVideoFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mVideoFileName += "/video.m4e";

mAudioFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mAudioFileName += "/audio.amr";

The android SDK keeps changing their API so things will go wrong when you hardcode the path:

videoRecorder.setOutputFile("/sdcard/video.m4e");//or
audioRecorder.setOutputFile("/sdcard/audio.amr");

Your app will be broken if the API ever changes the directories.A better way to get the file path it to use the API function:

mVideoFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mVideoFileName += "/video.m4e";

mAudioFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mAudioFileName += "/audio.amr";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文