update: 在更改代碼完后記得 Bulid -> Clean Project, 不然可能因?yàn)榫彺嬖斐墒?
平時(shí)播放視頻用的是官方DEMO下的IjkVideoView, 如果按照傳統(tǒng)方法播放raw資源文件下的視頻是不行的.
//該方法適用在系統(tǒng)自帶的VideoView中使用, 在Ijk中無(wú)法識(shí)別
String path = "android.resource://" + getPackageName() + "/" + R.raw.filename;
查閱了半天資料, 試了多種方式, 最后篩選了其中有用的兩篇, 現(xiàn)整理出來(lái)大家可以直接拿去用.
1. 實(shí)現(xiàn)接口IMediaDataSource
public class RawDataSourceProvider implements IMediaDataSource {
private AssetFileDescriptor mDescriptor;
private byte[] mMediaBytes;
public RawDataSourceProvider(AssetFileDescriptor descriptor) {
this.mDescriptor = descriptor;
}
@Override
public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
if(position + 1 >= mMediaBytes.length){
return -1;
}
int length;
if(position + size < mMediaBytes.length){
length = size;
}else{
length = (int) (mMediaBytes.length - position);
if(length > buffer.length)
length = buffer.length ;
length--;
}
System.arraycopy(mMediaBytes, (int) position, buffer, offset, length);
return length;
}
@Override
public long getSize() throws IOException {
long length = mDescriptor.getLength();
if(mMediaBytes == null){
InputStream inputStream = mDescriptor.createInputStream();
mMediaBytes = readBytes(inputStream);
}
return length;
}
@Override
public void close() throws IOException {
if(mDescriptor != null)
mDescriptor.close();
mDescriptor = null;
mMediaBytes = null;
}
private byte[] readBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
public static RawDataSourceProvider create(Context context, Uri uri){
try {
AssetFileDescriptor fileDescriptor = context.getContentResolver().openAssetFileDescriptor(uri, "r");
return new RawDataSourceProvider(fileDescriptor);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
2. 在IjkVideoView的openVideo()中進(jìn)行修改
因?yàn)槲业捻?xiàng)目都是在4.4以上, 并且需求簡(jiǎn)單, 只是普通的方法一個(gè)視頻, 所以沒有過(guò)多的測(cè)試, 這里如果大家有什么需求, 請(qǐng)自己完善.
// 我將此段代碼添加在else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){} 中
//判斷Uri是否是包含android.resource
if(mUri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE)){
RawDataSourceProvider rawDataSourceProvider = RawDataSourceProvider.create(context, mUri);
mMediaPlayer.setDataSource(rawDataSourceProvider);
}
完成.
接下來(lái)只要像平時(shí)一樣使用就可以了, setVideoPath的path(或者setVideoUri) 獲取依然使用開頭的方式拼接.
參考和部分代碼來(lái)源:
https://github.com/Bilibili/ijkplayer/issues/1013
http://www.cnblogs.com/xwgblog/p/5287151.html