最简单的MediaDataSource实现示例:
import android.media.MediaDataSource;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.IOException;
import java.io.InputStream;
@RequiresApi(api = Build.VERSION_CODES.M)
public class InputStreamMediaDataSource extends MediaDataSource {
private InputStream is;
private long streamLength = -1, lastReadEndPosition;
public InputStreamMediaDataSource(InputStream is, long streamLength) {
this.is = is;
this.streamLength = streamLength;
if (streamLength <= 0){
try {
this.streamLength = is.available(); //Correct value of InputStream#available() method not always supported by InputStream implementation!
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public synchronized void close() throws IOException {
is.close();
}
@Override
public synchronized int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
if (position >= streamLength)
return -1;
if (position + size > streamLength)
size -= (position + size) - streamLength;
if (position < lastReadEndPosition) {
is.close();
lastReadEndPosition = 0;
is = getNewCopyOfInputStreamSomeHow();//new FileInputStream(mediaFile) for example.
}
long skipped = is.skip(position - lastReadEndPosition);
if (skipped == position - lastReadEndPosition) {
int bytesRead = is.read(buffer, offset, size);
lastReadEndPosition = position + bytesRead;
return bytesRead;
} else {
return -1;
}
}
@Override
public synchronized long getSize() throws IOException {
return streamLength;
}
}
要将其与 API >= 23 一起使用,您必须提供 streamLength 值,并且如果(何时)MediaPlayer 返回 - 即 position < lastReadEndPosition,您必须知道如何创建 InputStream 的新副本。
用法示例:
你必须创建Activity,初始化MediaPlayer类(有很多文件播放的例子)并放置以下代码而不是旧的player.setDataSource("/path/to/media/file.3gp")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
File file = new File("/path/to/media/file.3gp");//It is just an example! If you have real file on the phone memory, you don't need to wrap it to the InputStream to play it in MediaPlayer!
player.setDataSource(new InputStreamMediaDataSource(new FileInputStream(file), file.length()));
} else
player.setDataSource(this, mediaUri);
如果您的文件是 Google Drive 上的对象 com.google.api.services.drive.model.File 和 com.google.api.services.drive.Drive drive,您可以获得
InputStream is = drive.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute().getContent();
在Build.VERSION.SDK_INT < Build.VERSION_CODES.M的情况下,我必须在Android设备的本地主机上设置HTTP服务器(通过NanoHTTPd)并通过uri-player.setDataSource(this, mediaUri)将字节流通过该服务器传输到MediaPlayer