bilibili/ijkplayer

Can the IjkMediaPlayer play the Android raw resource files?

yjwfn opened this issue · 11 comments

yjwfn commented

I have a video in Android raw directory.

Like this:
android.resource://com.lianlian.fitness/raw/2131165184

Can The IjkMediaPlayer play the Uri?

No.
ijkplayer doesn't know what "android.resource" is.

how to modify the dir let ijkplayer play?

Implement IMediaDataSource

yjwfn commented

@bbcallen

I called the setDataSource by:

  if(mUri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE)) {
               AssetFileDescriptor fileDescriptor =  getContext().getContentResolver().openAssetFileDescriptor(mUri, "r");
               IMediaDataSource dataSource = new RawDataSourceProvider(fileDescriptor);
               if(fileDescriptor != null)
                   mMediaPlayer.setDataSource(dataSource);
                else{
                   release(false);
                   return ;
               }
            }

I implement IMediaDataSource by myself but ijkplayer does't working.Are there any problems?

class RawDataSourceProvider implements IMediaDataSource{

    AssetFileDescriptor mDescriptor;

    public RawDataSourceProvider(AssetFileDescriptor descriptor) {
        this.mDescriptor = descriptor;
    }

    @Override
    public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {

        InputStream is = mDescriptor.createInputStream();
        if(is != null) {
           return is.read(buffer, offset, size);
        }

        return -1;
    }

    @Override
    public long getSize() throws IOException {
        return mDescriptor.getLength();
    }

    @Override
    public void close() throws IOException {
        mDescriptor.close();
    }
}

change
return mDescriptor.getLength();
to
return inputStream.available();

yjwfn commented

@linwea Does it normally work for you ?

播放本地资源要怎么填URI,找不到啊,不科学

I use this: (on kotlin)
class AssetMediaSource(val context: Context, val path: String) : IMediaDataSource {

private val inputStream: InputStream by lazy { context.assets.open(path, AssetManager.ACCESS_RANDOM) }
private var position: Long = 0

override fun readAt(position: Long, buffer: ByteArray?, offset: Int, size: Int): Int {
    if(size <= 0) {
        return size
    }
    if(this.position != position) {
        inputStream.reset()
        inputStream.skip(position)
        this.position = position
    }
    Log.d("AssetMediaSource",  "postion: $position offset: $offset, size: $size")
    val n = inputStream.read(buffer, offset, size)
    this.position += n
    return n
}

override fun getSize(): Long {
    val size = inputStream.available().toLong()
    Log.d("AssetMediaSource", "getSize(): $size")
    return size
}

override fun close() {
    Log.d("AssetMediaSource", "close()")
    inputStream.close()
}

}

yhnu commented

mark