多媒体开发.ppt
关于多媒体开发关于多媒体开发现在学习的是第1页,共32页Android平台多媒体平台多媒体w 音频播放w 音频录制w 视频播放现在学习的是第2页,共32页音频文件介绍音频文件介绍w 有两类主要的音频文件格式: n无损格式,例如WAV,PCM,TTA,FLAC,AU,APE,TAK,WavPack(WV) n有损格式,例如MP3,Windows Media Audio(WMA),Ogg Vorbis(OGG),AAC 现在学习的是第3页,共32页移动音频文件移动音频文件w 作为移动设备音频文件应该原则上比较小,一般的格式:nWAV、由于无损压缩效果最好。nMP3、有损压缩,文件比较小,由于去除的是人类无法感应到的声音,效果也很好。这是目前常用格式。nAAC、压缩比例更大,比MP3文件还要小。现在学习的是第4页,共32页如何选择音频格式?如何选择音频格式?w 作为移动设备音频文件原则上应该比较小,但是现在的移动设备处理能力已经很快了,sdcard容量的增加储备大文件也不是一个问题了。播放文件的来源也是选择文件格式的重要参考依据,如果我们的音频文件在网上直接播放,那么文件就要小这样文件传输比较快。如果文件来源于本地如sdcard,文件大小就不是问题。现在学习的是第5页,共32页音频文件介绍音频文件介绍w 有两类主要的音频文件格式: n无损格式,例如WAV,PCM,TTA,FLAC,AU,APE,TAK,WavPack(WV) n有损格式,例如MP3,Windows Media Audio(WMA),Ogg Vorbis(OGG),AAC 现在学习的是第6页,共32页视频文件介绍视频文件介绍w 视频格式可以分为适合本地播放的本地影像视频和适合在网络中播放的网络流媒体影像视频两大类。尽管后者在播放的稳定性和播放画面质量上可能没有前者优秀,但网络流媒体影像视频的广泛传播性使之正被广泛应用于视频点播、网络演示、远程教育、网络视频广告等等互联网信息服务领域。 现在学习的是第7页,共32页适合移动设备的视频文件适合移动设备的视频文件w 3GP,3GP是一种3G流媒体的视频编码格式,主要是为了配合3G网络的高传输速度而开发的,也是目前手机中最为常见的一种视频格式。w 视频MP4格式,除了支持MP3所具有的音乐播放功能外,还具备强大的MPEG-4视频播放能力。现在学习的是第8页,共32页Android开发音频应用程序开发音频应用程序w 音频播放w 音频录制现在学习的是第9页,共32页音频播放音频播放w Android平台可以通过资源文件、文件系统和网络三种方式来播放多媒体文件。无论使用哪一种播放方式,基本的流程都是类似的。现在学习的是第10页,共32页通过资源文件通过资源文件btnStart.setOnClickListener(new View.OnClickListener() btnStart.setOnClickListener(new View.OnClickListener() OverrideOverridepublic void onClick(View v) public void onClick(View v) label.setText(label.setText(妈妈咪呀!开始播放妈妈咪呀!开始播放.);.);try try MediaPlayer mp = MediaPlayer.create(MediaPlayer mp = MediaPlayer.create( MediaPlayerDemo_Audio1.this, R.raw.mamma); MediaPlayerDemo_Audio1.this, R.raw.mamma);mp.start();mp.start(); catch (IllegalStateException e) catch (IllegalStateException e) e.printStackTrace();e.printStackTrace(); ););现在学习的是第11页,共32页通过资源文件播放通过资源文件播放w raw文件夹,我们需要在res下面创建raw文件夹这个文件存放资源文件,文件命名“a-z0-9_.”,注意不能有大写字母。w MediaPlayer.create方法创建MediaPlayer对象。w mp.start()直接播放文件。现在学习的是第12页,共32页通过文件系统播放通过文件系统播放btnStart.setOnClickListener(new View.OnClickListener() btnStart.setOnClickListener(new View.OnClickListener() OverrideOverridepublic void onClick(View v) public void onClick(View v) label.setText(label.setText(妈妈咪呀!开始播放妈妈咪呀!开始播放.);.);try try MediaPlayer mp = new MediaPlayer();MediaPlayer mp = new MediaPlayer();mp.setDataSource(/sdcard/ma_mma.mp3);mp.setDataSource(/sdcard/ma_mma.mp3);mp.prepare();mp.prepare();mp.start();mp.start(); catch (Exception e) catch (Exception e) e.printStackTrace();e.printStackTrace(); ););现在学习的是第13页,共32页在模拟器中创建在模拟器中创建sdcardw 通过Eclipse的ADT插件创建w 通过sdk中的命令mksdcard创建nD:mksdcard 1024M D:workspaceandroid_sdcard_image现在学习的是第14页,共32页Eclipse的的ADT插件创建插件创建现在学习的是第15页,共32页现在学习的是第16页,共32页现在学习的是第17页,共32页视频播放视频播放w 视频播放与音频播放类似都是使用MediaPlayer类实现,但是视频播放需要一个视图(SurfaceView)展示播放画面。w SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用窗体部件的应用使用的。Android图形系统中一个重要的概念和线索是surface。View及其子类(如TextView, Button)要画在surface上。每个surface创建一个Canvas对象(但属性时常改变),用来管理view在surface上的绘图操作,如画点画线。现在学习的是第18页,共32页布局管理文件布局管理文件w 我们在mediaplayer_2.xml定义SurfaceView. . . SurfaceView android:id=+id/surface android:layout_gravity=center. . .现在学习的是第19页,共32页Activity中的中的SurfaceView. . .private SurfaceView mPreview;private SurfaceView mPreview;private SurfaceHolder holder;private SurfaceHolder holder;OverrideOverridepublic void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);super.onCreate(savedInstanceState);setContentView(R.layout.mediaplayer_2);setContentView(R.layout.mediaplayer_2);mPreview = (SurfaceView) findViewById(R.id.surface);mPreview = (SurfaceView) findViewById(R.id.surface);holder = mPreview.getHolder();holder = mPreview.getHolder();holder.addCallback(this);holder.addCallback(this);holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); . . .现在学习的是第20页,共32页SurfaceHolderw SurfaceHolder接口持有Surface引用,并且定义了方法控制Surface的尺寸和格式。在SurfaceHolder中定义了4种Surface类型,分别是NORMAL、HARDWARE、GPU和PUSH_BUFFERS。在视频播放与相机预览中,通常是使用PUSH_BUFFERS,也就是说,Surface本身并没有维护一个缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前。w 可以通过holder = mPreview.getHolder();获得这个对象。w SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS是为了surface 指定PUSH类型的缓冲区。现在学习的是第21页,共32页Listener的使用的使用w 除了MediaPlayer类,我们还需要注意几个播放器件Listener的使用,它们提供了播放器的更多的状态信息。除了OnVideoSizeChangedListener以外其它的都可以在音频中使用。public class MediaPlayerDemo_Video extends Activity public class MediaPlayerDemo_Video extends Activity implementsimplementsOnBufferingUpdateListenerOnBufferingUpdateListener, , OnCompletionListenerOnCompletionListener, , OnPreparedListenerOnPreparedListener, ,OnVideoSizeChangedListenerOnVideoSizeChangedListener, , SurfaceHolder.Callback SurfaceHolder.Callback . . . 现在学习的是第22页,共32页OnBufferingUpdateListener w 当播放网络上的媒体文件或者流媒体 MediaPlayer.OnBufferingUpdateListener 的onBufferingUpdate(MediaPlayer mp, int percent)接口函数会被回调,通知当前的缓冲进度信息。w 通过setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) 函数来注册该Listener。现在学习的是第23页,共32页OnCompletionListener w 当前歌曲播放结束后,MediaPlayer.OnCompletionListener的 onCompletion(MediaPlayer mp) 接口会被回调,通知歌曲结束事件。w 通过setOnCompletionListener(MediaPlayer.OnCompletionListener listener) 函数来注册该监听器 。现在学习的是第24页,共32页OnPreparedListener w 当播放网络媒体文件或流媒体时,播放器的准备时间较长,播放器准备完毕可以开始播放时,MediaPlayer.OnPreparedListener的onPrepared(MediaPlayer mp)接口会被回调,通知该信息。w 当播放器需要支持播放流媒体或者网络媒体文件时,建议使用prepareAsync()接口调用来准备播放器,同时通过MediaPlayer.OnPreparedListener来监听prepared信息。这样可以避免因为网络等因素造成的MediaPlayer准备时间过长进而导致程序长时间无响应。现在学习的是第25页,共32页OnVideoSizeChangedListenerw 当前视频尺寸第一次获得以及改变的时候,MediaPlayer. OnVideoSizeChangedListener的 onVideoSizeChanged(MediaPlayer mp, int width, int height)接口会被回调。w 通过setOnVideoSizeChangedListener (MediaPlayer. OnVideoSizeChangedListener listener) 函数来注册该监听器 。现在学习的是第26页,共32页实例中接口注册实例中接口注册OverrideOverridepublic void surfaceCreated(SurfaceHolder holder) public void surfaceCreated(SurfaceHolder holder) String path = /sdcard/nobody1.3gp;String path = /sdcard/nobody1.3gp;try try mMediaPlayer = new MediaPlayer();mMediaPlayer = new MediaPlayer();mMediaPlayer.setDataSource(path);mMediaPlayer.setDataSource(path);mMediaPlayer.setDisplay(holder);mMediaPlayer.setDisplay(holder);mMediaPlayer.prepare();mMediaPlayer.prepare();mMediaPlayer.setOnBufferingUpdateListener(this);mMediaPlayer.setOnBufferingUpdateListener(this);mMediaPlayer.setOnCompletionListener(this);mMediaPlayer.setOnCompletionListener(this);mMediaPlayer.setOnPreparedListener(this);mMediaPlayer.setOnPreparedListener(this);mMediaPlayer.setOnVideoSizeChangedListener(this);mMediaPlayer.setOnVideoSizeChangedListener(this); catch (Exception e) catch (Exception e) Log.e(TAG, error: + e.getMessage(), e);Log.e(TAG, error: + e.getMessage(), e); 现在学习的是第27页,共32页实例中其它播放方法实例中其它播放方法OverrideOverridepublic void onPrepared(MediaPlayer mp) public void onPrepared(MediaPlayer mp) Log.d(TAG, onPrepared called);Log.d(TAG, onPrepared called);mMediaPlayer.start();mMediaPlayer.start(); OverrideOverridepublic void onVideoSizeChanged(MediaPlayer mp, public void onVideoSizeChanged(MediaPlayer mp, int width, int height) int width, int height) Log.d(TAG, onVideoSizeChanged called);Log.d(TAG, onVideoSizeChanged called);mVideoWidth = mp.getVideoWidth();mVideoWidth = mp.getVideoWidth();mVideoHeight = mp.getVideoHeight();mVideoHeight = mp.getVideoHeight();if (mVideoWidth != 0 & mVideoHeight != 0) if (mVideoWidth != 0 & mVideoHeight != 0) holder.setFixedSize(mVideoWidth, mVideoHeight);holder.setFixedSize(mVideoWidth, mVideoHeight); mMediaPlayer.start();mMediaPlayer.start(); 现在学习的是第28页,共32页实例中接口注册实例中接口注册OverrideOverridepublic void surfaceCreated(SurfaceHolder holder) public void surfaceCreated(SurfaceHolder holder) String path = /sdcard/nobody1.3gp;String path = /sdcard/nobody1.3gp;try try mMediaPlayer = new MediaPlayer();mMediaPlayer = new MediaPlayer();mMediaPlayer.setDataSource(path);mMediaPlayer.setDataSource(path);mMediaPlayer.setDisplay(holder);mMediaPlayer.setDisplay(holder);mMediaPlayer.prepare();mMediaPlayer.prepare();mMediaPlayer.setOnBufferingUpdateListener(this);mMediaPlayer.setOnBufferingUpdateListener(this);mMediaPlayer.setOnCompletionListener(this);mMediaPlayer.setOnCompletionListener(this);mMediaPlayer.setOnPreparedListener(this);mMediaPlayer.setOnPreparedListener(this);mMediaPlayer.setOnVideoSizeChangedListener(this);mMediaPlayer.setOnVideoSizeChangedListener(this); catch (Exception e) catch (Exception e) Log.e(TAG, error: + e.getMessage(), e);Log.e(TAG, error: + e.getMessage(), e); 现在学习的是第29页,共32页释放资源方法释放资源方法OverrideOverrideprotected void onDestroy() protected void onDestroy() super.onDestroy();super.onDestroy();Log.d(TAG, onDestroy called);Log.d(TAG, onDestroy called);if (mMediaPlayer != null) if (mMediaPlayer != null) mMediaPlayer.release();mMediaPlayer.release();mMediaPlayer = null;mMediaPlayer = null; mVideoWidth = 0;mVideoWidth = 0;mVideoHeight = 0;mVideoHeight = 0; 现在学习的是第30页,共32页运行结果运行结果现在学习的是第31页,共32页感谢大家观看现在学习的是第32页,共32页