为什么会遇到这个问题?
我手头有一个小项目,需要将视频打包到apk中,然后实际操作中发现
在播放视频,执行mMediaPlayer.setDataSource()的时候,始终报错
具体的报错如下:
2020-02-04 19:03:35.718 23406-25729/com.kaijun.ningvideo E/MediaPlayerNative: error (1, -2147483648)
2020-02-04 19:03:35.718 23406-23406/com.kaijun.ningvideo E/MediaPlayer: Error (1,-2147483648)
具体的错误当时忘了保存了。但是在网上一查到处是这个错误,说法很多,但是总归,意思有以下几点:
- 路径错误
- 调用方法错误(通过create方式来创建MediaPlayer的时候不需要调用prepare方式)
从我自己的代码来看,大概也指向是路径错误:
try {
mMediaPlayer.reset();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDisplay(mSurfaceView.getHolder());
mMediaPlayer.setDataSource("raw://smallfrog.mp4");
mMediaPlayer.prepareAsync();
} catch (IOException e){
e.printStackTrace();
Log.d(TAG, "playVideo: 视频路径不正确");
}
代码中的处理很草率,但是我对视频的了解不多,只能等以后再加完善。
为了确认是否是路径错误导致的问题,我将视频放到了sd卡目录,然后获取路径设置给MediaPlayer,可以正常播放, 所以,肯定是视频路径出了问题。
后续在网上各种查找,才确认了问题的原因。
简单来说,我们对apk中视频资源的路径的描述出了问题。比如,我用过的两种描述:
- “raw://smallfrog.mp4”
- “raw/smallfrog.mp4”
这两种方式都是在网上查到的,描述的应该都是实际的路径,而实际上,对应的raw目录下的资源并不会被放到实际的目录,而是就集成在apk中,所以实际上,此视频的路径是不存在的。套用网上查到的描述;
Android资源文件大致可以分为两种:
第一种是res目录下存放的可编译的资源文件:
这种资源文件系统会在R.java里面自动生成该资源文件的ID,所以访问这种资源文件比较简单,通过R.XXX.ID即可;
第二种是assets目录下存放的原生资源文件:
因为系统在编译的时候不会编译assets下的资源文件,所以我们不能通过R.XXX.ID的方式访问它们。那我么能不能通过该资源的绝对路径去访问它们呢?因为apk安装之后会放在/data/app/**.apk目录下,以apk形式存在,asset/res和被绑定在apk里,并不会解压到/data/data/YourApp目录下去,所以我们无法直接获取到assets的绝对路径,因为它们根本就没有。
针对此问题,如果我们要访问对应的资源,需要采用如下方式:
try {
AssetFileDescriptor fd = getResources().openRawResouceFd(R.raw.greet_1);
mp.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
mp.start();
fd.close();
} catch (IllegalArgumentException e) {
// handle exception
} catch (IllegalStateException e) {
// handle exception
} catch (IOException e) {
// handle exception
}
亲试有效!
具体对此类的解释还请查看源文件。