My blog

Add intelligent tagline here

[Android]MediaPlayerでのエラー

MediaPlayerで mp.setDataSource(filePath) としてローカルのMP3ファイルを再生させようとしたら、

W/MediaPlayer(  738): info/warning (1, 26)
I/MediaPlayer(  738): Info (1,26)   Command PLAYER_SET_DATA_SOURCE  completed with an error or info PVMFErrNotSupported
E/MediaPlayer(  738): error (1, -4)

というエラーが出た。 もちろん、filePathは正しいし、ちゃんとファイルの実体があることも確認済。

http://blog.pocketjourney.com/2009/12/27/android-streaming-mediaplayer-tutorial-updated-to-v1-5-cupcake/

を見ると、setDataSourceではFile Descriptorが食えるから、そっちを使えという。具体的にはこんな感じ。

FileInputStream fis = null;
fis = new FileInputStream(mediaFile);
if (fis != null){
  mPlayer.setDataSource(fis.getFD());
}

この記事はversion 1.5だけど、今試しているのは2.1。nullチェックが出来るのでこっちのほうがいいかなぁ。

で、正しいのかどうかは不明だけど、これをすると、確かに上のエラーは出なくなった。しかし、今度はIllegalStateExceptionが出るよ?

E/MediaPlayer(  882): setDataSource called in state 4
W/System.err(  882): java.lang.IllegalStateException

さて、この、 4 という数字がなにを意味しているか。

android.git.kernel.orgから、Androidのソースを見ると、 platform/frameworks/base.git / include / media / mediaplayer.h に以下の定数がある。

enum media_player_states {
    MEDIA_PLAYER_STATE_ERROR        = 0,
    MEDIA_PLAYER_IDLE               = 1 << 0,
    MEDIA_PLAYER_INITIALIZED        = 1 << 1,
    MEDIA_PLAYER_PREPARING          = 1 << 2,
    MEDIA_PLAYER_PREPARED           = 1 << 3,
    MEDIA_PLAYER_STARTED            = 1 << 4,
    MEDIA_PLAYER_PAUSED             = 1 << 5,
    MEDIA_PLAYER_STOPPED            = 1 << 6,
    MEDIA_PLAYER_PLAYBACK_COMPLETE  = 1 << 7
};

4、ということは、なぜかPREPAREINGになっているということ? mPlayer.reset()を最初にかけると、state が0になるなぁ。

というわけで、続く。

と、ここではっと気がつく。 これ、二回setDataSource呼び出しちゃってるじゃん! そりゃだめだわさ…。

というわけで、ちゃんと直したらエラーはでなくなりました。 が、エミュレータで音がならない。どうしてだろう?

ぐぐると、Audioを出す設定が必要だとのこと。というわけで、 –useaudio を起動オプションにつけて再度試す。

無事音が出るようになりました! バカな事してて時間だけが食ってしまった… しかし、media playerに現在のstateを取得するメソッドはないんですね。