最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android視頻錄制功能的實現(xiàn)步驟

 更新時間:2021年04月16日 10:31:04   作者:lrh517  
這篇文章主要介紹了Android視頻錄制功能的實現(xiàn)步驟,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

官方使用指南請查看Google音頻和視頻指南

視頻錄制基本步驟

1.申明權(quán)限

 <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <--如果錄制的視頻保存在外部SD卡,還需要添加以下權(quán)限->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

注意:RECORD_AUDIO為危險權(quán)限,從Android 6.0開始(API級別23)開始,需要動態(tài)獲取。

2.視頻錄制參數(shù)配置

import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.text.TextUtils;

/**
 * @author Created by LRH
 * @description 視頻錄制參數(shù)(參數(shù)可自行拓展)
 * @date 2021/1/19 13:54
 */
public class VideoRecorderConfig {
	//Camera
    private Camera camera;
    //攝像頭預(yù)覽寬度
    private int videoWidth;
    //攝像頭預(yù)覽高度
    private int videoHeight;
    //攝像頭預(yù)覽偏轉(zhuǎn)角度
    private int cameraRotation;
    //保存的文件路徑
    private String path;
    //由于Camera使用的是SurfaceTexture,所以這里使用了SurfaceTexture
    //也可使用SurfaceHolder
    private SurfaceTexture mSurfaceTexture;
    
    private int cameraId = 0;

    public SurfaceTexture getSurfaceTexture() {
        return mSurfaceTexture;
    }

    public void setSurfaceTexture(SurfaceTexture surfaceTexture) {
        mSurfaceTexture = surfaceTexture;
    }

    public Camera getCamera() {
        return camera;
    }

    public void setCamera(Camera camera) {
        this.camera = camera;
    }

    public int getVideoWidth() {
        return videoWidth;
    }

    public void setVideoWidth(int videoWidth) {
        this.videoWidth = videoWidth;
    }

    public int getVideoHeight() {
        return videoHeight;
    }

    public void setVideoHeight(int videoHeight) {
        this.videoHeight = videoHeight;
    }

    public int getCameraRotation() {
        return cameraRotation;
    }

    public void setCameraRotation(int cameraRotation) {
        this.cameraRotation = cameraRotation;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public int getCameraId() {
        return cameraId;
    }

    public void setCameraId(int cameraId) {
        this.cameraId = cameraId;
    }

    public boolean checkParam() {
        return mSurfaceTexture != null && camera != null && videoWidth > 0 && videoHeight > 0 && !TextUtils.isEmpty(path);
    }
}

3.視頻錄制接口封裝(使用MediaRecorder

import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Build;
import android.view.Surface;

import com.emp.yjy.baselib.utils.LogUtils;
import java.io.IOException;

/**
 * @author Created by LRH
 * @description
 * @date 2021/1/19 13:53
 */
public class VideoRecorder {
    private static final String TAG = "VideoRecord";
    private MediaRecorder mRecorder;

    public VideoRecorder() {

    }

    /**
     * 開始錄制
     *
     * @param config
     * @return
     */
    public boolean startRecord(VideoRecorderConfig config, MediaRecorder.OnErrorListener listener) {
        if (config == null || !config.checkParam()) {
            LogUtils.e(TAG, "參數(shù)錯誤");
            return false;
        }
        if (mRecorder == null) {
            mRecorder = new MediaRecorder();
        }
        mRecorder.reset();
        if (listener != null) {
            mRecorder.setOnErrorListener(listener);
        }

        config.getCamera().unlock();
        mRecorder.setCamera(config.getCamera());
        //設(shè)置音頻通道
//        mRecorder.setAudioChannels(1);
        //聲音源
//        AudioSource.DEFAULT:默認(rèn)音頻來源
//        AudioSource.MIC:麥克風(fēng)(常用)
//        AudioSource.VOICE_UPLINK:電話上行
//        AudioSource.VOICE_DOWNLINK:電話下行
//        AudioSource.VOICE_CALL:電話、含上下行
//        AudioSource.CAMCORDER:攝像頭旁的麥克風(fēng)
//        AudioSource.VOICE_RECOGNITION:語音識別
//        AudioSource.VOICE_COMMUNICATION:語音通信
        mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        //視頻源
        mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        try {
            //推薦使用以下代碼進(jìn)行參數(shù)配置
            CamcorderProfile bestCamcorderProfile = getBestCamcorderProfile(config.getCameraId());
            mRecorder.setProfile(bestCamcorderProfile);
        } catch (Exception e) {
            //設(shè)置輸出格式
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            //聲音編碼格式
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            //視頻編碼格式
            mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
        }

        //設(shè)置視頻的長寬
        mRecorder.setVideoSize(config.getVideoWidth(), config.getVideoHeight());
//        設(shè)置取樣幀率
        mRecorder.setVideoFrameRate(30);
//        mRecorder.setAudioEncodingBitRate(44100);
//        設(shè)置比特率(比特率越高質(zhì)量越高同樣也越大)
        mRecorder.setVideoEncodingBitRate(800 * 1024);
//        這里是調(diào)整旋轉(zhuǎn)角度(前置和后置的角度不一樣)
        mRecorder.setOrientationHint(config.getCameraRotation());
//        設(shè)置記錄會話的最大持續(xù)時間(毫秒)
        mRecorder.setMaxDuration(15 * 1000);
        //設(shè)置輸出的文件路徑
        mRecorder.setOutputFile(config.getPath());
        //設(shè)置預(yù)覽對象(可以使用SurfaceHoler代替)
        mRecorder.setPreviewDisplay(new Surface(config.getSurfaceTexture()));
        //預(yù)處理
        try {
            mRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        //開始錄制
        mRecorder.start();
        return true;
    }

    /**
     * 停止錄制
     */
    public void stopRecord() {
        if (mRecorder != null) {
            try {
                mRecorder.stop();
                mRecorder.reset();
                mRecorder.release();
                mRecorder = null;
            } catch (Exception e) {
                e.printStackTrace();
                LogUtils.e(TAG, e.getMessage());
            }

        }
    }

    /**
     * 暫停錄制
     *
     * @return
     */
    public boolean pause() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && mRecorder != null) {
            mRecorder.pause();
            return true;
        }
        return false;
    }

    /**
     * 繼續(xù)錄制
     *
     * @return
     */
    public boolean resume() {
        if (mRecorder != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mRecorder.resume();
            return true;
        }
        return false;
    }
}

public CamcorderProfile getBestCamcorderProfile(int cameraID){
		CamcorderProfile profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_LOW);
		if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_480P)){
			//對比下面720 這個選擇 每幀不是很清晰
			profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_480P);
			profile.videoBitRate = profile.videoBitRate/5;
			return profile;
		}
		if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_720P)){
			//對比上面480 這個選擇 動作大時馬賽克!!
			profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_720P);
			profile.videoBitRate = profile.videoBitRate/35;
			return profile;
		}
		if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_CIF)){
			profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_CIF);
			return profile;
		}
		if(CamcorderProfile.hasProfile(cameraID, CamcorderProfile.QUALITY_QVGA)){
			profile = CamcorderProfile.get(cameraID, CamcorderProfile.QUALITY_QVGA);
			return profile;
		}
		return profile;
	}

3.使用示例

public void recordVideo(CustomCameraView CameraView) {
        VideoRecorderConfig config = new VideoRecorderConfig();
        String path = App.sGlobalContext.getExternalFilesDir("video").getAbsolutePath() + File.separator + "test1.mp4";
        config.setCamera(CameraView.getCamera());
        config.setCameraRotation(CameraView.getCameraRotation());
        config.setVideoHeight(CameraView.getCameraSize().height);
        config.setVideoWidth(CameraView.getCameraSize().width);
        config.setPath(path);
        config.setSurfaceTexture(CameraView.getSurfaceTexture());
        config.setCameraId(0);
        VideoRecorder record = new VideoRecorder();
        boolean start = record.startRecord(config, null);
        int duration = 15_000;
        while (duration > 0) {
            if (duration == 10_000) {
                boolean pause = record.pause();
                LogUtils.e(TAG, "暫停錄制" + pause);
            }
            if (duration == 5_000) {
                boolean resume = record.resume();
                LogUtils.e(TAG, "重新開始錄制" + resume);
            }
            SystemClock.sleep(1_000);
            duration -= 1_000;
        }

        record.stopRecord();
        LogUtils.d(TAG, "停止錄制");
    }

其中CustomCameraView為自己封裝的相機(jī)庫

到此這篇關(guān)于Android視頻錄制功能的實現(xiàn)步驟的文章就介紹到這了,更多相關(guān)Android視頻錄制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android中WebView用法實例分析

    Android中WebView用法實例分析

    這篇文章主要介紹了Android中WebView用法,以實例形式較為詳細(xì)的分析了Android中WebView的功能、注意事項與使用技巧,非常具有實用價值,需要的朋友可以參考下
    2015-10-10
  • 詳解Kotlin Android開發(fā)中的環(huán)境配置

    詳解Kotlin Android開發(fā)中的環(huán)境配置

    這篇文章主要介紹了詳解Kotlin Android開發(fā)中的環(huán)境配置的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Android中View的炸裂特效實現(xiàn)方法詳解

    Android中View的炸裂特效實現(xiàn)方法詳解

    這篇文章主要介紹了Android中View的炸裂特效實現(xiàn)方法,涉及Android組件ExplosionField的相關(guān)定義與使用技巧,需要的朋友可以參考下
    2016-07-07
  • 詳解Android的自動化構(gòu)建及發(fā)布

    詳解Android的自動化構(gòu)建及發(fā)布

    本篇文章主要介紹了Android的自動化構(gòu)建及發(fā)布,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • Android協(xié)程的7個重要知識點(diǎn)匯總

    Android協(xié)程的7個重要知識點(diǎn)匯總

    在現(xiàn)代Android應(yīng)用開發(fā)中,協(xié)程(Coroutine)已經(jīng)成為一種不可或缺的技術(shù),它不僅簡化了異步編程,還提供了許多強(qiáng)大的工具和功能,可以在高階場景中發(fā)揮出色的表現(xiàn),本文將深入探討Coroutine重要知識點(diǎn),幫助開發(fā)者更好地利用Coroutine來構(gòu)建高效的Android應(yīng)用
    2023-09-09
  • Android CheckBox中設(shè)置padding無效解決辦法

    Android CheckBox中設(shè)置padding無效解決辦法

    這篇文章主要介紹了Android CheckBox中設(shè)置padding無效解決辦法的相關(guān)資料,希望通過本文能幫助到大家,讓大家解決這樣類似的問題,需要的朋友可以參考下
    2017-10-10
  • Android library native調(diào)試代碼遇到的問題解決

    Android library native調(diào)試代碼遇到的問題解決

    這篇文章主要介紹了Android library native 代碼不能調(diào)試解決方法匯總,android native開發(fā)會碰到native代碼無法調(diào)試問題,而app主工程中的native代碼是可以調(diào)試的
    2023-04-04
  • Android串口通信apk源碼詳解(附完整源碼)

    Android串口通信apk源碼詳解(附完整源碼)

    這篇文章主要介紹了Android串口通信apk源碼詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Gradle的緩存路徑修改的四種方法(小結(jié))

    Gradle的緩存路徑修改的四種方法(小結(jié))

    這篇文章主要介紹了Gradle的緩存路徑修改的四種方法(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • android實現(xiàn)簡單的乘法計算代碼

    android實現(xiàn)簡單的乘法計算代碼

    本文完成輸入2個數(shù)相乘,并顯示其結(jié)果。共涉及到4個控件的使用學(xué)習(xí),輸入數(shù)字采用EditText,顯示結(jié)果用TextView,運(yùn)算按鈕button以及菜單中的退出鍵
    2013-11-11

最新評論

牙克石市| 永善县| 雅安市| 崇文区| 玛纳斯县| 福泉市| 黎川县| 潮州市| 平定县| 平安县| 巩义市| 镇康县| 凤凰县| 房山区| 班玛县| 安宁市| 友谊县| 南投市| 张家口市| 衡阳市| 同心县| 阜城县| 长丰县| 原阳县| 清远市| 田东县| 铜梁县| 莱芜市| 昌乐县| 英山县| 古蔺县| 满洲里市| 酒泉市| 呈贡县| 三明市| 福建省| 邳州市| 集贤县| 城口县| 新疆| 临安市|