我目前正在尝试设计一个简单的应用程序来流式传输互联网广播电台。我有电台的URL,我正在设置媒体播放器,如
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)
有谁知道这意味着什么?
我已经阅读了一些有关这些状态错误的内容,但找不到任何适用于我的项目的内容。
答案 0 :(得分:106)
您需要使用侦听器在mediaPlayer.start()
方法中调用onPrepared
。
您收到此错误是因为您在mediaPlayer.start()
到达准备状态之前调用它。
以下是如何做到这一点:
mp.setDataSource(url);
mp.setOnPreparedListener(this);
mp.prepareAsync();
public void onPrepared(MediaPlayer player) {
player.start();
}
答案 1 :(得分:31)
似乎错误-38表示状态异常(如错误消息所示)。例如,如果您在歌曲准备好之前或拨打start()
时拨打pause()
,即使该歌曲根本没有播放也是如此。
要解决此问题,请在调用方法之前检查mediaPlayer的状态。例如:
if(mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
此外,MediaPlayer正在发送事件消息。即使您不需要准备好的事件(尽管在此事件被触发之前不开始播放也是个好主意),您必须设置一个回调侦听器。这也适用于OnErrorListener
,OnCompletionListener
,OnPreparedListener
和OnSeekCompletedListener
(如果您调用搜索方法)。
只需通过
附加听众mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// Do something. For example: playButton.setEnabled(true);
}
});
答案 2 :(得分:12)
当我试图获取媒体播放器的当前位置(MediaPlayer.getCurrentPosition())时,我遇到了这个错误。我通过跟踪它的状态并在调用onPreparedListener之后只调用getCurrentPosition()方法来解决这个问题。
答案 3 :(得分:7)
这是我的代码,经过测试且运行良好:
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);
}
}
});
}
}
答案 4 :(得分:4)
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;
}
}
答案 5 :(得分:3)
前几天我遇到了同样的问题。我的音频MediaPlayer在具有高处理能力的设备上运行良好,但对于速度较慢的设备,媒体播放器只是没有播放一段时间,而且从LogCat开始,它有很多人抱怨调用错误状态。所以我通过调用 start(), pause(),... 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) {
............
}
});
}
});
还尝试释放您不再需要的任何媒体播放器。例如,如果您不想在背景上播放音频或视频,则应在 onPause()中调用 mediaPlayer.release()。
答案 6 :(得分:3)
有时,文件以Android无法解码的方式进行编码。甚至一些mp4文件也无法播放。请尝试不同的文件格式(大部分时间都播放.3gp)并查看..
答案 7 :(得分:1)
我解决了两个错误(-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();
}
});
}
}
答案 8 :(得分:0)
您在日志中收到此消息,因为您在MediaPlayer实例的当前状态下执行了某些操作。
因此,您应该始终注册一个错误处理程序来捕获这些内容(如@tidbeck建议的那样)。
首先,我建议您查看MediaPlayer
课程的文档,并了解状态的含义。请参阅: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
,我在媒体播放器处于状态时调用,不允许调用此属性。
答案 9 :(得分:0)
我在使用onPreparedListener时遇到了此错误,但仍然出现此错误。最后我得到了错误是我的错误的解决方案,因为我忘记了Android Manifest xml中的互联网权限。 :)
<uses-permission android:name="android.permission.INTERNET" />
我使用了媒体播放器的示例编码。我在StreamService.java中使用了
onCreate方法
String url = "http://s17.myradiostream.com:11474/";
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
答案 10 :(得分:0)
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();
答案 11 :(得分:0)
令人非常沮丧。所以,我得到的解决方案对我有用。
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();
}
答案 12 :(得分:0)
对我来说这很有用
mp.seekTo(0);
mp.start();
答案 13 :(得分:0)
我是android编程的新手,并且与此错误相同。所以我只是简单地重新定义了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();
答案 14 :(得分:0)
我将setAudioStreamType更改为setAudioAttributes;
mediaPlayer.setAudioAttributes(AudioAttributes.Builder()
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
.setLegacyStreamType(AudioManager.STREAM_ALARM)
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build());
答案 15 :(得分:-1)
我之前遇到过同样的问题,一楼的朋友是对的,你在错误的时间调用start()
,你应该为prepare()或prepareSync()
设置一个监听器方法mediaPlayer.setOnPreparedListener(this)
;在准备之前,在此回拨电话start()
中。它可以解决您的问题。我已经尝试过了。
答案 16 :(得分:-1)
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();
答案 17 :(得分:-1)