您的位置:首页 > 其它

SoundPool(播放小音频),MediaRecorder(录音),视频播放,开启摄像头

2015-09-15 21:23 253 查看

SoundPool

SoundPool是播放一些小的音频文件,这些文件因为比较小所以会将其完全加载到内存中然会再播放, MediaPlayer由于是播放比较大的文件,所以会边加载边播放。
一般在res中新建一个文件夹(raw)必须是这个名称。然会就可以用SoundPool调用这个文件进行播放了。代码如下:


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
soundpool_button= (Button) findViewById(R.id.soundPool_button);
soundpool_stop_button= (Button) findViewById(R.id.soundPool_Stop_button);
soundpool_stop_button.setOnClickListener(this);
soundpool_button.setOnClickListener(this);
id= iniPlay();
}
int a;
private SoundPool pool=null;
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.soundPool_button:
//public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
//soundID   a soundID returned by the load() function
// leftVolume    left volume value (range = 0.0 to 1.0)
// rightVolume   right volume value (range = 0.0 to 1.0)
//priority  stream priority (0 = lowest priority)
//loop  loop mode (0 = no loop, -1 = loop forever)
// rate  playback rate (1.0 = normal playback, range 0.5 to 2.0)
a= pool.play(id, 1,1,0,-1,1);
break;
case R.id.soundPool_Stop_button:
pool.stop(a);
break;
}
}

private int iniPlay() {

if(Build.VERSION.SDK_INT>=21){
//SDK在21即以上版本的用法
SoundPool.Builder builder = new SoundPool.Builder();
builder.setMaxStreams(2);
AudioAttributes.Builder attrBuilder= new AudioAttributes.Builder();
attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(attrBuilder.build());
pool= builder.build();

}else {
//public SoundPool(int maxStream, int streamType, int srcQuality)
// maxStream —— 同时播放的流的最大数量
// streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
// srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值
pool=new SoundPool(2, AudioManager.STREAM_MUSIC,0);
}
int id= pool.load(getApplicationContext(), R.raw.outgoing,1);
return id;
}


SDK在21之前直接用new SoundPool()去建立pool,21(包括21)之后会先建立一个builder,然后再进行一系列的操作再建立pool,所以在代码中会先判断SDK的版本号,根据不同的版本号进行不同的操作。具体的代码内容注释已经讲的比较清楚了,这里不再赘余。

注意:在load后不可以立刻play,因为load需要时间,所以将两者分开,初始化在oncreat中

MediaRecorder

MediaRecorder既录音也可以录视频,这里先讲录音。

首先建立一个MediaRecorder的对象,然后设置音频来源(一般是麦克风)、设置音频的格式(一般是THREE_GPP)、设置编码格式(一般为AMR_NB)、设置生成文件的地址和文件名(注意有‘/’和后缀名)。代码如下:

myRecorder=new MediaRecorder();
//设置声音的来源
myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置音频的格式
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//设置编码格式
myRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//设置生成文件的地址
myRecorder.setOutputFile(Environment.getExternalStorageDirectory()+"/Music/myRecord.MP3");

try {
//准备录音
myRecorder.prepare();
//开始录音
myRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}


若想停止调用一下代码进行释放资源:

//停止录音
myRecorder.stop();

myRecorder.reset();
//释放资源
myRecorder.release();


视频播放

VideoView

VideoView播放视频比较简单,

VideoView是一个控件,必须在XML中建立,如下:

<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>


在代码中:

myVideoView.setVideoPath(Environment.getExternalStorageDirectory()+"/Movies/pp.mp4");
myVideoView.setMediaController(new MediaController(MyRecorder.this));
myVideoView.start();


上面的代码是播放Movies文件夹下pp.mp4文件。这个控件自动会带播放和停止按钮。

SurfaceView

SurfaceView也可以播放视频,这个控件在播放视频的时候不会受到UI主线程的控制,而是利用MediaPlayer在控件中播放视频。MediaPlayer的对象配置完各个参数后,调用 player.setDisplay(surfaceView.getHolder());就可以在SurfaceView控件中播放视频了。完整的代码如下:

if(player==null){
player = new MediaPlayer();
}
player.reset();
try {
player.setDataSource(Environment.getExternalStorageDirectory()+"/pp.mp4");
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDisplay(surfaceView.getHolder());
player.prepare();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}


开启摄像头

开启摄像头是在ACtivity中打开系统自带的摄像头应用。代码如下:

public void onClick(View v) {
Intent intent = new Intent();
//获得摄像头的action,并设置到intent中
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);

file = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis()+".jpg");
try {
file.createNewFile();

} catch (IOException e) {
e.printStackTrace();
}
//将生成的照片放到file文件中。
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
//启动摄像头并获得返回值的照片
startActivityForResult(intent, 0x23);
}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==0x23){
if(resultCode==RESULT_OK){
//将获取的照片放到ImageView中
imageView.setImageURI(Uri.fromFile(file));

}

}
}


在上面的代码中有时会因为图片过大而不能显示出来,所以必须对图片进行压缩,代码如下:

private void zipImage(String savePath) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(savePath, options);
options.inSampleSize = computeInitialSampleSize(options, 480, 480 * 960);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(savePath, options);
try {
FileOutputStream fos = new FileOutputStream(savePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
bitmap.recycle();
bitmap = null;
System.gc();
}
public int computeSampleSize(BitmapFactory.Options options,
int minSideLength, int maxNumOfPixels) {
int initialSize = computeInitialSampleSize(options, minSideLength,
maxNumOfPixels);
int roundedSize;
if (initialSize <= 8) {
roundedSize = 1;
while (roundedSize < initialSize) {
roundedSize <<= 1;
}
} else {
roundedSize = (initialSize + 7) / 8 * 8;
}
return roundedSize;
}

private int computeInitialSampleSize(BitmapFactory.Options options,
int minSideLength, int maxNumOfPixels) {
double w = options.outWidth;
double h = options.outHeight;
int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
.sqrt(w * h / maxNumOfPixels));
int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
Math.floor(w / minSideLength), Math.floor(h / minSideLength));
if (upperBound < lowerBound) {
// return the larger one when there is no overlapping zone.
return lowerBound;
}
if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
return 1;
} else if (minSideLength == -1) {
return lowerBound;
} else {
return upperBound;
}
}


在onActivityResult方法中调用 zipImage(file.getAbsolutePath());//对图片进行压缩。

//将获取的照片放到ImageView中

imageView.setImageURI(Uri.fromFile(file));

就可以对压缩的图片进行显示了。

在相册中选择图片

在相册中选择图片的代码如下:

gallery_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");

//
startActivityForResult(intent,0x24);
}
});


在onActivityResult中:

case 0x24:
Uri uri=  data.getData();
String s = getAbsoluteImagePath(uri);
zipImage(s);//对图片进行压缩
imageView.setImageURI(uri);
break;


getAbsoluteImagePath(uri)为根据uri获得文件的绝对路径的方法。

protected String getAbsoluteImagePath(Uri uri)
{
// can post image
String [] proj={MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery( uri,
proj,                 // Which columns to return
null,       // WHERE clause; which rows to return (all rows)
null,       // WHERE clause selection arguments (none)
null);                 // Order-by clause (ascending by name)

int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();

return cursor.getString(column_index);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: