現在、インターネットラジオステーションをストリーミングするシンプルなアプリを設計しようとしています。ステーションのURLがあり、Media Playerを次のように設定しています
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(URL);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
エミュレートしてもプログラムはクラッシュしませんが、何も再生されず、次のエラーが表示されます。
start called in state 0
そしてその真下は
Error (-38,0)
誰もがこれが何を意味するか知っていますか?
これらの状態エラーについて少し読みましたが、私のプロジェクトに当てはまるものを見つけることができませんでした。
リスナーを使用して、onPrepared
メソッドでmediaPlayer.start()
を呼び出す必要があります。準備状態に達する前にmediaPlayer.start()
を呼び出しているため、このエラーが発生しています。
これを行う方法を次に示します。
mp.setDataSource(url);
mp.setOnPreparedListener(this);
mp.prepareAsync();
public void onPrepared(MediaPlayer player) {
player.start();
}
Error -38は状態の例外を意味するようです(エラーメッセージが示すように)。たとえば、start()
を呼び出す場合、曲の準備が完了する前、またはpause()
を呼び出す場合は、曲がまったく再生されていない場合でも同様です。
この問題を解決するには、メソッドを呼び出す前にmediaPlayerの状態を確認してください。例えば:
if(mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
さらに、MediaPlayerはイベントメッセージを送信しています。 prepare-eventが必要ない場合でも(このイベントが発生する前に再生を開始しないことをお勧めしますが)、callback-listenerを設定する必要があります。これは、OnErrorListener
、OnCompletionListener
、OnPreparedListener
、およびOnSeekCompletedListener
(seekメソッドを呼び出す場合)にも当てはまります。
リスナーは次の方法で簡単に添付できます
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// Do something. For example: playButton.setEnabled(true);
}
});
メディアプレーヤーの現在の位置(MediaPlayer.getCurrentPosition())を準備しようとしていないときに取得しようとしたときに、このエラーが発生しました。これを回避するには、その状態を追跡し、onPreparedListenerが呼び出された後にのみgetCurrentPosition()メソッドを呼び出します。
これは私のコードであり、テスト済みで正常に動作しています:
package com.example.com.mak.mediaplayer;
import Android.media.MediaPlayer;
import Android.os.Bundle;
import Android.view.View;
import Android.widget.Button;
import Android.app.Activity;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MediaPlayer mpp = MediaPlayer.create(this, R.raw.red); //mp3 file in res/raw folder
Button btnplay = (Button) findViewById(R.id.btnplay); //Play
btnplay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View vone) {
mpp.start();
}
});
Button btnpause = (Button) findViewById(R.id.btnpause); //Pause
btnpause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View vtwo) {
if (mpp.isPlaying()) {
mpp.pause();
mpp.seekTo(0);
}
}
});
}
}
以下のコードでテストしました。うまく働いている
public class test extends Activity implements OnErrorListener, OnPreparedListener {
private MediaPlayer player;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
player = new MediaPlayer();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
player.setDataSource("http://www.hubharp.com/web_sound/BachGavotte.mp3");
player.setOnErrorListener(this);
player.setOnPreparedListener(this);
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
player.release();
player = null;
}
@Override
public void onPrepared(MediaPlayer play) {
play.start();
}
@Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
return false;
}
}
数日前に同じ問題に遭遇しました。私のオーディオMediaPlayerは、高い処理能力を備えたデバイスで正常に動作しますが、低速のデバイスの場合、メディアプレーヤーはしばらく再生せず、LogCatから誤った状態で呼び出されることについて多くの苦情がありました。 start()、pause()、... in onPrepared()のメソッドを呼び出すことで解決しました- OnPreparedListener()以下の通り:
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
........
mediaPlayer.start();
....
songControlBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
mediaPlayer.start();
}
}
});
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
............
}
});
}
});
また、不要になったメディアプレーヤーをリリースしてください。たとえば、バックグラウンドでオーディオやビデオを再生したくない場合は、mediaPlayer.release() in onPause()を呼び出す必要があります。
Androidがデコードできない方法でファイルがエンコードされる場合があります。いくつかのmp4ファイルでも再生できません。別のファイル形式(.3gpがほとんどの場合再生される)を試してみてください。
エラー(-19,0)と(-38,0)の両方を解決しました。再生前に毎回MediaPlayerの新しいオブジェクトを作成し、その後リリースしました。
前 :
void play(int resourceID) {
if (getActivity() != null) {
//Using the same object - Problem persists
player = MediaPlayer.create(getActivity(), resourceID);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
player.release();
}
});
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
}
後:
void play(int resourceID) {
if (getActivity() != null) {
//Problem Solved
//Creating new MediaPlayer object every time and releasing it after completion
final MediaPlayer player = MediaPlayer.create(getActivity(), resourceID);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
player.release();
}
});
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
}
if(length>0)
{
mediaPlayer = new MediaPlayer();
Log.d("length",""+length);
try {
mediaPlayer.setDataSource(getApplication(),Uri.parse(uri));
} catch(IOException e) {
e.printStackTrace();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.seekTo(length);
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();
また、onPreparedListenerで試したがこのエラーが発生しました。最後に、Android Manifest xmlでインターネットの許可を忘れたため、エラーが私のせいであるという解決策を得ました。 :)
<uses-permission Android:name="Android.permission.INTERNET" />
Mediaplayerのサンプルコーディングを使用しました。 StreamService.Javaで使用しました
onCreateメソッド
String url = "http://s17.myradiostream.com:11474/";
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
それは非常にイライラしていました。だから、私は私のために働く解決策を得た。
try {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(file.getAbsolutePath());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
});
}
});
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
私にとってこれはうまくいきました
mp.seekTo(0);
mp.start();
MediaPlayerインスタンスの現在の状態では許可されていないことを行うため、ログにこのメッセージが表示されます。
したがって、それらをキャッチするために、常にエラーハンドラを登録する必要があります(@tidbeckが提案したとおり)。
最初に、MediaPlayer
クラスのドキュメントを見て、状態の意味を理解することをお勧めします。参照: http://developer.Android.com/reference/Android/media/MediaPlayer.html#StateDiagram
ここでの間違いはよくある間違いの1つである可能性がありますが、他の人はここに書いていますが、一般的には、どのメソッドがどの状態で呼び出すのに有効かについてのドキュメントを参照します: http:// developer。 Android.com/reference/Android/media/MediaPlayer.html#Valid_and_Invalid_States
私の例では、メディアプレーヤーがこのプロパティを呼び出すことが許可されていない状態にあるときに呼び出したメソッドmediaPlayer.CurrentPosition
でした。