假设我有一个文件的完整路径。将该文件加载到MediaPlayer中,哪种方法更好?
String filePath = "somepath/somefile.mp3";
mediaPlayer.setDataSource(filePath);
或
String filePath = "somepath/somefile.mp3";
File file = new File(filePath);
FileInputStream inputStream = new FileInputStream(file);
mediaPlayer.setDataSource(inputStream.getFD());
inputStream.close();
有关系吗?简单地使用路径似乎更容易,但是有理由为了使用FileDescriptor而做额外的工作吗?
发布于 2012-05-24 02:32:20
实际上,事实证明在某些情况下是有区别的。
调用mediaPlayer.prepare()
时,如果您尝试从getApplicationContext().getFilesDir()
加载文件,则mediaPlayer.setDataSource(String path)
将失败,具体取决于文件的保存方式。例如,如果我使用new RandomAccessFile(filePath, "rw")
编写一个文件,如果您使用mediaPlayer.setDataSource(String path)
,那么该文件实际上不能被mediaplayer读取。prepare()
将立即从mediaplayer触发error(1, -2147483648)
;本质上是一个文件权限错误。SDK9引入了file.setReadable (boolean readable, boolean ownerOnly)
,它可能允许您通过将ownerOnly
设置为false...but来解决此问题,但如果您需要支持较旧的SDK,这对您没有帮助。
但是,mediaPlayer.setDataSource(FileDescriptor fd)
没有这个问题,mediaplayer将成功地准备完全相同的文件,而不会出现权限问题。
发布于 2012-03-09 06:14:01
MediaPlayer.java具有同时接受字符串(路径)和FD的setDataSource()签名。它们最终都会变成原生C代码。尽管其中一种方法的效率可能稍高一些,但它可以忽略不计,除非您设置数据源的频率高于每秒一次。
/**
* Sets the data source (file-path or http/rtsp URL) to use. Call this after
* reset(), or before any other method (including setDataSource()) that might
* throw IllegalStateException in this class.
*
* @param path the path of the file, or the http/rtsp URL of the stream you want to play
* @throws IllegalStateException if it is called
* in an order other than the one specified above
*/
public native void setDataSource(String path) throws IOException, IllegalArgumentException, IllegalStateException;
/**
* Sets the data source (FileDescriptor) to use. It is the caller's responsibility
* to close the file descriptor. It is safe to do so as soon as this call returns.
* Call this after reset(), or before any other method (including setDataSource())
* that might throw IllegalStateException in this class.
*
* @param fd the FileDescriptor for the file you want to play
* @throws IllegalStateException if it is called
* in an order other than the one specified above
*/
public void setDataSource(FileDescriptor fd)
throws IOException, IllegalArgumentException, IllegalStateException {
// intentionally less than LONG_MAX
setDataSource(fd, 0, 0x7ffffffffffffffL);
}
/**
* Sets the data source (FileDescriptor) to use. It is the caller's responsibility
* to close the file descriptor. It is safe to do so as soon as this call returns.
* Call this after reset(), or before any other method (including setDataSource())
* that might throw IllegalStateException in this class.
*
* @param fd the FileDescriptor for the file you want to play
* @param offset the offset into the file where the data to be played starts, in bytes
* @param length the length in bytes of the data to be played
* @throws IllegalStateException if it is called
* in an order other than the one specified above
*/
public native void setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException;
https://stackoverflow.com/questions/9625680
复制相似问题