Android不预览录视频

不用预览,录制固定时间的视频

activity 

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /** 开始摄像 **/
                startService(new Intent(MainActivity.this, VideoSerivice.class));
            }
        });

        findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.e("Service", "stopService");
                /** * 启动定时器,到规定时间recordTime后执行停止录像任务 */
                Intent intents = new Intent();
                intents.setAction("com.example.testvideo.VideoService");
            }
        });
    }
}



service

public class VideoSerivice extends Service implements
        SurfaceHolder.Callback {

    private SurfaceView surfaceview;// 视频预览控件
    private LinearLayout lay; // 愿揽控件的
    private SurfaceHolder surfaceHolder; // //和surfaceView相关的
    private Context context;
    private boolean isRecorder = false;
    WindowManager wm;
    LinearLayout relLay;
    CramerThread thread;

    /**
     * 检测摄像头硬件 如果应用程序未使用manifest声明对摄像头需求进行特别指明,则应该在运行时检查一下摄像头是否可用
     */
    public boolean checkCameraHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA)) {
            return true;
        }
        return false;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("","onCreate");
        if (!checkCameraHardware(this)) {
            Toast.makeText(this, "摄像头被占用或不存在", Toast.LENGTH_LONG).show();
            return;
        }
        // 设置悬浮窗体属性
        // 1.得到WindoeManager对象:
        wm = (WindowManager) getApplicationContext().getSystemService("window");
        // 2.得到WindowManager.LayoutParams对象,为后续设置相关参数做准备:
        WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
        // 3.设置相关的窗口布局参数,要实现悬浮窗口效果,要需要设置的参数有
        // 3.1设置window type
        wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        // 3.2设置图片格式,效果为背景透明 //wmParams.format = PixelFormat.RGBA_8888;
        wmParams.format = 1;
        // 下面的flags属性的效果形同“锁定”。 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。
        wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        // 4.// 设置悬浮窗口长宽数据
        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        // 5. 调整悬浮窗口至中间
        wmParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER;
        // 6. 以屏幕左上角为原点,设置x、y初始值
        wmParams.x = 0;
        wmParams.y = 0;
        // 7.将需要加到悬浮窗口中的View加入到窗口中了:
        // 如果view没有被加入到某个父组件中,则加入WindowManager中
        surfaceview = new SurfaceView(this);
        surfaceHolder = surfaceview.getHolder();
        WindowManager.LayoutParams params_sur = new WindowManager.LayoutParams();
        params_sur.width = 1;
        params_sur.height = 1;
        params_sur.alpha = 255;
        surfaceview.setLayoutParams(params_sur);

        surfaceview.getHolder()
                .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        // surface.getHolder().setFixedSize(800, 1024);
        surfaceview.getHolder().addCallback((SurfaceHolder.Callback) this);

        relLay = new LinearLayout(this);
        WindowManager.LayoutParams params_rel = new WindowManager.LayoutParams();
        params_rel.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params_rel.height = WindowManager.LayoutParams.WRAP_CONTENT;
        relLay.setLayoutParams(params_rel);
        relLay.addView(surfaceview);
        wm.addView(relLay, wmParams); // 创建View


    }


    @Override
    public void surfaceChanged(SurfaceHolder holder, int arg1, int arg2,
                               int arg3) {
        System.out.println("*****");

        // 将holder,这个holder为开始在oncreat里面取得的holder,将它赋给surfaceHolder
        surfaceHolder = holder;

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        System.out.println("++++++");

        // 将holder,这个holder为开始在oncreat里面取得的holder,将它赋给surfaceHolder
        surfaceHolder = holder;
        Log.i("process", Thread.currentThread().getName());
        // //录像线程,当然也可以在别的地方启动,但是一定要在onCreate方法执行完成以及surfaceHolder被赋值以后启动
        thread = new CramerThread(50000, surfaceview,
                surfaceHolder);// 设置录制时间为2小时
        thread.start();
        Toast.makeText(VideoSerivice.this, "开始录像", Toast.LENGTH_LONG).show();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        System.out.println("*****");
        // surfaceDestroyed的时候同时对象设置为null
        surfaceview = null;
        surfaceHolder = null;
    }



    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

public class CramerThread extends Thread {
	private MediaRecorder mediarecorder;// 录制视频的类private long
	private SurfaceHolder surfaceHolder;
	private SurfaceView surfaceview;// 显示视频的控件
	private Camera mCamera;
	private long recordTime;
	private long startTime = Long.MIN_VALUE;
	private long endTime = Long.MIN_VALUE;
	private HashMap<String, String> map = new HashMap<String, String>();
	private static final String TAG = "SEDs508EG";
	public static final int MEDIA_TYPE_IMAGE = 1;
	public static final int MEDIA_TYPE_VIDEO = 2;



	public CramerThread(long recordTime, SurfaceView surfaceview,
						SurfaceHolder surfaceHolder) {
		this.recordTime = recordTime;
		this.surfaceview = surfaceview;
		this.surfaceHolder = surfaceHolder;
	}

	@Override
	public void run() {
		/** * 开始录像 */
		startRecord();
		/** * 启动定时器,到规定时间recordTime后执行停止录像任务 */
		Timer timer = new Timer();
		timer.schedule(new TimerThread(), recordTime);

	}

	/** * 获取摄像头实例对象 * * @return */
	public Camera getCameraInstance() {
		Camera c = null;
		try {
			c = Camera.open();
		} catch (Exception e) {
			// 打开摄像头错误
			Log.i("info", "打开摄像头错误");
		}
		return c;
	}

	/** * 开始录像 */
	public void startRecord() {
		mediarecorder = new MediaRecorder();// 创建mediarecorder对象
		mCamera = getCameraInstance(); // 解锁camera
		mCamera.unlock();
		mediarecorder.setCamera(mCamera); // 设置录制视频源为Camera(相机)
		mediarecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
		mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 设置录制文件质量,格式,分辨率之类,这个全部包括了
		mediarecorder.setProfile(CamcorderProfile
				.get(CamcorderProfile.QUALITY_LOW));
		mediarecorder.setPreviewDisplay(surfaceHolder.getSurface()); // 设置视频文件输出的路径
		// mediarecorder.setOutputFile("/sdcard/sForm.3gp");
		mediarecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO)
				.toString());
		try { // 准备录制
			mediarecorder.prepare(); // 开始录制
			mediarecorder.start();
			// time.setVisibility(View.VISIBLE);// 设置录制时间显示
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void releaseMediaRecorder() {
		if (mediarecorder != null) {
			// 清除recorder配置
			mediarecorder.reset();
			// 释放recorder对象
			mediarecorder.release();
			mediarecorder = null;
			// 为后续使用锁定摄像头
			mCamera.lock();
		}
	}


	/** * 停止录制 */
	public void stopRecord() {
		System.out.println("--------------");

		if (mediarecorder != null) {
			// 停止录制
			mediarecorder.stop();
			// 释放资源
			mediarecorder.release();
			mediarecorder = null;
			if (mCamera != null) {
				mCamera.release();
				mCamera = null;
			}
		}
	}


	/** * 定时器 * @author bcaiw * */
	public class TimerThread extends TimerTask {
		/** * 停止录像 */
		@Override
		public void run() {
			try {
				stopRecord();
				this.cancel();
			} catch (Exception e) {
				map.clear();
				map.put("recordingFlag", "false");
				String ac_time = getVedioRecordTime();// 录像时间
				map.put("recordTime", ac_time);
				// sendMsgToHandle(m_msgHandler, iType, map);
			}

		}
	}

	/**
	 * 通用方法,接收多线程过来的数据,有可能不仅仅是msg,所以定义map对象
	 *
	 * @param handle
	 * @param iType
	 * @param info
	 */
	public void sendMsgToHandle(Handler handle, int iType,
								Map<String, String> info) {
		Message threadMsg = handle.obtainMessage();
		threadMsg.what = iType;
		Bundle threadbundle = new Bundle();
		threadbundle.clear();
		for (Iterator i = info.keySet().iterator(); i.hasNext();) {
			Object obj = i.next();
			threadbundle.putString(obj.toString(), info.get(obj));
		}
		threadMsg.setData(threadbundle);
		handle.sendMessage(threadMsg);

	}

	/**
	 * 计算当前已录像时间,默认值返回0
	 *
	 * @return
	 */
	public String getVedioRecordTime() {
		String result = "0";
		if (startTime != Long.MIN_VALUE && endTime != Long.MIN_VALUE) {
			long tempTime = (endTime - startTime);
			result = String.valueOf(tempTime);
		}
		return result;

	}

	private static File getOutputMediaFile(int type) {
		// 判断SDCard是否存在
		if (!Environment.MEDIA_MOUNTED.equals(Environment
				.getExternalStorageState())) {
			Log.d(TAG, "SDCard不存在");
			return null;
		}

		File mediaStorageDir = new File(
				Environment.getExternalStorageDirectory() + File.separator
						+ "/MyXingCheCamera3GP/");
		if (!mediaStorageDir.exists()) {
			if (!mediaStorageDir.mkdir()) {
				Log.d(TAG, "failed to create directory");
				return null;
			}
		}
		// 创建媒体文件名
		String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
				.format(new Date());
		File mediaFile;
		if (type == MEDIA_TYPE_IMAGE) {
			mediaFile = new File(mediaStorageDir.getPath() + File.separator
					+ "IMG_" + timestamp + ".jpg");
		} else if (type == MEDIA_TYPE_VIDEO) {
			mediaFile = new File(mediaStorageDir.getPath() + File.separator
					+ "VID_" + timestamp + ".3gp");
		} else {
			Log.d(TAG, "文件类型有误");
			return null;
		}

		return mediaFile;
	}
}


AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.videotest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".VideoSerivice"/>
    </application>
    <!-- 录制视频/音频权限 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
    <!-- 调用摄像头权限 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- sd卡读写权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
    <!-- 挂载sd卡 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <!-- 悬浮窗口权限 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <!-- 关闭应用程序的权限 -->
    <uses-permission android:name="android.permission.RESTART_PACKAGES" />
</manifest>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值