MediaPlayer.prepare 在播放 m4a 文件时抛出 IllegalStateException

发布于 2024-10-08 00:11:53 字数 634 浏览 0 评论 0 原文

我有一个使用 MediaPlayer 流式传输的歌曲列表。有些歌曲始终有效,而另一些则始终无效。我看不出这些文件之间有什么区别,而且它们似乎在 iTunes 等中播放得很好。

当歌曲失败时,它会在 mediaPlayer.prepare() 行上抛出 IllegalStateException。抛出的 IllegalStateException 中没有有用的信息,(detailMessage 为 null,stackState 为 null)

这是我的代码

try {
    mediaPlayer.setDataSource(media.url);
    setPlayerState(PlayerState.PREPARING);
    mediaPlayer.prepare();
} catch (Exception e) {
    e.printStackTrace();
    Log.e(TAG, "bad stream");
}

这是不起作用的文件的 url: skdy.bryceb.dev.mediarain.com/song.m4a

这是一个可行的方法: skdy.bryceb.dev.mediarain.com/song2.m4a

有什么想法为什么这对某些歌曲有效而对其他歌曲无效?

I have a list of songs that I'm streaming using the MediaPlayer. Some of the songs consistently work and others consistently do not work. I can't see a difference between these files, and they seem to play fine in itunes and such.

When the songs fail it is throwing an IllegalStateException on the mediaPlayer.prepare() line. The IllegalStateException that is thrown has no useful info in it, (detailMessage is null, stackState is null)

Here is my code

try {
    mediaPlayer.setDataSource(media.url);
    setPlayerState(PlayerState.PREPARING);
    mediaPlayer.prepare();
} catch (Exception e) {
    e.printStackTrace();
    Log.e(TAG, "bad stream");
}

Here is a url to the file that does NOT work:
skdy.bryceb.dev.mediarain.com/song.m4a

Here is one that DOES work:
skdy.bryceb.dev.mediarain.com/song2.m4a

Any ideas why this works on some songs and fails on others?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沧笙踏歌 2024-10-15 00:11:53

谢谢MisterSquonk,我确信这种方法会起作用。

在我的特殊情况下,在用头撞墙一段时间后,我意识到在某些歌曲上,我在播放器状态设置为准备之前就达到了缓冲量。所以我添加了一个检查以确保 MediaPlayer 处于“PREPARED”状态,然后它工作得很好:

// Media prepared listener
    mediaPlayer.setOnPreparedListener(
            new MediaPlayer.OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    setPlayerState(PlayerState.PREPARED);
                }
            });

    // Media buffer listener
    mediaPlayer.setOnBufferingUpdateListener(
            new MediaPlayer.OnBufferingUpdateListener() {
                public void onBufferingUpdate(MediaPlayer mp, int percent) {

                    // Sometimes the song will finish playing before the 100% loaded in has been
                    // dispatched, which result in the song playing again, so check to see if the 
                    // song has completed first
                    if(getPlayerState() == PlayerState.COMPLETED)
                        return;

                    if(getPlayerState() == PlayerState.PAUSED)
                        return;

                    // If the music isn't already playing, and the buffer has been reached
                    if(!mediaPlayer.isPlaying() && percent > PERCENT_BUFFER) {
                        if(getPlayerState() == PlayerState.PREPARED)
                        {
                            mediaPlayer.start();
                            setPlayerState(PlayerState.PLAYING);
                        }
                        //if it isn't prepared, then we'll wait till the next buffering
                        //update
                        return;
                    }
                }
            });

Thanks MisterSquonk I'm sure that way would work.

In my particular case after beating my head against the wall for a while I realized that on some songs, I was getting to the buffered amount before the player state was getting set to prepared. So I added a check to make sure that the MediaPlayer was in the "PREPARED" state and then it worked great:

// Media prepared listener
    mediaPlayer.setOnPreparedListener(
            new MediaPlayer.OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    setPlayerState(PlayerState.PREPARED);
                }
            });

    // Media buffer listener
    mediaPlayer.setOnBufferingUpdateListener(
            new MediaPlayer.OnBufferingUpdateListener() {
                public void onBufferingUpdate(MediaPlayer mp, int percent) {

                    // Sometimes the song will finish playing before the 100% loaded in has been
                    // dispatched, which result in the song playing again, so check to see if the 
                    // song has completed first
                    if(getPlayerState() == PlayerState.COMPLETED)
                        return;

                    if(getPlayerState() == PlayerState.PAUSED)
                        return;

                    // If the music isn't already playing, and the buffer has been reached
                    if(!mediaPlayer.isPlaying() && percent > PERCENT_BUFFER) {
                        if(getPlayerState() == PlayerState.PREPARED)
                        {
                            mediaPlayer.start();
                            setPlayerState(PlayerState.PLAYING);
                        }
                        //if it isn't prepared, then we'll wait till the next buffering
                        //update
                        return;
                    }
                }
            });
羞稚 2024-10-15 00:11:53

好的,我在“沙盒”应用程序/活动中编写了一个最小的 Mediaplayer 实现,我总是保留备用以进行测试。

我可能是错的,但如果您通过网络流式传输这些歌曲,则需要在 URL 前面加上 http:// 前缀。

我逐字尝试了 Winamp 和 Chrome 的 url(无协议前缀字符串),它们工作得很好,尽管这两个应用程序可能都会使用某种形式的智能来确定如何连接/流式传输。

如果我在 mediaPlayer 代码中尝试这样做,我会得到与您相同的异常,但如果我在 URL 中添加 http:// 前缀,则歌曲可以正常播放。

示例...

// Activity scope
Button button;
CheckBox checkBox;
String url = "";

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //button declared in my activity
    button = (Button)findViewById(R.id.button);
    button.setOnClickListener(this);

    if (!checkBox.isChecked())
        url = getString(R.string.url_song1);
    else
        url = getString(R.string.url_song2);

    mediaPlayer = new MediaPlayer();
}

@Override
public void onClick(View arg0) {
    try {
        Log.i(TAG, "onClick() entered...");
        mediaPlayer.setDataSource(url);
        Log.i(TAG, "Preparing mediaplayer...");
        mediaPlayer.prepare();
        Log.i(TAG, "Starting mediaplayer...");
        mediaPlayer.start();
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "bad stream");
    }       
}

如果我将歌曲复制到 SD 卡,它们都可以正常播放,并且只要互联网 URL 字符串具有“http://”前缀,它们也可以正常播放。

OK, I hacked together a minimal Mediaplayer implementation in a 'sandbox' app/activity I always keep spare for testing.

I might be wrong but if you're streaming these songs over the net, you'll need to prefix the url with http://.

I tried the urls with Winamp and Chrome verbatim (no protocol prefix string) and they worked fine although it's likely both of those applications will use some form of intelligence to work out how to connect/stream.

If I tried that in my mediaPlayer code, I get the same exception as you but if I prefix the urls with http:// the songs play fine.

Example...

// Activity scope
Button button;
CheckBox checkBox;
String url = "";

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //button declared in my activity
    button = (Button)findViewById(R.id.button);
    button.setOnClickListener(this);

    if (!checkBox.isChecked())
        url = getString(R.string.url_song1);
    else
        url = getString(R.string.url_song2);

    mediaPlayer = new MediaPlayer();
}

@Override
public void onClick(View arg0) {
    try {
        Log.i(TAG, "onClick() entered...");
        mediaPlayer.setDataSource(url);
        Log.i(TAG, "Preparing mediaplayer...");
        mediaPlayer.prepare();
        Log.i(TAG, "Starting mediaplayer...");
        mediaPlayer.start();
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "bad stream");
    }       
}

If I copy the songs to my SD card both play fine and as long as the internet url strings have an 'http://' prefix then they also work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文