说明
B站播放器,基于FFmpeg(fast forward mpeg),mpeg:国际xxx制定视音频压缩技术标准的组织。主要标准有5个:MPEG-1,MPEG-2,MPEG-4,MPEG-7,MPEG-21。
H.264/H.265:编码协议。H.265是H.264的升级版,在相同的图象质量下,相比于H.264,通过H.265编码的视频大小将减少40%左右。
源码地址:
github地址:https://github.com/bilibili/ijkplayer
- 快速集成
使用默认编译好的so库
支持格式:https://ffmpeg.org/general.html
1、默认不支持格式:avi,mkv,MP3,wma音频,webm
2、默认不支持https
参照github集成即可
# required
allprojects {
repositories {
jcenter()
}
}
dependencies {
# required, enough for most devices.
compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
# Other ABIs: optional
compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'
# ExoPlayer as IMediaPlayer: optional, experimental
compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'
}
-编译so库,支持https,以及更多格式
编译:参照github (If you prefer more codec/format)编译步骤,增加编译openssl,即支持https
// 首先 cd 到 ijkplayer/android/contrib 目录下,Android下编译脚本就放在该目录下
cd android/contrib
// 编译 openssl
./compile-openssl.sh clean
./compile-openssl.sh all
项目集成:编译后源码:android/ijkplayer/。ijkplayer-java(必选),ijkplayer-example下widget包下所有代码(必选),ijkplayer-exo(可选),需要哪种cpu指令类型的so库,可自己选择复制到项目module的jni目录,一般使用v7a。
注意事项:不要去修改ijkplayer-java,widget包的包名,使用tv.danmaku.ijk.media。如果非要修改,需要修改c源码,重新编译,修改方法自己百度。
支持播放项目中raw目录下文件:
实现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;
}
}
在IjkVideoView openVideo方法添加
if (!TextUtils.isEmpty(scheme) && scheme.equals(ContentResolver.SCHEME_ANDROID_RESOURCE)) {
RawDataSourceProvider rawDataSourceProvider = RawDataSourceProvider.create(context, mUri);
if (rawDataSourceProvider != null)
mMediaPlayer.setDataSource(rawDataSourceProvider);
else {
release(false);
return;
}
}