关于android 视频录制,视频清晰度问题..求解

zgysuper 2012-09-21 01:28:31
主程序:

package com.demo01;
/**
* 视频录制
*/

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
private SurfaceView surfaceView;
private Button luXiang_bt;
private Button tingZhi_bt;
private TextView time_tv; //显示时间的文本框
private MediaRecorder mRecorder;
private boolean recording; // 记录是否正在录像,fasle为未录像, true 为正在录像
private File videoFolder; // 存放视频的文件夹
private File videFile; // 视频文件
private Handler handler;
private int time; // 时间
private Camera myCamera; // 相机声明
private SurfaceHolder holder;
/**
* 录制过程中,时间变化
*/
private Runnable timeRun = new Runnable() {

@Override
public void run() {
time++;
time_tv.setText(time + "秒");
handler.postDelayed(timeRun, 1000);
}
};


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 强制横屏
setContentView(R.layout.main);

//获取控件
surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
luXiang_bt = (Button) findViewById(R.id.luXiang_bt);
tingZhi_bt = (Button) findViewById(R.id.tingZhi_bt);
time_tv = (TextView) findViewById(R.id.time);

handler = new Handler();
holder = surfaceView.getHolder();

// 判断sd卡是否存在
boolean sdCardExist = Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
System.out.println("sdCard存在: " + sdCardExist);

if (sdCardExist) {
// 设定存放视频的文件夹的路径
String path = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator
+ "VideoFolder"
+ File.separator;

// 声明存放视频的文件夹的File对象
videoFolder = new File(path);

// 如果不存在此文件夹,则创建
if (!videoFolder.exists()) {
videoFolder.mkdirs();
}

// 设置surfaceView不管理的缓冲区
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// 设置surfaceView分辨率
surfaceView.getHolder().setFixedSize(800, 480);

// 录像点击事件
luXiang_bt.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
if (!recording) {
try {
// 关闭预览并释放资源
myCamera.stopPreview();
myCamera.release();
myCamera = null;

mRecorder = new MediaRecorder();
// 获取当前时间,作为视频文件的文件名
String nowTime = java.text.MessageFormat.format(
"{0,date,yyyyMMdd_HHmmss}",
new Object[] {new java.sql.Date(System.currentTimeMillis())});
// 声明视频文件对象
videFile = new File(videoFolder.getAbsoluteFile()
+ File.separator + "video" + nowTime + ".mp4");
// 创建此视频文件
videFile.createNewFile();
System.out.println("视频文件: " + videFile.getAbsolutePath());

mRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface()); // 预览
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 视频源
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 录音源为麦克风
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 输出格式为mp4
/* 引用android.util.DisplayMetrics 获取分辨率 */
// DisplayMetrics dm = new DisplayMetrics();
// getWindowManager().getDefaultDisplay().getMetrics(dm);
mRecorder.setVideoSize(800, 480); // 视频尺寸
mRecorder.setVideoFrameRate(30); // 视频帧频率
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); // 视频编码
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 音频编码
mRecorder.setMaxDuration(1800000);
mRecorder.setOutputFile(videFile.getAbsolutePath());
mRecorder.prepare(); // 准备录像
mRecorder.start(); // 开始录像
time_tv.setVisibility(View.VISIBLE); // 设置文本框可见
handler.post(timeRun); // 调用Runable
recording = true; // 改变录制状态为正在录制
} catch (IOException e1) {
e1.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
else
Toast.makeText(MainActivity.this, "视频正在录制中...", Toast.LENGTH_LONG).show();
}

});
}
else
Toast.makeText(this, "未找到sdCard!", Toast.LENGTH_LONG).show();


// 停止点击事件
tingZhi_bt.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
if (recording) {
mRecorder.stop();
mRecorder.release();
handler.removeCallbacks(timeRun);
time_tv.setVisibility(View.GONE);
int videoTimeLength = time;
time = 0;
recording = false;
Toast.makeText(MainActivity.this,
videFile.getAbsolutePath() + " " + videoTimeLength + "秒",
Toast.LENGTH_LONG).show();
}
// 开启相机
if (myCamera == null) {
myCamera = Camera.open();
try {
myCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
}
myCamera.startPreview(); // 开启预览
}
});

// 添加回调
holder.addCallback(new SurfaceHolder.Callback() {

@Override
public void surfaceCreated(SurfaceHolder holder) {
System.out.println("------surfaceCreated------");
// 开启相机
if (myCamera == null) {
myCamera = Camera.open();
try {
myCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
}

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
System.out.println("------surfaceChanged------");
// 开始预览
myCamera.startPreview();

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("------surfaceDestroyed------");
// 关闭预览并释放资源
if (myCamera != null) {
myCamera.stopPreview();
myCamera.release();
myCamera = null;
}
}
});

}

@Override
protected void onDestroy() {
handler.removeCallbacks(timeRun);
if (mRecorder != null) {
mRecorder.release();
}
if (myCamera != null) {
myCamera.stopPreview();
myCamera.release();
}
super.onDestroy();
}

}


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo01"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >
<activity
android:name=".MainActivity"
android:label="视频录制DEMO" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


布局文件:main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff" >

<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>

<Button
android:id="@+id/tingZhi_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:text="停止"/>


<Button
android:id="@+id/luXiang_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@id/tingZhi_bt"
android:text="录像"/>

<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF0000"
android:text="1秒"
android:visibility="gone"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"/>

</RelativeLayout>

//-------------------------------------------------------
这样录制出来的视频,其码率只有不到100的码率.视频很模糊
而调动系统录像程序,录制出来的视频,码率有将近3000的码率,非常清晰
想请教各位达人,,,该如何改进呢..???
...全文
3172 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
g794071757 2014-04-14
  • 打赏
  • 举报
回复
引用 9 楼 laizhongmin 的回复:
设置属性在API 8以上只需要setProfile,outputformat/encoder等不用设置了,我改成这样之后视频清晰度和大小就和系统的录制视频一样了
果然这样清晰了很多了,谢谢指点。
xun-ming 2014-04-04
  • 打赏
  • 举报
回复
 mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
只是多了这段代码,而且还使用的都是系统默认的格式
yx1234500000 2014-03-18
  • 打赏
  • 举报
回复
引用 9 楼 laizhongmin 的回复:
mMediaRecorder
							.setVideoSource(MediaRecorder.VideoSource.CAMERA);
					mMediaRecorder
							.setAudioSource(MediaRecorder.AudioSource.MIC);
					
//					mMediaRecorder
//							.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//					mMediaRecorder
//							.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//					mMediaRecorder
//							.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//					mMediaRecorder.setVideoSize(1920, 1020);
//					mMediaRecorder.setVideoFrameRate(15);//现象:在2.3上正常,4.0上报错,原因:每秒12-15帧之间足以表示运动,电视是30
					
					
					mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
					mMediaRecorder.setPreviewDisplay(mSurfaceHolder
							.getSurface());
					String videoOutPath = Environment.getExternalStorageDirectory()
							+ "/DCIM/"
							+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".3gp";
					mMediaRecorder.setOutputFile(videoOutPath);
设置属性在API 8以上只需要setProfile,outputformat/encoder等不用设置了,我改成这样之后视频清晰度和大小就和系统的录制视频一样了
我使用九楼的答案,录制的视频花屏,是什么个情况?楼主知道不?
laizhongmin 2014-02-26
  • 打赏
  • 举报
回复
mMediaRecorder
							.setVideoSource(MediaRecorder.VideoSource.CAMERA);
					mMediaRecorder
							.setAudioSource(MediaRecorder.AudioSource.MIC);
					
//					mMediaRecorder
//							.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//					mMediaRecorder
//							.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//					mMediaRecorder
//							.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//					mMediaRecorder.setVideoSize(1920, 1020);
//					mMediaRecorder.setVideoFrameRate(15);//现象:在2.3上正常,4.0上报错,原因:每秒12-15帧之间足以表示运动,电视是30
					
					
					mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
					mMediaRecorder.setPreviewDisplay(mSurfaceHolder
							.getSurface());
					String videoOutPath = Environment.getExternalStorageDirectory()
							+ "/DCIM/"
							+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".3gp";
					mMediaRecorder.setOutputFile(videoOutPath);
设置属性在API 8以上只需要setProfile,outputformat/encoder等不用设置了,我改成这样之后视频清晰度和大小就和系统的录制视频一样了
laizhongmin 2014-02-25
  • 打赏
  • 举报
回复
同样遇到了这个问题,把很多参数都改大了,但是测试之后,发现几个视频的大小还是差不多,和系统自带的录像清晰度差好多的
yong7356 2013-09-29
  • 打赏
  • 举报
回复
学习了,最后怎么解决的这个清晰率问题和压缩率问题的????
zgysuper 2012-09-22
  • 打赏
  • 举报
回复
咋没人回答呀...
我好郁闷呀
zgysuper 2012-09-22
  • 打赏
  • 举报
回复
哎...我好郁闷呀

4楼的兄弟,把你以前的拿来看下咯,,我蛋疼..啊!!!!!!!!!!!!!!!!
ameyume 2012-09-22
  • 打赏
  • 举报
回复
分辨率太大了?
另外,设置的帧率,码率等其实一般都达不到,只是最大值能达到。

我以前也差不多这样写的,录制出来和系统自带的图库录像质量差不多啊。
aq173873757 2012-09-22
  • 打赏
  • 举报
回复
e嗯嗯 还不错 楼主辛苦了
zgysuper 2012-09-21
  • 打赏
  • 举报
回复
我自己顶....-.-

80,350

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧