SoundPool、录制音频、播放视频、调用摄像头

SoundPool的用法

在Android中播放音频文件一般都使用MediaPlayer,但是一般都是比较长的音频文件,我们可以用soundpool可以播一些短的反应速度要求高的声音,比如通知提示音,消息提示音等。

特点

  1. SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作
  2. SoundPool在load时可以处理多个媒体一次初始化并放入内存中,这里效率比MediaPlayer高了很多。
  3. SoundPool类支持同时播放多个音效,而MediaPlayer类是同步执行的只能一个文件一个文件的播放。

用法

①我们在创建SoundPool对象时,在API 21以下可以用

 SoundPool pool=new SoundPool(2,AudioManager.STREAM_MUSIC,0);

其中第一个参数maxStream表示同时播放的流的最大数量,第二个参数streamType表示流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出),第三个参数srcQuality表示采样率转化质量,当前无效果,使用0作为默认值 。

API 21及以上,要借助SoundPool.Builder来创建SoundPool对象。
首先创建SoundPool.Builder对象,然后设置一些播放的参数,最后调用build()方法来创建SoundPool对象。

SoundPool.Builder builder=new SoundPool.Builder();
builder.setMaxStreams(2);
AudioAttributes.Builder audioBuilder = new AudioAttributes.Builder();
audioBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(audioBuilder.build());
SoundPool pool=builder.build();

然后调用load()方法,得到voiceId的int值。如果我们要从APK资源中载入音频文件,那么我们要在res目录下新建文件夹raw,然后将播放的音频文件放入raw下

int voiceId=pool.load(getApplicationContext(),R.raw.outgoing,1);

传入的3个参数依次为Context,目标音频资源ID,优先级。
②最后播放,则调用play()方法。

pool.play(voiceId,1,1,0,-1,1);

这里传入了6个参数,第一个为load()方法返回的id,第二个leftVolume表示左音量,第三个rightVolume表示右音量,第四个priority表示优先级,第五个loop表示循环次数,其中0表示一次,-1表示循环,第六个rate表示速率,速率最低0.5最高为2,1代表正常速度 。

注意:因为SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作,所以如果载入音乐文件多大,当我们执行play(),可能会播放不出来声音。所以我们尽量让加载文件和调用play()方法,放在不同的位置。比如加载放在onCreate()方法里,调用play()方法放在按钮的监听事件里!

代码示例

这里我们在布局中添加一个按钮,点击按钮播放我们的音频。下面是MainActivity中的代码

import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    private SoundPool pool;
    private int voiceId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        voiceId=initSoundPool();
        Button button= (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pool.play(voiceId,1,1,0,-1,1);
            }
        });
    }
    private int initSoundPool(){
        //API 21及以上使用
        if (Build.VERSION.SDK_INT>=21){
            SoundPool.Builder builder=new SoundPool.Builder();
            builder.setMaxStreams(2);
            AudioAttributes.Builder audioBuilder=new AudioAttributes.Builder();
            audioBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
            builder.setAudioAttributes(audioBuilder.build());
            pool=builder.build();
        //API 21以下使用
        }else {
            pool=new SoundPool(2,AudioManager.STREAM_MUSIC,0);
        }
        return pool.load(getApplicationContext(),R.raw.outgoing,1);
    }
}

录制音频文件

录制音频文件就需要借助MediaRecorder类。

MediaRecorder的工作流程

SoundPool、录制音频、播放视频、调用摄像头_第1张图片
这个图,很清楚的说明了MediaRecorder的工作流程,我们在用的时候,只要按照这个流程一步一步写下来就行了!

用法

我们在布局中添加两个按钮,一个点击开始录音,一个点击结束录音。

<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/button_start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始录音" />

    <Button  android:id="@+id/button_stop" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="结束录音" />
</LinearLayout>

然后是主活动的代码

import android.media.MediaRecorder;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    private MediaRecorder mediaRecorder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button_start= (Button) findViewById(R.id.button_start);
        button_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               mediaRecorder=new MediaRecorder();    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);                                                             mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);               mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);                     mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory()+"/myrecorder.3gp");
                try {
                    mediaRecorder.prepare();
                    mediaRecorder.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
        Button button_stop= (Button) findViewById(R.id.button_stop);
        button_stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mediaRecorder.stop();
                mediaRecorder.reset();
                mediaRecorder.release();
            }
        });
    }
}

最后要加上调用麦克风的权限和写入内存卡的权限

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

播放视频

VideoView

VideoView类将视频的显示和控制集于一身,可以让我们非常便捷的显示和控制视频的播放。
它的用法也非常简单,首先我们在布局中加入一个按钮和一个VideoView控件,点击按钮可以播放视频。

<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/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始播放" />
    <VideoView  android:id="@+id/videoview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" />
</LinearLayout>

然后是MainActivity

import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;

public class MainActivity extends AppCompatActivity {
    private VideoView videoView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //得到VideoView的实例
        videoView= (VideoView) findViewById(R.id.videoview);
        Button button= (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//设置VideoView的播放文件路径
                        videoView.setVideoPath(Environment.getExternalStorageDirectory()+"/aa.mp4");
                //设置播放位置
                videoView.setMediaController(new MediaController(MainActivity.this));
                videoView.start();//开始播放
            }
        });
    }
}

最后别忘了加入读取内存卡的权限:

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

SurfaceView

同样的我们在布局中加入一个按钮和一个SurfaceView,点击按钮,播放视频!用法和前边将播放音频差不多。

<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/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始播放"/>
    <SurfaceView  android:id="@+id/surfaceview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/>
</LinearLayout>

然后是MainActivity

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    private SurfaceView surfaceView;
    private MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        surfaceView= (SurfaceView) findViewById(R.id.surfaceview);
        Button button= (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mediaPlayer==null){
                    mediaPlayer=new MediaPlayer();
                }
                mediaPlayer.reset();
                try {
                    mediaPlayer.setDataSource(Environment.getExternalStorageDirectory()+"/aa.mp4");
                    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    //SurfaceHolder是SurfaceView的控制接口,设置显示视频显示在SurfaceView上
                    mediaPlayer.setDisplay(surfaceView.getHolder());
                    mediaPlayer.prepare();
                    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            mp.start();
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

这里我们也需要声明访问内存卡的权限

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

调用系统摄像头

很多时候我们的应用程序可能会使用到摄像头的拍照功能,这时就需要我们调用系统摄像头来进行拍照,为我们的应用程序服务。
这里我们在布局中加入一个按钮,然后加入一个ImageView,点击按钮,调用摄像头拍照,然后把拍好的照片设置到ImageView上面显示。

<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/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="调用系统摄像头"/>
    <ImageView  android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" />
</LinearLayout>

MainActivity.java

import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.File;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    private ImageView imageView;
    private Uri uri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView= (ImageView) findViewById(R.id.image);
        Button button= (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//隐式启动相机
                //创建File对象,来存储拍下的照片
                File file=new File(Environment.getExternalStorageDirectory(),"hello.jpg");
                if(!file.exists()){
                    try {
                        file.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                uri=Uri.fromFile(file);//将File对象转换为Uri对象
                intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);//告诉系统相机,存储照片的位置
                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){
                Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
                imageView.setImageBitmap(bitmap);//得到图片
            }
        }
    }
}

你可能感兴趣的:(SoundPool,VideoView,摄像头,录制音频)