在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Java  C  Android  影視/ 安卓拍攝視頻如何全屏適配?

安卓拍攝視頻如何全屏適配?

1,最近遇到個問題,用camera錄制的視頻,在拍攝預覽過程中是全屏的,到文件管理器中播放就不是的了,會比拍攝時看到的寬一些,困擾了很久,不知道怎么解決,懇請大佬指點一下?

2,代碼:

public class MainActivity extends AppCompatActivity {

    private SurfaceView surfaceview;
    private MediaRecorder mr;
    private Button bt_start;
    private Button bt_stop;
    private boolean isRecording = false;
    private Camera mCamera;
    private int width;
    private int height;
    private Camera.Size previewSize;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        surfaceview = (SurfaceView) findViewById(R.id.surfaceview);

        bt_start = (Button) findViewById(R.id.bt_start);
        bt_stop = (Button) findViewById(R.id.bt_stop);
        WindowManager wm = (WindowManager) this
                .getSystemService(Context.WINDOW_SERVICE);
        width = wm.getDefaultDisplay().getWidth();
        height = wm.getDefaultDisplay().getHeight();
        SurfaceHolder holder = surfaceview.getHolder();
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        holder.setFixedSize(width, height);
        surfaceview.setKeepScreenOn(true);
    }

    public void start(View v){
        //實際的權(quán)限申請不應該這么寫
        new RxPermissions(this)
                .request(Manifest.permission.CAMERA,
                        Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT,
                        Manifest.permission.RECORD_AUDIO,
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if(aBoolean){
                            Toast.makeText(MainActivity.this,"已授權(quán)",Toast.LENGTH_SHORT).show();
                        }else {
                            Toast.makeText(MainActivity.this,"未授權(quán)",Toast.LENGTH_SHORT).show();
                        }
                    }
                });
        try {
            mCamera = Camera.open();
            Camera.Parameters parameters = mCamera.getParameters();
            mCamera.setDisplayOrientation(90);
            mCamera.setPreviewDisplay(surfaceview.getHolder());
            mCamera.startPreview();
            List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();

            if (mSupportedPreviewSizes != null) {
                previewSize = getOptimalPreviewSize(mSupportedPreviewSizes,
                        Math.max(width, height), Math.min(width, height));
            }
            Camera.Parameters mParams = mCamera.getParameters();
            mParams.setPreviewSize(previewSize.width, previewSize.height);
//            mCamera.setDisplayOrientation(90);
            List<String> focusModes = mParams.getSupportedFocusModes();
            if(focusModes.contains("continuous-video")){
                mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            }
            mCamera.setParameters(mParams);

            mCamera.unlock();

            mr = new MediaRecorder();
            mr.setCamera(mCamera);
            mr.reset();



            mr.setPreviewDisplay(surfaceview.getHolder().getSurface());
            mr.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 視頻源
            mr.setAudioSource(MediaRecorder.AudioSource.MIC);// 音頻源
            mr.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 視頻輸出格式
            mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 音頻格式
            mr.setVideoSize(previewSize.width,previewSize.height);
            mr.setVideoFrameRate(30);
            mr.setVideoEncodingBitRate(3*1024*1024);// 設(shè)置幀頻率,然后就清晰了
            mr.setOrientationHint(90);// 輸出旋轉(zhuǎn)90度,保持豎屏錄制
            mr.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);// 視頻錄制格式
            File file = new File(Environment.getExternalStorageDirectory(),"zz"+System.currentTimeMillis()+".mp4");
            mr.setOutputFile(file.getAbsolutePath());
            mr.setOnErrorListener(new MediaRecorder.OnErrorListener() {
                @Override
                public void onError(MediaRecorder mr, int what, int extra) {
                    isRecording = false;
                    mr.stop();
                    mr.release();
                    mr = null;
                    isRecording = false;
                    bt_start.setEnabled(true);
                    bt_stop.setEnabled(false);
                    Toast.makeText(MainActivity.this,"錄制出錯!",Toast.LENGTH_SHORT).show();
                }
            });
            //設(shè)置預覽顯示
            mr.setPreviewDisplay(surfaceview.getHolder().getSurface());
            mr.prepare();
            mr.start();
            bt_start.setEnabled(false);
            bt_stop.setEnabled(true);
            Toast.makeText(MainActivity.this,"錄制開始!",Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            //TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public void stop(View v){
        mr.stop();
        bt_start.setEnabled(true);
        bt_stop.setEnabled(false);
    }

    @Override
    protected void onDestroy() {
        //TODO Auto-generated method stub
        super.onDestroy();

        if(mr!= null){
            mr.release();
            mr = null;
        }
    }

    public Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null) {
            return null;
        }
        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        int targetHeight = h;
        for (Camera.Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }


}

3,圖片:

拍攝圖:
    

clipboard.png

在文件夾中播放的圖:
    

clipboard.png

4,會看到實際上的圖片會寬一些,應該怎么解決這個問題,想做成全屏的。

回答
編輯回答
傻丟丟

getOptimalPreviewSize 的第一個參數(shù)是硬件所支持的尺寸列表,后面長寬是你想要顯示的UI尺寸。
所以預覽的圖片顯示是經(jīng)過修正的,并不是攝像頭看到的實際尺寸。
個人想法
方案1.只是用完全匹配的尺寸,即UI尺寸和硬件尺寸相同比例的size (不太好,特別是低檔機的硬件支持數(shù)少,會很模糊)
方案2.拿到拍攝后的圖后修圖。不直接用系統(tǒng)相機生成的圖,用工具類裁剪后保存。

2017年11月16日 17:17
編輯回答
心沉

也就是預覽和實際不相同,你獲取屏幕的寬和高的方法可能存在一定的差距,我沒記錯的話這個數(shù)值和實際有所出入。
不過我自己也沒嘗試過是否因為這個原因,可以參考https://blog.csdn.net/gh86091...

看是否有所幫助

2017年5月30日 10:18