移动多媒体编程节选

多媒体文件格式

文件格式定义了物理文件是如何组织并在文件系统上存储的。以一个普通的音频文件来说,它可能主要由两部分数据组成,元数据和音频数据。而元数据和音频数据的存储位置是根据特定规范制定的,音频数据可能按帧顺序存储,也可能一整块存储在文件的某个位置。


编码

编码/解码针对的是多媒体文件的音频或视频文件。这个过程,实际上也就是原数据的压缩和解压缩的过程。以编码方式为准,可以将多媒体文件分为无压缩,无损压缩和有损压缩3类。

1,无压缩

没有对音频或者视频数据做任何的处理,维持原来的文件大小不变。WAV是一种无压缩的音频格式。

2,无损压缩

无损压缩能够在不损失质量的情况下缩小文件大小。对于音频文件而言,无损压缩可以使文件缩小到原文件的50%-60%。无损压缩包括APE,LA,FLAC,Apple Lossless,WMA LossLess等。

3,有损压缩

有损压缩在一定程度上损失了质量,但是大幅度缩小了文件大小。对于音频文件而言,有损压缩可以使文件缩小到原文件的5%-20%。有损压缩的创新之处在于发现了音频数据并非都可以被人耳识别,如果对此类的音频数据进行编码,可以极大的缩小文件尺寸。目前普遍采用的MP3文件,就是有损压缩典型的代表。有损压缩格式主要包括WMA,MPEG audio等


MIDI与其他媒体文件不同,他本身并不包含任何音频数据,它是一个协议,只包含用于产生特定声音的指令,而这些指令包含调用何种MIDI设备的声音,声音的强弱及持续的时间等。电脑把这些指令交由声卡去合成响应的声音。


音频和视频播放

多媒体模块是基于PackVideo的OpenCore引擎。

三种不同的数据源,资源文件,文件系统和网络三种方式来播放多媒体文件。

在播放网络媒体文件时,下载,播放等工作均由底层的PVPlayer来完成,在应用层开发者只需要设置网络文件的数据源即可。网络播放媒体文件时需要调用prepareAsync()方法,而不是prepare()方法。


状态切换图


其中,双箭头为异步操作,单箭头为 同步操作。


要注意的是,调用reset()方法后进入的idle状态如果调用getCurrentPosition()之类的方法会爆出错误,会调用底层系统的 OnErrorListener.onError()方法,MediaPlayer进入error状态,而同时对于new MediaPlayer()出来的,也是处于idle状态的,同样的之类的方法,不会调用onError方法,而且也不会进入error状态。另外,MediaPlayer.create()方法产生的对象来说,是直接进入prepare状态了。最后,对于不再需要的MediaPlayer对象,一定要通过调用release()方法进入end状态,因为这关系到自由的释放问题。


在播放器放音视频文件时,可能发生各种各样的错误,比如说IO错误,多媒体文件格式错误等,正确处理播放过程中的各种错误显得尤为重要,所以需要注册mediaplayer的onerrorlistener,在错误发生时,OnErrorListener.onError()方法会被调用,MediaPlayer对象进入到error状态。如果希望复用MediaPlayer对象并从错误中恢复过来,那么可以调用reset()方法使MediaPlayer再次进入idle状态(实践中有些错误是可以不用reset()的)。总之,监视MediaPlayer的状态是非常重要的,在错误发生之际提示用户,并恢复播放器的状态才是正确的处理方法。


播放视频

播放视频同样可以用mediaplayer,加上surfaceview来渲染界面即可,调用方法是MediaPlayer.setDisplay(SurfaceHolder holder)来设置视频的渲染。


录音

MediaRecorder的状态图

播放和录制是两个截然不同的过程,播放时,播放器需要从多媒体文件中解码,将内容输出到设备,比如说扬声器。而录制时,录制器需要从设定的输入源采集数据,以设定的文件格式输出文件,还有按照设置的编码格式对音频内容进行编码,目前是支持从电话和扬声器两个音频源录制数据。





创建 MediaRecorder 对象只能使用 new 操作符,刚刚创建的 MediaRecorder 处于 idle 状态。MediaRecorder 同样会占用宝贵的硬件资源,因此在不再需要时,应该调用 release()方法销毁 MediaRecorder 对象。在其他状态调用 reset()方法,可以使得 MediaRecorder 对象重新回到 idle 状态,达到复用 MediaRecorder 对象的目的

MediaRecorder 定义了两个内部接口 OnErrorListener 和 OnInfoListener 来监听录制过程中的错误信息。例如,当录制的时间长度达到了最大限制或者录制文件的大小达到了最大文件限制时,系统会回调已经注册的 OnInfoListener 接口的 onInfo()方法。

典型的一个过程的代码如下:

MediaRecorder recorder = new MediaRecorder();
 recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
 recorder.setOutputFile(PATH_NAME);
 recorder.prepare();
 recorder.start();   // Recording is now started
 ...
 recorder.stop();
 recorder.reset();   // You can reuse the object by going back to setAudioSource() step
 recorder.release(); // Now the object cannot be reused
 

你可能感兴趣的:(移动多媒体编程节选)