媒体播放器在状态0中调用,错误(-38,0)


105

我目前正在尝试设计一个流互联网广播电台的简单应用。我有该电台的网址,并且正在像设置媒体播放器

    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)

有人知道这意味着什么吗?

我已经阅读了一些有关这些状态错误的信息,但找不到适用于我的项目的任何信息。




@SmashCode请将另一个答案标记为已接受,因为我的答案完全没有用。
tidbeck

Answers:


119

您需要使用侦听器来调用mediaPlayer.start()onPrepared方法。之所以收到此错误,是因为您要mediaPlayer.start()在错误到达准备状态之前进行调用。

这是您可以做到的:

mp.setDataSource(url); 
mp.setOnPreparedListener(this);
mp.prepareAsync();

public void onPrepared(MediaPlayer player) {
    player.start();
}

如果我们不希望它立即开始怎么办?即使我初始化播放器并等待一分钟左右,我还是第一次尝试播放它,除非我在onPrepared
Elliptica

1
您之前已经准备好了,还记得您已经准备好了。同时,您尝试记住是否要运行它。当它们都准备好并且要运行时,就可以启动它。
维克多·帕洛格(VictorPaléologue)

33

似乎错误-38表示状态异常(如错误消息所指示)。例如,如果您start()在歌曲准备好之前致电,或在致电时致电pause(),即使该歌曲根本没有播放。

要解决此问题,请在调用方法之前检查mediaPlayer的状态。例如:

if(mediaPlayer.isPlaying()) {
    mediaPlayer.pause();
}

此外,MediaPlayer正在发送事件消息。即使您不需要准备事件(尽管在触发此事件之前不开始回放也是一个好主意),也必须设置一个回调侦听器。这也为成立OnErrorListenerOnCompletionListenerOnPreparedListenerOnSeekCompletedListener(如果调用seek方法)。

听众可以简单地通过

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

我的情况是在不玩游戏的玩家上调用pause()
stevo.mit 2015年

在无效状态下调用mediaPlayer.isPlaying()将使媒体播放器进入错误状态。最好维护一个明确的枚举来维护状态。
Madeyedexter,2013年

14

当我尝试获取媒体播放器的当前位置(不在准备好的声明中时)时,出现此错误。我通过跟踪其状态并仅在调用onPreparedListener之后调用getCurrentPosition()方法来解决此问题。


您怎么知道是因为这个原因?
AdamMc331 '16

9

这是我的代码,经过测试,可以正常工作:

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

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

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

并更新到SetAudioStreamType(..)使用SetAudioAttributes(...)
皮埃尔·

4

我几天前遇到了同样的问题。我的音频MediaPlayer在具有高处理能力的设备上可以正常工作,但是对于速度较慢的设备,媒体播放器只是无法播放一段时间,而从LogCat上,它有很多抱怨称状态错误。因此,我通过在OnPreparedListener()的onPrepared()方法中调用start()pause(),... 的调用来解决此问题,如下所示:

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


3

有时,文件是以Android无法解码的方式进行编码的。甚至某些mp4文件也无法播放。请尝试使用其他文件格式(大多数时候播放.3gp文件),然后查看..


46
我不能要求互联网广播电台更改其文件格式。
SmashCode 2012年

您会收到“无法播放此视频”弹出窗口吗?你如何解决?我发现了错误,但是无论如何都得到了这种模式,并且由于媒体来自公共API,因此我无法控制媒体的来源。如果有人知道如何防止出现“无法播放此视频”模式,我将不胜感激。
卡夫蒂2014年

您是否尝试设置错误侦听器。MediaPlayer mp = new MediaPlayer(){@Override public void setOnErrorListener(android.media.MediaPlayer.OnErrorListener listener){//在这里做一些事情。mp.setDataSource(..
Rukmal Dias


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媒体播放器处于不允许调用此属性的状态时调用的method 。


0

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

}

}


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

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


0

我也遇到了我使用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();

-1

我刚才遇到了同样的问题,在一楼的朋友是对的,您start()在错误的时间调用了,您应该为prepare()或prepareSync()使用此方法设置监听器mediaPlayer.setOnPreparedListener(this);在准备之前,请在此回调调用中进行操作。start()这可能会解决您的问题。我已经尝试过了。


你可以再详细一点吗?
Karthik AMR 2014年

抱歉,英语不是我的母语,我也不擅长……但是我只想帮助其他有相同问题的人,仅此而已。
peerless2012 2014年

-1

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

-2
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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.