首页 > Windows开发 > 详细

媒体播放及Media Player API

时间:2020-04-09 17:19:13      阅读:110      评论:0      收藏:0      [点我收藏+]
  1. MediaPlayer API介绍
  2. 音频播放
  3. 视频播放及VideoView,SurfaceView

MediaPlayer API介绍

????MediaPlayer OverView官方文档

????Mediaplayer可用来播放video,audio,另外可使用AudioManager(提供铃声和音量的控制)管理音频资源和输出

????MediaPlayer状态转换图:

技术分享图片

(上图双箭头表示异步调用

MediaPlayer 可在任何状态设置相关的事件监听器, 同时提供了一个方便的静态方法create来创建Media Player实例并使其进入Prepared状态。

通过MediaPlayer构造函数所创建的实例处于Idle状态,此时需要调用setDataSource使其进入Initialzed状态,然后可调用prepare方法进入Prepared状态,或其异步版本的prepare方法(prepareAsync),调用prepareSync会进入Preparing状态,使用prepareAsync方法需要设置OnPreparedListener监听器来变为Prepared状态,进入Prepared 状态就可以调用start方法来播放媒体文件。

音频播放

  • 播放音频
  1. MediaPlayer player = new
    										MediaPlayer();//Idle状态
    
  2. ????????//在使用app自带资源时
    								
  3. //常使用create简便方法实例化Media Player,并且进入Prepared状态,player = create(this,R.id.resId);
    							
  4. 
    							//在使用assets 目录的文件时 
    								
  5. //使用AssetsManager来管理,可使用getAssets()得到AssetsManager的实例assetsManager?,
    							
  6. //AssetsFileDescriptor afd = assetsManager.openFd(String fileName);将afd作为参数传递给create或setDataSource
    							
  7. ? ?
  8. //另外create和setDataSource使用String path作为参数时,path指的是文件系统路径,通常是sdCard目录的媒体文件
    							
  9. player.setDataSource(…)//设置资源,进入Initialized状态
    
  10. player.prepare() //进入Prepared状态
    
  11. //or 调用prepareAsync()进入preparing状态,可以设置监听器 setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener).
    						
  12. Player.start()//开始播放 进入started状态
    						

    ? ?

  1. 其余子类需要调用其构造方法来创建实例

  1. ?

    ?

  • 在音频应用中使用 VolumeShaper 来执行渐强、渐弱、渐强渐弱、降低音量以及其他短暂的自动音量转换。VolumeShaper 类在 Android 8.0(API 级别 26)及更高版本中可用。通过对 AudioTrackMediaPlayer 的实例调用 createVolumeShaper() 来创建 VolumeShaperVolumeShaper 仅对创建它的 AudioTrack 或 MediaPlayer 生成的音频起作用

    VolumeShaper 的行为由它的 VolumeShaper.Configuration 定义。该配置指定了音量曲线、插值器类型和持续时间。

    技术分享图片

    技术分享图片

  1. //创建配置
    							
  2. VolumeShaper.Configuration configuration = new
    												VolumeShaper.Configuration.Builder()
    
  3.                     .setCurve(new
    									float[]{0.0f,0.5f,1.0f},new
    																			float[]{0.f, 1.f,0.f})
    
  4.                     .setDuration(1000*60*1)
    
  5.                     .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
    
  6.                     .build();
    
  7. //创建volumeShaper
    
  8. 
    							VolumeShaper volumeShaper = player.createVolumeShaper(configuration);
    
  9. //应用volumeShaper到音频
    
  10.  volumeShaper.apply(VolumeShaper.Operation.PLAY);
    
  11. //替换配置
    
  12. boolean
    								join = true;
    
  13. volumeShaper.replace(newConfig, VolumeShaper.Operation.PLAY, join);
    
  14. //关闭volumeShaper
    
  15. volumeShaper.close();
    

    ? ?

  • SoundPool为应用程序管理和播放音频资源,预先将音频加载到内存,低时延、cpu占用少。通常用于游戏播放短音频,支持速率、音量、音频优先级,声道、循环设置。

    使用SoundPool.Builder构造实例,构造函数已被废弃。使用SoundPool.Builder时有一下几个方法:setAudioAttribute方法需要一个AudioAttribute对象。

    技术分享图片

    ?

AudioAttribute封装了描述音频流信息的属性的集合,使用AudioAttribute.Builder创建AudioAttribute实例。使用setUsage设置使用场景,setContentType设置内容类型,build创建AudioAttribute实例。

技术分享图片

SoundPool的方法load方法加载音频并返回一个int值,这个int 值是音频的streamID。播放时调用SoundPool的play方法。第一个参数sound技术分享图片ID即是load方法加载音频时返回的代表音频的streamID。第二三个参数时左声道和右声道,0.0f-1.0f。loop代表循环次数(播放次数=循环次数+1),为-1时一直循环。rate:播放速度0.5-2.0,默认为1。

?

  1. AudioAttributes attr = new
    										AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME).
    

setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();

  1. SoundPool soundPool = new
    									SoundPool.Builder().setAudioAttributes(attr).setMaxStreams(10).build();
    
  2.  int soundID = soundPool.load(…);//加载音频
    
  3. soundPool.play(soundID,1.0,1.0,0,0,1);//播放音乐
    
  4. //可将所加载的音频的streamID放入容器(List,Map),保存streamID。
    

? ?

?

视频播放及VideoView,SurfaceView

  • VideoView

    在使用videoView时(和布局主题有关)会导致有白边现象,可以实现VideoView的子类(自定义View),重写onMeasure()方法。

  1. protected
    								void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
  2. 
    							super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
  3. //获取系统服务的WindowManager
    
  4. 
    							WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
    
  5. 
    							assert wm != null;
    
  6. //将所得到的像素大小保存在point中
    
  7. 
    							Point point = new
    											Point();
    
  8.     wm.getDefaultDisplay().getSize(point);
    
  9. //设置绘制的大小
    
  10.     setMeasuredDimension(point.x,point.y);
    
  11. }
    

?获取当前屏幕的大小与WindowManager,Display,DisplayMetris这三个类有关。getContext.getSystemService(Context.WINDOW_SERVICE)取得windowManager,windowManager.getDefaultDisplay()返回一个Display。Display中有许多获得窗口屏幕大小的方法:getSize,getMetrics。

?

使用自定义的VideoView播放视频

  1. //MediaController提供图形界面对视频的控制
    
  2. MediaController mediaController = new
    									MediaController(this);
    
  3. //设置视频
    
  4. fullScreenVideoView.setVideoURI(Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.fat));
    
  5. //将meidiaController与videoView联系起来
    
  6. mediaController.setMediaPlayer(fullScreenVideoView);
    
  7. fullScreenVideoView.setMediaController(mediaController);
    
  8. //打开屏幕,获取焦点
    
  9. fullScreenVideoView.requestFocus();
    
  10. //播放视频
    
  11. fullScreenVideoView.start();
    

? ?

  • SurfaceView

    VideoView是SurfaceView的子类

    Surface是可以在子线程渲染更新界面,surfaceView.getHolder的返回值就是一个surfaceHolder,也是surfaceView的核心, surfaceHolder.addCallback()为其添加一个回调,在这个回调中包含surface的完整的生命周期:surfaceCreated、surfaceChanged、surfaceDestroy。若使用绘画子线程必须,子线程必须和主线程同步,只有当surface状态在生命周期只能子线程才能访问surface。

  1. mediaPlayer = MediaPlayer.create(this,R.raw.fat);
    
  2. surfaceView.getHolder().setKeepScreenOn(true);
    
  3. surfaceView.getHolder().addCallback(new
    									SurfaceHolder.Callback() {
    
  4. 
    							@Override
    								
  5. 
    							public
    									void surfaceCreated(SurfaceHolder holder) {
    
  6. 
    							DisplayMetrics metrics = new
    											DisplayMetrics();
    
  7. 
    							MainActivity.this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
    
  8.         surfaceView.setLayoutParams(new
    									ConstraintLayout.LayoutParams(metrics.widthPixels,
    
  9.                 mediaPlayer.getVideoHeight()*metrics.widthPixels/mediaPlayer.getVideoWidth()));
    
  10.         mediaPlayer.setDisplay(surfaceView.getHolder());
    
  11.         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    
  12.     }
    
  13. 
    							@Override
    								
  14. 
    							public
    									void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
  15.     }
    
  16. 
    							@Override
    								
  17. 
    							public
    									void surfaceDestroyed(SurfaceHolder holder) {
    }
  18. });
    

媒体播放及Media Player API

原文:https://www.cnblogs.com/lrllzp/p/12668079.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!