遇到此问题setDataSource用FileDescriptor代替即可,如下面红色的代码。
MediaPlayer player = new MediaPlayer();
try {
Log.d(TAG, recorder.getFileName());
player.setAudioStreamType(AudioManager.STREAM_RING);
FileInputStream fis = new FileInputStream(new File(filePath));
player.setDataSource(fis.getFD());
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
mp.release();
}
});
player.setLooping(false);
player.prepare();
player.setVolume(1f, 1f);
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
将媒体文件push到sdcard目录
启动模拟器后,在DDMS透视图中,选择File Explorer,选择/mnt/sdcard目录,点击视图工具栏的+,将选择的文件push进去。
注:如果push失败,提示Read-Only File System,请将sdcard目录授以读+写权限,命令为
- $ adb shell mount -o remount rw /
使用ls -l查看指定目录下的文件及文件夹详细信息,权限信息在第一列。如
- $ adb shell
- # ls -l /mnt/sdcard
注:在File Explorer中,已经列出了各文件夹和文件的权限。如果sdcard没有读写权限,请先授权。
使用VideoView渲染媒体
为什么要用VideoView?VideoView使用起来简单,而且封装了播放器,如播放错误,android会给出警告提示 ,不需要用户编程处理这些异常。代码如下:
- viedoView.setVideoPath(filePath);//filePath = “/sdcard/test.mp3”;
- videoView.start();
简单是简单,但不幸的是,如果媒体源没问题,但播放异常的话,定位就复杂一些了。
注:启动后,系统提示”对不起,该视频无法播放“,在LogCat中看到MediaPlayer和VideoView都指打印了一条error(1, -2147483648)的LOG。
导致此错误的典型原因有:
1,文件路径不对,如目录错误,不存在的URL及URI
2,媒体文件错误,或不支持的格式
3,缺少权限
经过debug,发现问题出在VideoView#openVidio的mMediaPlayer.prepareAsync();处。
prepare失败了,prepare的方法有两个,还有一个是prepare(),官网给的说明,它位的不同之处是,前者是异步执行。但个人认为,应该还有一个不同之处,前者不会抛出异常。
使用MediaPlayer
使用MediaPlayer也很简单。如下代码所示:
- MediaPlayer mp = new MediaPlayer();
- mp.setDataSource(this,uri);
- mp.prepare();// 使用mp.prepareAsync(),不会抛出异常,但有错误LOG,为error(38,0);
- mp.start();
注:对上面那个无法播放的问题,可以在prepare()处捕获到IO异常:
- java.io.IOException: Prepare failed.: status=0x1
对于此异常,有网友说模拟器对mp3支持不好,建议将mp3换成ogg格式再试。也有的说,使用类似以下方法
- // FileInputStream fis = new FileInputStream(file);
- // mp.setDataSource(fis.getFD());
前者我没有试过,如果有度过的,请告诉我结果。我使用的是后者,发现在创建输入流时,抛出了FileNotFoundException:file not exists(permission denied),关键在permission denied这句,应该是缺少权限,但媒体文件是有权限的,sdcard目录没有,于是给sdcard目录授以最大权限。
- $ adb shell
- # chmod 777 /mnt/sdcard
讨论
讨论1:在准备工作中,已经使用
- $ adb shell mount -o remount rw /
或
- $ adb shell mount -o remount 777 /
给目录授权过了,但为何sdcard目录还是无权限?
讨论2:Android对网络播放是否存在bug,对于本地可以正常播放的3gp,mp4等视频,放到服务器中使用http get方式进行网络播放,却只有少数片源可以播放,大多数在prepare()时就抛出了异常。