2012-03-08 26 views
18

ファイルへのフルパスがあるとします。 MediaPlayerにそのファイルを読み込む方が良いでしょうか?MediaPlayerのsetDataSource、パスまたはFileDescriptorを使用する方が良いですか?

String filePath = "somepath/somefile.mp3"; 
mediaPlayer.setDataSource(filePath); 

OR

String filePath = "somepath/somefile.mp3"; 
File file = new File(filePath); 
FileInputStream inputStream = new FileInputStream(file); 
mediaPlayer.setDataSource(inputStream.getFD()); 
inputStream.close(); 

それが重要ですか?単にパスを使用する方が簡単ですが、FileDescriptorを使用する余分な作業を行う理由はありますか?

+0

'' ContentProvider'からのコンテンツまたはインスタンスのための資産フォルダから再生しているときFileDescriptor'が使用可能です。 – Jens

答えて

29

実際には、特定の状況に違いがあることがわかります。あなたがmediaPlayer.prepare()を呼び出すときにファイルが保存された方法に応じて、getApplicationContext().getFilesDir()からファイルをロードしようとしている場合

mediaPlayer.setDataSource(String path)は、失敗します。たとえば、new RandomAccessFile(filePath, "rw")を使用してファイルを書き込むと、mediaPlayer.setDataSource(String path)を使用すると、メディアプレーヤはファイルを実際に読み取ることができません。 prepare()はすぐにメディアプレーヤーからerror(1, -2147483648)をトリガーします。基本的にファイルのアクセス権のエラーです。 SDK 9は、おそらくあなたがfalseにownerOnlyを設定することで、この問題を解決できるようになるfile.setReadable (boolean readable, boolean ownerOnly)を導入しました...しかし、あなたは古いSDKをサポートする必要がある場合、それはあなたを助けることはありません。

しかし、mediaPlayer.setDataSource(FileDescriptor fd)はこの問題とメディアプレーヤが正常に許可の問題もなく、まったく同じファイルを準備する必要はありません。

+1

-2147483648はファイルアクセス許可エラーではありません。 – braden

+1

http://www.weston-fl.com/blog/?p=2988 はかかわらず、何らかの理由で、文字列を使用してアプリケーションのファイルディレクトリ内のファイルでメディアプレーヤーを指していることは失敗しますが、ファイル記述子の作品を使用しました。 –

+0

関連するノートで、暗号化されたAPK拡張ファイル(.OBB)からビデオを再生するときは、MediaPlayerでビデオを再生するためにFileDescriptorを使用する必要があります。 MediaPlayerは、OBBファイルを読み取るための適切な権限を持っていないアプリケーションのコンテキスト外からファイルにアクセスしようとします。 'FileDescriptor'を使うことはこの問題を克服します。 – Reinier

2

MediaPlayer.java文字列(パス)及びFDの両方を受け入れるsetDataSource()署名を有します。 どちらも最終的にネイティブのCコードになります。これらのうちの1つは、データソースを1秒に1回より頻繁に設定しないかぎり、わずかに効率が良いかもしれませんが、ごくわずかです。

/** 
* 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; 
+0

ありがとう!おそらく、FileDescriptorがいくつかの自明なメリットをもたらすかもしれないと私は考えました。バッファリングの利点またはいくつかのそのようなこと。 –

関連する問題