现在的位置: 首页 > 综合 > 正文

智能电视TV开发—录像

2018年02月16日 ⁄ 综合 ⁄ 共 7782字 ⁄ 字号 评论关闭

现在社交类程序很火,里面基本包含定位,IM,微视频,在智能电视TV的客户端也会提供录像功能,然后可以传送给智能电视播放,下面我们通过一个实例实现具备录像功能。

由于手机很多都是定制系统,所以当我们设置摄像头参数的时候,提示设置失败,我试了两款手机,有的手机有问题,有的正常,所以再设置参数的地方加了try来捕获。

首先看一下布局界面:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <com.jwzhangjie.smarttv_client.media.Video.SmartVideoSurfaceView
                android:id="@+id/surface_camera"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
            />

           <com.jwzhangjie.smarttv_client.widget.TVChronometer
               android:id="@+id/video_show_time"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_margin="10dip"
               />
        </RelativeLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1" >

        <Button
            android:id="@+id/play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开始" />
    </LinearLayout>

</LinearLayout>

里面有两个封装的类,对应如下的代码:

package com.jwzhangjie.smarttv_client.media.Video;

import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class SmartVideoSurfaceView extends SurfaceView implements Callback{
	private SurfaceHolder mHolder;
	private Camera mCamera;
	private boolean previewRunning = false;
	
	public SmartVideoSurfaceView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initConfig();
	}
	private void initConfig(){
		mHolder = this.getHolder();
		mHolder.addCallback(this);
	}
	public Camera getVideoCamera(){
		return mCamera;
	}
	public SurfaceHolder getMyHolder(){
		return mHolder;
	}
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		try {
			mCamera = Camera.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		if (mCamera != null) {
			if (previewRunning) {
				mCamera.stopPreview();
			}
			try {
				Camera.Parameters params = mCamera.getParameters();
				params.setPreviewSize(width, height);
				params.setPreviewFormat(ImageFormat.JPEG);
				mCamera.setParameters(params);
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				try {
					mCamera.setPreviewDisplay(mHolder);
					mCamera.startPreview();
					previewRunning = true;
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		if (mCamera != null) {
			mCamera.stopPreview();
			previewRunning = false;
			mCamera.release();	
		}
	}

}

这个是重写了SurfaceView

package com.jwzhangjie.smarttv_client.widget;

import com.jwzhangjie.smarttv_client.R;

import android.content.Context;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.Chronometer;
import android.widget.Chronometer.OnChronometerTickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class TVChronometer extends LinearLayout implements OnChronometerTickListener{

	private ImageView video_red;
	private Chronometer video_show_time;
	private boolean show = false;
	public TVChronometer(Context context) {
		super(context);
		init();
	}

	public TVChronometer(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	public void init(){
		setOrientation(HORIZONTAL);
		setGravity(Gravity.CENTER_VERTICAL);
		video_red = new ImageView(getContext());
		video_red.setImageResource(R.drawable.video_record_1);
		LinearLayout.LayoutParams redParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		redParams.setMargins(0, 8, 8, 8);
		addView(video_red, redParams);
		
		video_show_time = new Chronometer(getContext());
		video_show_time.setOnChronometerTickListener(this);
		addView(video_show_time);
		setVisibility(View.INVISIBLE);
	}

	public void start(){
		setVisibility(View.VISIBLE);
		video_show_time.setBase(SystemClock.elapsedRealtime());
		video_show_time.start();
	}
	
	public void stop(){
		setVisibility(View.INVISIBLE);
		video_show_time.stop();
	}

	@Override
	public void onChronometerTick(Chronometer chronometer) {
		if (show) {
			video_red.setImageResource(R.drawable.video_record_1);
		}else {
			video_red.setImageResource(R.drawable.video_record_2);
		}
		show = !show;
	}
	
}

这个是用来显示录像的时候,时间显示和红点闪烁

主界面代码如下:

package com.jwzhangjie.smarttv_client.media;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.jwzhangjie.smarttv_client.R;
import com.jwzhangjie.smarttv_client.media.Video.SmartVideoSurfaceView;
import com.jwzhangjie.smarttv_client.media.Video.VideoRecorder;
import com.jwzhangjie.smarttv_client.ui.base.BaseActivity;
import com.jwzhangjie.smarttv_client.widget.TVChronometer;

public class SmartCamera extends BaseActivity implements OnClickListener{

	private SmartVideoSurfaceView mSurfaceView;
	private TVChronometer video_show_time;
	private VideoRecorder mRecorder;
	private Button play;
	private boolean isRecording = false;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_camera_video);
		initView();
		initSurfaceConfig();
		initListener();
	}
	
	private void initView(){
		mSurfaceView = (SmartVideoSurfaceView)findViewById(R.id.surface_camera);
		play = (Button)findViewById(R.id.play);
		video_show_time = (TVChronometer)findViewById(R.id.video_show_time);
		
	}
	
	private void initListener(){
		play.setOnClickListener(this);
	}
	
	private void initSurfaceConfig(){
		mRecorder = new VideoRecorder();
		mRecorder.init(mSurfaceView, "/mnt/sdcard/", "test.mp4");
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.play:
			if (!isRecording) {
				play.setText("停止");
				mRecorder.startRecording();
				video_show_time.start();
			}else {
				play.setText("开始");
				mRecorder.stopRecording();
				video_show_time.stop();
			}
			isRecording = !isRecording;
			break;
		}
	}
	
}

里面有一个封装MediaRecoder的类,代码如下:

package com.jwzhangjie.smarttv_client.media.Video;

import java.io.File;

import android.media.MediaRecorder;
import android.os.AsyncTask;

public class VideoRecorder extends MediaRecorder{
	private SmartVideoSurfaceView mSurfaceView;
	private boolean preView = false;
	private int videoFramesPerSecond = 20;
	private String fileDir;
	private String fileName;
	private File videoFile;
	public VideoRecorder(){
		
	}
	
	public void setCamera(SmartVideoSurfaceView mSurfaceView){
		this.mSurfaceView = mSurfaceView;
	}
	
	public void setVideoFile(String fileDir, String fileName){
		this.fileDir = fileDir;
		this.fileName = fileName;
	}
	
	public void init(SmartVideoSurfaceView mSurfaceView,String fileDir, String fileName ){
		this.mSurfaceView = mSurfaceView;
		this.fileDir = fileDir;
		this.fileName = fileName;
	}
	
	public void setVideoFrameRaido(int videoFramesPerSecond){
		this.videoFramesPerSecond = videoFramesPerSecond;
	}
	
	public boolean startRecording(){
		new VideoAysn().execute(1);
		return preView;
	}
	
	private class VideoAysn extends AsyncTask<Integer, Void, Void>{
		
		@Override
		protected Void doInBackground(Integer... params) {
			try {
				if (params[0] == 1) {
					preView = false;
					mSurfaceView.getVideoCamera().unlock();
					setCamera(mSurfaceView.getVideoCamera());
					setAudioSource(MediaRecorder.AudioSource.MIC);
					setVideoSource(MediaRecorder.VideoSource.CAMERA);
					setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
					videoFile = new File(fileDir, fileName);
					if (videoFile.exists()) {
						videoFile.delete();
					}
					setOutputFile(videoFile.getPath());
					setVideoFrameRate(videoFramesPerSecond);
					//设置这个参数会导致java.lang.RuntimeException: start failed.
//					setVideoSize(mSurfaceView.getWidth(), mSurfaceView.getHeight());
					setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
					setVideoEncoder(MediaRecorder.VideoEncoder.H264);
					
					setPreviewDisplay(mSurfaceView.getMyHolder().getSurface());
					prepare();
					start();
					preView = true;
				}else {
					if (preView) {
						stop();
						mSurfaceView.getVideoCamera().lock();
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				preView = false;
			}
			return null;
		}
		
	}
	public void stopRecording(){
		new VideoAysn().execute(2);
	}
}

运行效果如下:

我测试了一下录像文件音视频正常,还有就是权限自己不要忘记加了。

抱歉!评论已关闭.