安卓錄製視頻問題

今天用安卓錄製視頻

用的是別人現成的代碼,代碼原地址http://blog.csdn.net/peijiangping1989/article/details/7049991

但是會報錯


06-03 21:32:32.285: W/System.err(27250): java.lang.RuntimeException: start failed.
06-03 21:32:32.285: W/System.err(27250): at android.media.MediaRecorder.start(Native Method)
06-03 21:32:32.285: W/System.err(27250): at com.it_videorecorder.MainActivity.record(MainActivity.java:87)
06-03 21:32:32.285: W/System.err(27250): at java.lang.reflect.Method.invokeNative(Native Method)
06-03 21:32:32.285: W/System.err(27250): at java.lang.reflect.Method.invoke(Method.java:511)
06-03 21:32:32.285: W/System.err(27250): at android.view.View$1.onClick(View.java:3586)
06-03 21:32:32.285: W/System.err(27250): at android.view.View.performClick(View.java:4084)
06-03 21:32:32.285: W/System.err(27250): at android.view.View$PerformClick.run(View.java:16966)
06-03 21:32:32.285: W/System.err(27250): at android.os.Handler.handleCallback(Handler.java:615)
06-03 21:32:32.289: W/System.err(27250): at android.os.Handler.dispatchMessage(Handler.java:92)
06-03 21:32:32.289: W/System.err(27250): at android.os.Looper.loop(Looper.java:137)
06-03 21:32:32.289: W/System.err(27250): at android.app.ActivityThread.main(ActivityThread.java:4931)
06-03 21:32:32.289: W/System.err(27250): at java.lang.reflect.Method.invokeNative(Native Method)
06-03 21:32:32.289: W/System.err(27250): at java.lang.reflect.Method.invoke(Method.java:511)
06-03 21:32:32.289: W/System.err(27250): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
06-03 21:32:32.292: W/System.err(27250): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
06-03 21:32:32.292: W/System.err(27250): at dalvik.system.NativeStart.main(Native Method)

 

這個錯誤百度了下,貌似不少人遇到。

我看了下大概有幾個可能的原因

第一 視頻尺寸設置不支持

第二 格式設置不對,是3gp 還是mp4這個不同手機會有不同的實現方式。我的是這個原因

第三 幀率設置不對。可能幀率設置的高手機支持不了那麼高的分辨率

大概是這幾個原因,每個人程序不同,即使報同樣的錯誤解決方式也會不一樣。都試一試,逐個排查一下。

貼個代碼,因上面那個鏈接裏面的代碼會出現小小錯誤,把我的發上來,有用的上的就拿去吧。

package com.dineed.videorecorder;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import java.io.IOException;  

import javax.security.auth.callback.Callback;

import android.content.pm.ActivityInfo;  
import android.graphics.PixelFormat;  
import android.media.MediaRecorder;  
import android.os.Bundle;  
import android.view.SurfaceHolder;  
import android.view.SurfaceView;  
import android.view.View;  
import android.view.View.OnClickListener;  
import android.view.Window;  
import android.view.WindowManager;  
import android.widget.Button;  


public class VideoRecorderActivity extends Activity {
	private Button start;// 開始錄製按鈕   
    private Button stop;// 停止錄製按鈕   
    private MediaRecorder mediarecorder;// 錄製視頻的類   
    private SurfaceView surfaceview;// 顯示視頻的控件   
    // 用來顯示視頻的一個接口,我靠不用還不行,也就是說用mediarecorder錄製視頻還得給個界面看   
    // 想偷偷錄視頻的同學可以考慮別的辦法。。嗯需要實現這個接口的Callback接口   
    private SurfaceHolder surfaceHolder;  

    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉標題欄   
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
                WindowManager.LayoutParams.FLAG_FULLSCREEN);// 設置全屏   
        // 設置橫屏顯示   
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  
        // 選擇支持半透明模式,在有surfaceview的activity中使用。   
        getWindow().setFormat(PixelFormat.TRANSLUCENT); 
        
		setContentView(R.layout.activity_video_recorder);
		init();  
	}

	  private void init() {  
	        start = (Button) this.findViewById(R.id.start);  
	        stop = (Button) this.findViewById(R.id.stop);  
	        start.setOnClickListener(new TestVideoListener());  
	        stop.setOnClickListener(new TestVideoListener());  
	        surfaceview = (SurfaceView) this.findViewById(R.id.surfaceview);  
	        SurfaceHolder holder = surfaceview.getHolder();// 取得holder   

	        
	        holder.addCallback(new SurfaceHolder.Callback() {
				
				@Override
				public void surfaceDestroyed(SurfaceHolder holder) {
					// TODO Auto-generated method stub
					surfaceview = null;  
			        surfaceHolder = null;  
			        mediarecorder = null;
				}
				
				@Override
				public void surfaceCreated(SurfaceHolder holder) {
					// TODO Auto-generated method stub
					surfaceHolder = holder; 
				}
				
				@Override
				public void surfaceChanged(SurfaceHolder holder, int format, int width,
						int height) {
					// TODO Auto-generated method stub
					surfaceHolder = holder;  

				}
			});// holder加入回調接口  
	        

	       
	        // setType必須設置,要不出錯.   
	        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
	    }  
	
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.video_recorder, menu);
		return true;
	}

	
	
	class TestVideoListener implements OnClickListener {  
		  
        @Override  
        public void onClick(View v) {  
            if (v == start) {  
                mediarecorder = new MediaRecorder();// 創建mediarecorder對象   
                // 設置錄製視頻源爲Camera(相機)   
                mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);  
                // 設置錄製完成後視頻的封裝格式THREE_GPP爲3gp.MPEG_4爲mp4   
                mediarecorder  
                        .setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);  
                // 設置錄製的視頻編碼h263 h264   
                mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);  
                // 設置視頻錄製的分辨率。必須放在設置編碼和格式的後面,否則報錯   
                mediarecorder.setVideoSize(640, 480);  
                // 設置錄製的視頻幀率。必須放在設置編碼和格式的後面,否則報錯   
                //mediarecorder.setVideoFrameRate(20);  
                mediarecorder.setPreviewDisplay(surfaceHolder.getSurface());  
                // 設置視頻文件輸出的路徑   
                mediarecorder.setOutputFile("/sdcard/love.3gp");  
                try {  
                    // 準備錄製   
                    mediarecorder.prepare();  
                    // 開始錄製   
                    mediarecorder.start();  
                } catch (IllegalStateException e) {  
                    // TODO Auto-generated catch block   
                    e.printStackTrace();  
                } catch (IOException e) {  
                    // TODO Auto-generated catch block   
                    e.printStackTrace();  
                }  
            }  
            if (v == stop) {  
                if (mediarecorder != null) {  
                    // 停止錄製   
                    mediarecorder.stop();  
                    // 釋放資源   
                    mediarecorder.release();  
                    mediarecorder = null;  
                }  
            }  
  
        }  
  
    }  
  
    public void surfaceChanged(SurfaceHolder holder, int format, int width,  
            int height) {  
        // 將holder,這個holder爲開始在oncreat裏面取得的holder,將它賦給surfaceHolder   
        surfaceHolder = holder;  
    }  
  
    public void surfaceCreated(SurfaceHolder holder) {  
        // 將holder,這個holder爲開始在oncreat裏面取得的holder,將它賦給surfaceHolder   
        surfaceHolder = holder;  
    }  
  
    public void surfaceDestroyed(SurfaceHolder holder) {  
        // surfaceDestroyed的時候同時對象設置爲null   
        surfaceview = null;  
        surfaceHolder = null;  
        mediarecorder = null;  
    }  

	
	
	
	
}


佈局文件

其實就是一個Surfview和兩個BUTTON

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1" >

        <SurfaceView
            android:id="@+id/surfaceview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="4"
        android:gravity="center"
        android:orientation="vertical" >

        <Button
            android:id="@+id/start"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Start" />

        <Button
            android:id="@+id/stop"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Stop" />
    </LinearLayout>

</LinearLayout>

 

要注意在manifest.xml添加外部存儲寫權限,攝像頭權限錄音權限。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章