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

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);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值