Media Player called in state 0, error (-38,0)

I am currently trying to design a simple app that streams an internet radio station. I have the URL for the station and am setting up the Media Player like

    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();

The program isn't crashing when emulated, but nothing is playing and I am get the following error:

start called in state 0

and right below it is

Error (-38,0)

Does anyone know what this means?

I've read a little about these state errors, but couldn't find anything that applies to my project.

176416 次浏览

有时候文件的编码方式是 Android 无法解码的。甚至一些 mp4文件也不能播放。请尝试不同的文件格式(.3 gp 大部分时间都在播放) ,请参阅。.

You need to call mediaPlayer.start() in the onPrepared method by using a listener. 之所以出现这个错误,是因为在 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 正在发送事件消息。即使您不需要事件准备(尽管在事件激发之前不启动回放是一个好主意) ,您也必须设置一个回调侦听器。这也适用于 OnErrorListenerOnCompletionListenerOnPreparedListenerOnSeekCompletedListener(如果调用 find 方法)。

监听器可以简单地通过

mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// Do something. For example: playButton.setEnabled(true);
}
});

我测试的代码以下。工作正常

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;
}
}

This is my code,tested and working fine:

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);
}
}
});
}
}

几天前我也遇到了同样的问题。我的音频 MediaPlayer 在高处理能力的设备上运行得很好,但对于速度慢的设备,媒体播放器只是没有播放一段时间,而且 LogCat 有很多抱怨称调用的状态是错误的。所以我通过调用 关于 PreparedListener ()预备()方法中的 Start ()暂停(),... 来解决这个问题,如下所示:

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) {
............


}
});
}
});

还要尝试释放任何你不再需要的媒体播放器。例如,如果你不想播放背景音频或视频,那么你应该调用 暂停()中的 Release ()

You get this message in the logs, because you do something that is not allowed in the current state of your MediaPlayer instance.

因此,您应该始终注册一个错误处理程序来捕获这些内容(如@tidbeck 建议的那样)。

At first, I advice you to take a look at the documentation for the MediaPlayer class and get an understanding of what that with states means. See: http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram

这里的错误很可能是常见的错误之一,其他人在这里写道,但是一般来说,我会看一下关于在什么状态下调用哪些方法是有效的文档: http://developer.android.com/reference/android/media/MediaPlayer.html#Valid_and_Invalid_States

在我的示例中,是方法 mediaPlayer.CurrentPosition,当媒体播放器处于不允许调用此属性的状态时调用该方法。

mp = new MediaPlayer();
AssetFileDescriptor afd = mContext.getAssets().openFd(fileName);
mp.reset();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});


mp.prepareAsync();

I got this error when I was trying to get the current position (MediaPlayer.getCurrentPosition()) of media player when it wasn't in the prepared stated. I got around this by Keeping track of its state and only calling the getCurrentPosition() method after onPreparedListener is called.

我还在 onPreparedListener 上尝试了这个错误,但仍然得到了这个错误。最后我得到了错误是我的错误的解决方案,因为我忘记了在 Android Manifest xml 中的互联网权限。:)

<uses-permission android:name="android.permission.INTERNET" />

我使用了 MediapPlayer 的示例代码,我在 StreamService.java 中使用过
onCreate

String url = "http://s17.myradiostream.com:11474/";
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();

我解决了两个错误(-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();

It was every much frustrated. So, I got solution which works for me.

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();

enter image description here

上面的图片,你可以得到正确的方式。

我是新的机器人编程和我有相同的错误作为这一个。所以我只是重新定义了 mp.createmediaPlayer = MediaPlayer.create (getApplicationContext () ,Settings。系统名称: System.DEFAULT _ RINGTONE _ URI)。这也许不是真正的做法,但对我来说却很有效:

try {
mp = MediaPlayer.create(getApplicationContext(), Settings.System.DEFAULT_RINGTONE_URI);
} catch (Exception e) {
e.printStackTrace();
}


mp.start();

我将 setAudioStreamType 更改为 setAudioAttritribute;

mediaPlayer.setAudioAttributes(AudioAttributes.Builder()
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
.setLegacyStreamType(AudioManager.STREAM_ALARM)
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build());