Android 實現視頻錄製播放,android錄製

來源:互聯網
上載者:User

Android 實現視頻錄製播放,android錄製

   實作類別似的小視頻功能,可以錄製一個視頻然後播放該視頻。

   視頻錄製,使用一個自訂控制項。

      

<span style="font-size:14px;">/** * 視頻錄製控制項 *  * @author lip *  * @date 2015-3-16 */public class MovieRecorderView extends LinearLayout implements OnErrorListener {     private SurfaceView mSurfaceView;    private SurfaceHolder mSurfaceHolder;    private ProgressBar mProgressBar;     private MediaRecorder mMediaRecorder;    private Camera mCamera;    private Timer mTimer;// 計時器    private OnRecordFinishListener mOnRecordFinishListener;// 錄製完成回調介面     private int mWidth;// 視頻解析度寬度    private int mHeight;// 視頻解析度高度    private boolean isOpenCamera;// 是否一開始就開啟網路攝影機    private int mRecordMaxTime;// 一次拍攝最長時間    private int mTimeCount;// 時間計數    private File mVecordFile = null;// 檔案     public MovieRecorderView(Context context) {        this(context, null);    }     public MovieRecorderView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }     @TargetApi(Build.VERSION_CODES.HONEYCOMB)    public MovieRecorderView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        mWidth=320;        mHeight=240;        isOpenCamera=true;        mRecordMaxTime=10;         LayoutInflater.from(context).inflate(R.layout.moive_recorder_view, this);        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);        mProgressBar.setMax(mRecordMaxTime);// 設定進度條最大量         mSurfaceHolder = mSurfaceView.getHolder();        mSurfaceHolder.addCallback(new CustomCallBack());        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }     /**     *      * @author liuyinjun     *      * @date 2015-2-5     */    private class CustomCallBack implements Callback {         @Override        public void surfaceCreated(SurfaceHolder holder) {            if (!isOpenCamera)                return;            try {                initCamera();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }         @Override        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {         }         @Override        public void surfaceDestroyed(SurfaceHolder holder) {            if (!isOpenCamera)                return;            freeCameraResource();        }     }     /**     * 初始化網路攝影機     *      * @author lip     * @date 2015-3-16     * @throws IOException     */    private void initCamera() throws IOException {        if (mCamera != null) {            freeCameraResource();        }        try {            mCamera = Camera.open();        } catch (Exception e) {            e.printStackTrace();            freeCameraResource();        }        if (mCamera == null)            return;         setCameraParams();        mCamera.setDisplayOrientation(90);        mCamera.setPreviewDisplay(mSurfaceHolder);        mCamera.startPreview();        mCamera.unlock();    }     /**     * 設定網路攝影機為豎屏     *      * @author lip     * @date 2015-3-16     */    private void setCameraParams() {        if (mCamera != null) {            Parameters params = mCamera.getParameters();            params.set("orientation", "portrait");            mCamera.setParameters(params);        }    }     /**     * 釋放網路攝影機資源     *      * @author liuyinjun     * @date 2015-2-5     */    private void freeCameraResource() {        if (mCamera != null) {            mCamera.setPreviewCallback(null);            mCamera.stopPreview();            mCamera.lock();            mCamera.release();            mCamera = null;        }    }     private void createRecordDir() {       // File sampleDir = new File(Environment.getExternalStorageDirectory() + File.separator + "im/video/");        File sampleDir = new File(Environment.getExternalStorageDirectory() + File.separator+"RecordVideo/");        //File sampleDir = new File("/video/");        if (!sampleDir.exists()) {            sampleDir.mkdirs();        }        File vecordDir = sampleDir;        // 建立檔案        try {            mVecordFile = File.createTempFile("recording", ".mp4", vecordDir);//mp4格式            //LogUtils.i(mVecordFile.getAbsolutePath());            Log.d("Path:",mVecordFile.getAbsolutePath());        } catch (IOException e) {        }    }     /**     * 初始化     *      * @author lip     * @date 2015-3-16     * @throws IOException     */    private void initRecord() throws IOException {        mMediaRecorder = new MediaRecorder();        mMediaRecorder.reset();        if (mCamera != null)            mMediaRecorder.setCamera(mCamera);        mMediaRecorder.setOnErrorListener(this);        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());        mMediaRecorder.setVideoSource(VideoSource.CAMERA);// 視頻源        mMediaRecorder.setAudioSource(AudioSource.MIC);// 音頻源        mMediaRecorder.setOutputFormat(OutputFormat.MPEG_4);// 視頻輸出格式        mMediaRecorder.setAudioEncoder(AudioEncoder.AMR_NB);// 音頻格式        mMediaRecorder.setVideoSize(mWidth, mHeight);// 設定解析度:        // mMediaRecorder.setVideoFrameRate(16);// 這個我把它去掉了,感覺沒什麼用        mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 512);// 設定幀頻率,然後就清晰了        mMediaRecorder.setOrientationHint(90);// 輸出旋轉90度,保持豎屏錄製        mMediaRecorder.setVideoEncoder(VideoEncoder.MPEG_4_SP);// 視頻錄製格式        // mediaRecorder.setMaxDuration(Constant.MAXVEDIOTIME * 1000);        mMediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());        mMediaRecorder.prepare();        try {            mMediaRecorder.start();        } catch (IllegalStateException e) {            e.printStackTrace();        } catch (RuntimeException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        }    }     /**     * 開始錄製視頻     *      * @author liuyinjun     * @date 2015-2-5//     * @param fileName//     *            視訊儲存位置     * @param onRecordFinishListener     *            達到指定時間之後回調介面     */    public void record(final OnRecordFinishListener onRecordFinishListener) {        this.mOnRecordFinishListener = onRecordFinishListener;        createRecordDir();        try {            if (!isOpenCamera)// 如果未開啟網路攝影機,則開啟                initCamera();            initRecord();            mTimeCount = 0;// 時間計數器重新賦值            mTimer = new Timer();            mTimer.schedule(new TimerTask() {                 @Override                public void run() {                    // TODO Auto-generated method stub                    mTimeCount++;                    mProgressBar.setProgress(mTimeCount);// 設定進度條                    if (mTimeCount == mRecordMaxTime) {// 達到指定時間,停止拍攝                        stop();                        if (mOnRecordFinishListener != null)                            mOnRecordFinishListener.onRecordFinish();                    }                }            }, 0, 1000);        } catch (IOException e) {            e.printStackTrace();        }    }     /**     * 停止拍攝     *      * @author liuyinjun     * @date 2015-2-5     */    public void stop() {        stopRecord();        releaseRecord();        freeCameraResource();    }     /**     * 停止錄製     *      * @author liuyinjun     * @date 2015-2-5     */    public void stopRecord() {        mProgressBar.setProgress(0);        if (mTimer != null)            mTimer.cancel();        if (mMediaRecorder != null) {            // 設定後不會崩            mMediaRecorder.setOnErrorListener(null);            mMediaRecorder.setPreviewDisplay(null);            try {                mMediaRecorder.stop();            } catch (IllegalStateException e) {                e.printStackTrace();            } catch (RuntimeException e) {                e.printStackTrace();            } catch (Exception e) {                e.printStackTrace();            }        }    }     /**     * 釋放資源     *      * @author liuyinjun     * @date 2015-2-5     */    private void releaseRecord() {        if (mMediaRecorder != null) {            mMediaRecorder.setOnErrorListener(null);            try {                mMediaRecorder.release();            } catch (IllegalStateException e) {                e.printStackTrace();            } catch (Exception e) {                e.printStackTrace();            }        }        mMediaRecorder = null;    }     public int getTimeCount() {        return mTimeCount;    }     /**     * @return the mVecordFile     */    public File getmVecordFile() {        return mVecordFile;    }     /**     * 錄製完成回調介面     *     * @author lip     *      * @date 2015-3-16     */    public interface OnRecordFinishListener {        public void onRecordFinish();    }     @Override    public void onError(MediaRecorder mr, int what, int extra) {        try {            if (mr != null)                mr.reset();        } catch (IllegalStateException e) {            e.printStackTrace();        } catch (Exception e) {            e.printStackTrace();        }    }}</span>


   視頻播放:

   

<span style="font-size:14px;">public class MainActivity extends ActionBarActivity {    private MovieRecorderView movieRV;    private Button startBtn;    private Button stopBtn;    private Button playBtn;    private Button pauseBtn;    private SurfaceView playView;    private MediaPlayer player;    int position;    public MainActivity() {    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initViews();        initEvents();        init();    }    private void init()    {        player=new MediaPlayer();        playView=(SurfaceView) this.findViewById(R.id.play_surfaceV);        //設定SurfaceView自己不管理的緩衝區        playView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);        playView.getHolder().addCallback(new Callback() {            @Override            public void surfaceDestroyed(SurfaceHolder holder) {            }            @Override            public void surfaceCreated(SurfaceHolder holder) {                if (position>0) {                    try {                        //開始播放                        play();                        //並直接從指定位置開始播放                        player.seekTo(position);                        position=0;                    } catch (Exception e) {                        // TODO: handle exception                    }                }            }            @Override            public void surfaceChanged(SurfaceHolder holder, int format, int width,                                       int height) {            }        });    }    private void initViews()    {        movieRV=(MovieRecorderView)findViewById(R.id.moive_rv);        //錄製        startBtn=(Button)findViewById(R.id.start_btn);        stopBtn=(Button)findViewById(R.id.stop_btn);        //播放        playBtn=(Button)findViewById(R.id.play_btn);        pauseBtn=(Button)findViewById(R.id.pause_btn);    }    private void initEvents()    {        //開始錄製        startBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                movieRV.record(new MovieRecorderView.OnRecordFinishListener() {                    @Override                    public void onRecordFinish() {                    }                });            }        });        //停止錄製        stopBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                movieRV.stop();            }        });        //播放已錄製視頻        playBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {               play();            }        });        //暫停        pauseBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {               if(player.isPlaying())               {                   player.pause();               }               else               {                   player.start();               }            }        });    }    @Override    protected void onPause() {        //先判斷是否現正播放        if (player.isPlaying()) {            //如果現正播放我們就先儲存這個播放位置            position=player.getCurrentPosition()            ;           player.stop();        }        super.onPause();    }    private void play()    {        try {            Log.d("play:","");            player.reset();            player.setAudioStreamType(AudioManager.STREAM_MUSIC);            //設定需要播放的視頻            String path=movieRV.getmVecordFile().getAbsolutePath();            player.setDataSource(path);            Log.d("play:",path);            //把視頻畫面輸出到SurfaceView            player.setDisplay(playView.getHolder());            player.prepare();            //播放            player.start();        } catch (Exception e) {            // TODO: handle exception        }    }}</span>
布局檔案:

     

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"                xmlns:tools="http://schemas.android.com/tools"                android:layout_width="match_parent"                android:layout_height="match_parent"                android:paddingLeft="@dimen/activity_horizontal_margin"                android:paddingRight="@dimen/activity_horizontal_margin"                android:paddingTop="@dimen/activity_vertical_margin"                android:paddingBottom="@dimen/activity_vertical_margin"                tools:context=".MainActivity">    <record.lip.com.videorecord.MovieRecorderView        android:id="@+id/moive_rv"        android:layout_centerHorizontal="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content">        </record.lip.com.videorecord.MovieRecorderView>    <RelativeLayout        android:id="@+id/record_rl"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/moive_rv"        android:gravity="center"        android:layout_centerInParent="true">        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/start_btn"            android:text="開始"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/stop_btn"            android:layout_toRightOf="@id/start_btn"            android:text="停止"/>        </RelativeLayout>    <SurfaceView        android:id="@+id/play_surfaceV"        android:layout_below="@id/record_rl"        android:layout_width="200dp"        android:layout_height="200dp"        android:layout_centerHorizontal="true"/>    <RelativeLayout        android:id="@+id/play_rl"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/play_surfaceV"        android:gravity="center"        android:layout_centerInParent="true">    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/play_btn"        android:text="播放"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/pause_btn"        android:text="暫停"        android:layout_toRightOf="@id/play_btn"/>        </RelativeLayout></RelativeLayout>
    需要的系統許可權:

     

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

    基本的視頻錄製功能就可以實現了。

   :android仿視頻錄製播放

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.