Android摄像头录制视频,但播放倒挂 [英] Android Camera recording video but plays upside down

查看:209
本文介绍了Android摄像头录制视频,但播放倒挂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用下面的code录制视频,并完美地记录,但是当它播放视频,小青倒扣。

我试着设置 mrec.setOrientationHint(180) MREC prepare(); ,但它是无用的。任何提示?

 进口的java.io.File;
进口java.io.IOException异常;
进口java.lang.reflect.InvocationTargetException;
进口java.lang.reflect.Method中;

进口android.app.Activity;
进口android.hardware.Camera;
进口android.media.MediaRecorder;
进口android.os.Bundle;
进口android.os.Environment;
进口android.util.Log;
进口android.view.Menu;
进口android.view.MenuItem;
进口android.view.Surface;
进口android.view.SurfaceHolder;
进口android.view.SurfaceView;
进口android.view.Window;

/ **
 * @author SANA HASSAN
 * /
公共类CameraSurfaceView延伸活动{

    私人preVIEW米preVIEW;
    私人MediaRecorder MREC =新MediaRecorder();
    私人诠释cameraId = 0;
    私人相机mCamera;


    @覆盖
    保护无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        米preVIEW =新的preVIEW(本);
        的setContentView(M preVIEW);
    }

    @覆盖
    公共布尔onCreateOptionsMenu(功能菜单){
        menu.add(0,0,0,开始);
        menu.add(0,1,0,停止);
        返回super.onCreateOptionsMenu(菜单);
    }

    @覆盖
    公共布尔onOptionsItemSelected(菜单项项){
        开关(item.getItemId()){
            情况下0:
                尝试 {
                    的StartRecording();
                }
                赶上(例外五){
                    e.printStackTrace();
                    mrec.release();
                }
                打破;

            情况1:
                mrec.stop();
                mrec.release();
                MREC = NULL;
                打破;

            默认:
                打破;
        }
        返回super.onOptionsItemSelected(项目);
    }

    保护无效的startRecording()抛出IOException异常{

        MREC =新MediaRecorder();
        mrec.setCamera(mCamera);
        mCamera.unlock();
        文件目录=新的文件(Environment.getExternalStorageDirectory()+/ NICUVideos);
        directory.mkdirs();
        mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
        mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mrec.setOutputFile(Environment.getExternalStorageDirectory()+"/NICUVideos/"+System.currentTimeMillis()+".mp4");
        mrec.set previewDisplay(M preview.getHolder()getSurface());
        mrec.setVideoSize(640,480);

        方法[]方法= mrec.getClass()的getMethods()。
        对于(方法方法:方法){
            尝试{
                如果(method.getName()。等于(setAudioEncodingBitRate)){
                    method.invoke(MREC,12200);
                }
                否则,如果(method.getName()。等于(setVideoEncodingBitRate)){
                    method.invoke(MREC,800000);
                }
                否则,如果(method.getName()。等于(setAudioSamplingRate)){
                    method.invoke(MREC,8000);
                }
                否则,如果(method.getName()。等于(setVideoFrameRate)){
                    method.invoke(MREC,20);
                }
            }
            赶上(抛出:IllegalArgumentException E){
                e.printStackTrace();
            }
            赶上(IllegalAccessException E){
                e.printStackTrace();
            }
            赶上(的InvocationTargetException E){
                e.printStackTrace();
            }
        }
        mrec.setAudioEn codeR(MediaRecorder.AudioEn coder.AMR_NB);
        mrec.setVideoEn codeR(MediaRecorder.VideoEn coder.MPEG_4_SP);
        mrec.setMaxDuration(60000); //60秒
        mrec.setMaxFileSize(10000000); //大约10兆字节
        MREC prepare()。
        mrec.start();
    }

    保护无效STO precording(){
        mrec.stop();
        mrec.release();
        mCamera.release();
    }

    类preVIEW延伸SurfaceView实现SurfaceHolder.Callback {
        SurfaceHolder mHolder;
        活动活性;

        preVIEW(活动活动){
            超(活动);
            mHolder = getHolder();
            mHolder.addCallback(本);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        公共无效surfaceCreated(SurfaceHolder持有者){

            Camera.CameraInfo信息=新Camera.CameraInfo();
            的for(int i = 0; I< Camera.getNumberOfCameras();我++){
                Camera.getCameraInfo(ⅰ,信息);
                如果(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
                    mCamera = Camera.open(ⅰ);
                    cameraId =我;
                }
            }

            尝试 {
               mCamera.set previewDisplay(保持器);
            }赶上(IOException异常除外){
                mCamera.release();
                mCamera = NULL;
            }
        }

        公共无效surfaceDestroyed(SurfaceHolder持有者){
            mCamera.stop preVIEW();
            mCamera.release();
            mCamera = NULL;
        }

        公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){
            setCameraDisplayOrientation(mCamera);
            mCamera.start preVIEW();
        }

        公共无效setCameraDisplayOrientation(摄像机镜头){
            Camera.CameraInfo信息=新Camera.CameraInfo();
            Camera.getCameraInfo(cameraId,资讯);

            INT旋转= CameraSurfaceView.this.getWindowManager()getDefaultDisplay()getRotation()。
            INT度= 0;
            开关(旋转){
                案例Surface.ROTATION_0:度= 0;打破;
                案例Surface.ROTATION_90:度= 90;打破;
                案例Surface.ROTATION_180:度= 180;打破;
                案例Surface.ROTATION_270:度= 270;打破;
            }

            INT结果;
            如果(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
                结果=(info.orientation +度)%360;
                结果=(360  - 结果)%360; //补偿镜
            }其他{//背向
                结果=(info.orientation  - 度+ 360)%360;
            }
            Log.d(Vars.TAG,结果=+结果);
            camera.setDisplayOrientation(结果);
        }
    }

}
 

解决方案

这个问题是由于Android的处理旋转,只需设置一些元数据,而不是实际旋转的视频,以及一些播放软件则忽略该设置。

作为<一说href="http://developer.android.com/reference/android/media/MediaRecorder.html#setOrientationHint%28int%29">the文档:

  

请注意,某些视频播放器可以选择播放过程中忽略了视频中的compostion矩阵。

您的选择是要么使用能够理解被设置,或重新连接code中的视频后,它被记录到正确的方向中的元数据不同的播放软件。它不是从你的描述中清楚其中哪些是你的情况更好的解决方案。

I record a video using the below code and it records perfectly, but when it plays the video, it plays it upside down.

I tried settings mrec.setOrientationHint(180) before mrec.prepare(); but it was useless. Any hints?

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.app.Activity;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;

/**
 * @author SANA HASSAN
 */
public class CameraSurfaceView extends Activity {

    private Preview mPreview;
    private MediaRecorder mrec = new MediaRecorder();
    private int cameraId = 0;
    private Camera mCamera;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        mPreview = new Preview(this);
        setContentView(mPreview);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(0, 0, 0, "Start");
        menu.add(0, 1, 0, "Stop");
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 0:
                try {
                    startRecording();
                } 
                catch (Exception e) {
                    e.printStackTrace();
                    mrec.release();
                }
                break;

            case 1: 
                mrec.stop();
                mrec.release();
                mrec = null;
                break;

            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    protected void startRecording() throws IOException  {

        mrec = new MediaRecorder();
        mrec.setCamera(mCamera);
        mCamera.unlock();
        File directory = new File(Environment.getExternalStorageDirectory()+"/NICUVideos");
        directory.mkdirs();
        mrec.setAudioSource( MediaRecorder.AudioSource.MIC);
        mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mrec.setOutputFile(Environment.getExternalStorageDirectory()+"/NICUVideos/"+System.currentTimeMillis()+".mp4"); 
        mrec.setPreviewDisplay(mPreview.getHolder().getSurface());
        mrec.setVideoSize(640, 480);

        Method[] methods = mrec.getClass().getMethods();
        for (Method method: methods){
            try{
                if(method.getName().equals("setAudioEncodingBitRate")){
                    method.invoke(mrec, 12200);
                }
                else if(method.getName().equals("setVideoEncodingBitRate")){
                    method.invoke(mrec, 800000);
                }
                else if(method.getName().equals("setAudioSamplingRate")){
                    method.invoke(mrec, 8000);
                }
                else if(method.getName().equals("setVideoFrameRate")){
                    method.invoke(mrec, 20);
                }
            }
            catch (IllegalArgumentException e) {
                e.printStackTrace();
            } 
            catch (IllegalAccessException e) {
                e.printStackTrace();
            } 
            catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mrec.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        mrec.setMaxDuration(60000); // 60 seconds
        mrec.setMaxFileSize(10000000); // Approximately 10 megabytes
        mrec.prepare();
        mrec.start();
    }

    protected void stopRecording() {
        mrec.stop();
        mrec.release();
        mCamera.release();
    }

    class Preview extends SurfaceView implements SurfaceHolder.Callback {
        SurfaceHolder mHolder;
        Activity activity;

        Preview(Activity activity) {
            super(activity);
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        public void surfaceCreated(SurfaceHolder holder) {

            Camera.CameraInfo info=new Camera.CameraInfo();
            for (int i=0; i < Camera.getNumberOfCameras(); i++) {
                Camera.getCameraInfo(i, info);
                if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    mCamera=Camera.open(i);
                    cameraId = i;
                }
            }

            try {
               mCamera.setPreviewDisplay(holder);
            } catch (IOException exception) {
                mCamera.release();
                mCamera = null;
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            setCameraDisplayOrientation(mCamera);
            mCamera.startPreview();
        }

        public void setCameraDisplayOrientation(Camera camera) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(cameraId, info);

            int rotation = CameraSurfaceView.this.getWindowManager().getDefaultDisplay().getRotation();
            int degrees = 0;
            switch (rotation) {
                case Surface.ROTATION_0: degrees = 0; break;
                case Surface.ROTATION_90: degrees = 90; break;
                case Surface.ROTATION_180: degrees = 180; break;
                case Surface.ROTATION_270: degrees = 270; break;
            }

            int result;
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                result = (info.orientation + degrees) % 360;
                result = (360 - result) % 360;  // compensate the mirror
            } else {  // back-facing
                result = (info.orientation - degrees + 360) % 360;
            }
            Log.d(Vars.TAG, "Result = "+result);
            camera.setDisplayOrientation(result);
        }
    }

}

解决方案

This problem is due to Android handling rotation by just setting some metadata instead of actually rotating the video, and some playback software then ignoring that setting.

As noted in the docs:

Note that some video players may choose to ignore the compostion matrix in a video during playback.

Your options are to either use different playback software that understands the metadata being set, or to re-encode the video after it's been recorded to the correct orientation. It's not clear from your description which of those would be the better solution in your case.

这篇关于Android摄像头录制视频,但播放倒挂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆