Android0915<十九>(多媒体、SoundPool、MediaRecorder、SurfaceView,简单地使用摄像头)
来源:互联网 发布:win7日程安排软件 编辑:程序博客网 时间:2024/06/15 12:36
SoundPool
SoundPool类管理和播放音频资源的应用。因为MediaPlayer在播放音乐时会资源占用量较高、延迟时间较长、不支持多个音频同时播放等。,但有时一些系统提示音很小,就没有必要用MediaPlayer去播放,就用到了SoundPool.SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作。SoundPool主要用于播放一些较短的声音片段,与MediaPlayer相比,SoundPool的优势在于CPU资源占用量低和反应延迟小。另外,SoundPool还支持自行设置声音的品质、音量、 播放比率等参数。
SoundPlayer 播放音频的实现步骤
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/btn_soundpool" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="提示音"/></LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity { private Button btn_soundpool; private SoundPool pool=null; private int voiceID; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); voiceID=initSoundpool(); btn_soundpool= (Button) findViewById(R.id.btn_soundpool); btn_soundpool.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { playSound(); } }); } public void playSound(){ //play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) , // soundID该方法的第一个参数指定播放哪个声音,其中leftVolume和rightVolume表示左右音量, // priority表示优先级,loop表示循环次数,rate表示速率,如 //速率最低0.5最高为2,1代表正常速度 pool.play(voiceID,1,1,0,1,1); } private int initSoundpool() { //判断sdk的版本号,高于21 的可以用下面的方法 if (Build.VERSION.SDK_INT >= 21) { //通过SoundPool.Builder创建SoundPool得到实例对象 SoundPool.Builder builder=new SoundPool.Builder(); //setMaxStreams()方法设置可以同时播放的同时流的最大数量。参数为大于等于1的值 builder.setMaxStreams(2); //AudioAttributes类封装的属性的集合来描述一个音频流的信息。 //AudioAttributes.Builder用于生成AudioAttributes类 AudioAttributes.Builder attrBuilder=new AudioAttributes.Builder(); //AudioAttributes.Builder的setLegacyStreamType()方法从传统的流类型中推断出的属性。 //setLegacyStreamType参数AudioManager.STREAM_MUSIC为音乐播放的音频流 attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC); //setAudioAttributes()方法得到AudioAttributes集合,参数为attribute类型的非空值 builder.setAudioAttributes(attrBuilder.build()); pool=builder.build(); }else{ //SDK版本低于21的可以用下面的方法 //第一个参数是声音的大小,第二个参数是数量流的类型,第三个参数为采样率转化质量,当前无效果,使用0作为默认值 pool=new SoundPool(2,AudioManager.STREAM_MUSIC,0); } //int load(String path, int priority) 从APK资源载入或 resld 所对应的资源加载声音。 //最后一个参数为优先级。 //加载声音之后,该方法都会返回该声音的的ID,以后程序就可以通过该声音的ID 来播放指定声音。 return pool.load(getApplicationContext(),R.raw.msg,1); }}
MediaRecorder录音
MediaRecorder的机制图,录音需要系统的录音权限
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
基本的步骤为:
1、创建一个实例对象
2、创建一个Mediarecorder的类,然后调用Mediarecorder的方法完成设置audio源、设置输出文件格式、audio编码格式、设置输出文件
3、准备录音,开始录音,停止录音,释放相关连接对象
>
mediaRecorder=new MediaRecorder(); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory()+"/myrecord.3gp");mediaRecorder.prepare();mediaRecorder.start(); mediaRecorder.stop();//reset()重启mediarecorder其空闲状态mediaRecorder.reset();//release()释放资源这个mediarecorder对象关联mediaRecorder.release();
activity_main.xml
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button btn_StartRecorder; private Button btn_StopRecorder; private MediaRecorder mediaRecorder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); voiceID=initSoundpool(); btn_StartRecorder= (Button) findViewById(R.id.btn_start_recorder); btn_StartRecorder.setOnClickListener(this); btn_StopRecorder= (Button) findViewById(R.id.btn_stop_recorder); btn_StopRecorder.setOnClickListener(this);}@Override public void onClick(View v) { switch(v.getId()){ case R.id.btn_start_recorder: //创建一个MediaRecorder类的实例对象 mediaRecorder=new MediaRecorder(); //setAudioSource()方法设置用于录制的音频源,参数为使用的音频源 //MediaRecorder.AudioSource定义的音频源.MIC为麦克风音频源 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //setOutputFormat()方法为设置输出格式为.3gp mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //setAudioEncoder()方法为设置编码格式, // 参数为定义的音频编码格式,AMR_NB为AMR(窄带)音频编解码器 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //setOutputFile()方法设置输出文件的路径, mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory()+"/myrecord.3gp"); try { //prepare()准备录音机开始捕获和编码数据。 mediaRecorder.prepare(); //start()开始捕获和指定setoutputfile()文件数据编码 mediaRecorder.start(); } catch (IOException e) { e.printStackTrace(); } break; case R.id.btn_stop_recorder: //stop()停止录制 mediaRecorder.stop(); //reset()重启mediarecorder其空闲状态 mediaRecorder.reset(); //release()释放资源这个mediarecorder对象关联 mediaRecorder.release(); break; } }}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/btn_start_recorder" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始录音"/> <Button android:id="@+id/btn_stop_recorder" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="结束录音"/></LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.administrator.soundpool" ><uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <application android:allowBackup="true" android:icon="@mipmap/music" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SurfaceViewActivity"></activity> </application></manifest>
VideoView和SurfaceView播放视频
用VideoView控件来播放视频,显示视频文件。VideoView类可以从各种来源加载图像(如资源或内容提供商),负责计算测量从视频,它可以用在任何布局管理器,提供了各种各样的显示选项,如缩放和着色。
SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。 当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。虽然VideoView可以很容易地播放视频,但播放位置和播放大小并不受控制,因此,需要用SurfaceView来播放视频
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/btn_surfaceview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始播放surfacview"/> <Button android:id="@+id/btn_start_playvideo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始播放"/> <VideoView android:id="@+id/videoview" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.administrator.soundpool" ><uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <application android:allowBackup="true" android:icon="@mipmap/music" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SurfaceViewActivity"></activity> </application></manifest>
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button btn_StartPlay; private VideoView mVideoView; private Button btn_surfaceview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_StartPlay= (Button) findViewById(R.id.btn_start_playvideo); btn_StartPlay.setOnClickListener(this); mVideoView= (VideoView) findViewById(R.id.videoview); btn_surfaceview= (Button) findViewById(R.id.btn_surfaceview); btn_surfaceview.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.btn_start_playvideo: //setVideoPath设置视频的文件来源位置 mVideoView.setVideoPath(Environment.getExternalStorageDirectory()+"/aa.mp4"); //setMediaController设置进度条在界面上显示 mVideoView.setMediaController(new MediaController(MainActivity.this)); //start()开始播放视频 mVideoView.start(); break; case R.id.btn_surfaceview: Intent intent=new Intent(MainActivity.this,SurfaceViewActivity.class); startActivity(intent); break; }}}
SurfaceViewActivity.java启动另一个界面来说明surfaceView播放视频
public class SurfaceViewActivity extends Activity implements View.OnClickListener{ private Button btn_playsvvideo; private SurfaceView mSurfaceView; private MediaPlayer player; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_surfaceview); btn_playsvvideo= (Button) findViewById(R.id.btn_playsurfaceview); btn_playsvvideo.setOnClickListener(this); mSurfaceView= (SurfaceView) findViewById(R.id.surfaceview); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_playsurfaceview: if (player==null){ player=new MediaPlayer(); } player.reset(); try { //设置视频位置 player.setDataSource(Environment.getExternalStorageDirectory()+"/aa.mp4"); player.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置声音类型 Log.d("空指针",player+""+mSurfaceView); player.setDisplay(mSurfaceView.getHolder());//设置视频播放位置 player.prepare();//准备 player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start();//开始播放 } }); } catch (IOException e) { e.printStackTrace(); } break; } }}
activity_surfaceview.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"><Button android:id="@+id/btn_playsurfaceview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始播放"/> <SurfaceView android:id="@+id/surfaceview" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
调用系统摄像头
调用系统的摄像头进行拍照并显示在ImageView上,还可以调用系统的相册,选取其中的一张在ImageView上显示,有时候照片质量过高,无法显示,可以对照片进行压缩,在进行存储并显示。
MainActivity.xml(这里将图片压缩写到另一个类里)
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button btn_StartCamera; private Button btn_OpenGallery; private ImageView mImageView; private File file; private int GET_PIC_FORM_GALLERY=0x24; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_StartCamera= (Button) findViewById(R.id.btn_startcamera); btn_StartCamera.setOnClickListener(this); mImageView= (ImageView) findViewById(R.id.imageview); btn_OpenGallery= (Button) findViewById(R.id.btn_open_gallery); btn_OpenGallery.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.btn_startcamera: Intent intent=new Intent(); intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//隐式启动系统相机 file=new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg"); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(file));//告诉系统相机将照片保存的位置 startActivityForResult(intent, 0x23);//开始启动 break; //调用系统相册按钮事件监听 case R.id.btn_open_gallery: Intent intentOpenGallery=new Intent(Intent.ACTION_GET_CONTENT); //得到intent的类型为图片 intentOpenGallery.setType("image/*"); startActivityForResult(intentOpenGallery, GET_PIC_FORM_GALLERY); break; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode==RESULT_OK){ if (requestCode==0x23){ ImageZip.zipImage(file.getAbsolutePath());//压缩图片 mImageView.setImageURI(Uri.fromFile(file));//得到图片 }if (requestCode==GET_PIC_FORM_GALLERY){ //从系统相册中得到图片 Uri uri=data.getData(); mImageView.setImageURI(uri); } } }}
ImageZip.java(压缩图片的方法)
public class ImageZip { public static 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 static 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 static 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; } }}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:id="@+id/btn_startcamera" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="调用系统相机"/> <Button android:id="@+id/btn_open_gallery" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="打开相册"/><ImageView android:id="@+id/imageview" android:layout_width="match_parent" android:layout_height="match_parent" /></RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.administrator.camera" ><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <application android:allowBackup="true" android:icon="@mipmap/camera" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
- Android0915<十九>(多媒体、SoundPool、MediaRecorder、SurfaceView,简单地使用摄像头)
- 多媒体应用之/SoundPool/MediaRecorder/MediaPlayerVideo/SurfaceView
- 音乐(多媒体)SoundPool,MediaRecorder和Mediaplayer
- SoundPool、 VedioView、 MediaRecorder、 SurfaceView、 Camera、
- SoundPool(播放小音频),MediaRecorder(录音),视频播放,开启摄像头
- Android -- 视频音频多媒体播放,在线播放, MediaPlayer, SurfaceView, SoundPool, Timer定时器使用
- Android -- 视频音频多媒体播放,在线播放, MediaPlayer, SurfaceView, SoundPool, Timer定时器使用
- 使用MediaRecorder+SurfaceView实现录像
- 多媒体 使用MediaRecorder录制音频
- Android开发--多媒体应用开发(二)--SoundPool的使用
- Android 多媒体 通过MediaRecorder+SurfaceView实现拍照,录像
- SoundPool的简单使用
- SoundPool简单使用
- Android --- 多媒体应用(SoundPool播放音频)
- Android开发之录音MediaRecorder、播放音频(MediaPlayer、SoundPool)
- Android --- 多媒体应用(MediaRecorder 录音)
- 09-15 Camera (摄像机),SoundPool(播放提示音等小音频),VideoView(播放视频),SurfaceView(播放视频),MediaRecorder(录制音频)
- MediaPlayer 、soundPool、SurfaceView
- jsp的4个作用域
- C++Primer第五版 7.3.4节练习
- BZOJ 1187 HNOI2007 神奇游乐园 插头DP
- 以个人用户在服务器运行 caffe 点滴
- HDU 5364 Distribution money (水题)
- Android0915<十九>(多媒体、SoundPool、MediaRecorder、SurfaceView,简单地使用摄像头)
- android之视频的播放(VedioView,SuefaceView)和图片的获得
- 不结束进程卸载关键进程中DLL文件的方法
- html初学-简介
- php环境配置
- 程序编译过程
- C++Primer第五版 7.4节练习
- java 中的 final 变量
- Ubuntu 14.04出现“device not managed”错误及ubuntu可以ping通外网浏览器上不了网。