【问题标题】:mediaPlayer error -38,0媒体播放器错误 -38,0
【发布时间】:2013-08-28 07:43:10
【问题描述】:

我尝试做简单的在线电台播放器。这是流http://radio-electron.ru:8000/96的地址这是我的代码。

MyActivity.java

package com.example.untitled2;

import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.IOException;

public class MyActivity extends Activity {

    MediaPlayer mediaPlayer;
    Button playButton;


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

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
        mediaPlayer = new MediaPlayer();
        playButton = (Button)findViewById(R.id.button);

        playButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(mediaPlayer.isPlaying())
                    mediaPlayer.stop();
                else {
                    try {

                        mediaPlayer.setDataSource(getApplicationContext(), Uri.parse("http://radio-electron.ru:8000/96"));
                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                        mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                            @Override
                            public boolean onError(MediaPlayer mediaPlayer, int i, int i2) {
                                Toast.makeText(getApplicationContext(), "ERROR " + i, Toast.LENGTH_LONG).show();
                                playButton.setEnabled(false);
                                Log.d("radio", "error " + i + " " + i2);
                                return false;  //To change body of implemented methods use File | Settings | File Templates.
                            }
                        });
                        mediaPlayer.prepareAsync();
                    }
                    catch (IOException e) {
                        Toast.makeText(getApplicationContext(), "ERROR " + e, Toast.LENGTH_LONG).show();
                        Log.d("radio", "error " + e);
                    }
                    mediaPlayer.start();
                }
            }
        });
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:orientation="vertical"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
        >
    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="New Button"
            android:id="@+id/button"
            android:layout_gravity="center"/>
</FrameLayout>

我不知道,为什么我得到 -(38, 0) 代码,它是什么意思。 我使用 Intellij IDEA 并在 Android 2.3 和 4.2 模拟器上尝试此代码并遇到一些问题。

【问题讨论】:

    标签: java android android-mediaplayer


    【解决方案1】:

    -38 指的是来自errno.h 的ENOSYS 错误代码(参见此解释https://stackoverflow.com/a/15206308/768935)

    您似乎试图在准备完成之前开始播放。使用setOnPreparedListener()方法设置准备监听,准备完成后才调用start()方法。

    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
      public void onPrepared(MediaPlayer mp) {
          mp.start();
      }
    });
    mediaPlayer.prepareAsync();
    

    并从代码中删除当前的mediaPlayer.start() 调用。

    【讨论】:

    • 即使在 start() 之前使用 prepare() 方法,我也会遇到同样的错误。并且 prepare() 同步工作。所以玩家绝对应该在 start() 之前做好准备。它只发生在某些文件上。
    • @ka3ak 很有趣。如果您可以将其作为问题发布并提供重现它的方法,我相信会有人可以帮助您。
    • 我已经找到了原因。文件路径包含#,但我使用URL设置数据源。我只是想指出,错误不仅可能是由于准备不完整造成的。
    【解决方案2】:

    我在 MediaPlayer 上调用getDuration(); 得到了我的-38 错误在它准备好之前。


    值得检查MediaPlayer 文档。

    有一段以It is a programming error to invoke methods such as getCurrentPosition()...开头

    在 MediaPlayer 准备好之前有一个不适合调用的方法列表,这反过来可能导致-38。

    【讨论】:

    • 你拯救了我的夜晚!谢谢。
    • 这件事发生在我身上! prepare() 和 start() 都可以调用!不幸的是,主线程在错误的时刻调用了 getCurrentPosition() 和 getDuration()。我通过创建一个包装类来修复:github.com/carlosrafaelgn/FPlayAndroid/blob/master/…
    【解决方案3】:

    您最好在 Mediaplayer 启动之前检查您是否正在执行任何与 播放状态 相关的操作,例如 getCurrentPosition()。

    【讨论】:

    • 酷,这就是我的情况:我在调用onPrepared() 监听器之前调用了mediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);。
    【解决方案4】:

    错误码-38应该对应INVALID_OPERATION。

    造成这种情况的一个可能原因是您在调用start 之前没有等待prepareAsync 完成。您应该设置一个onPreparedListener 并仅在调用onPrepared 时启动MediaPlayer。

    【讨论】:

      【解决方案5】:

      @allprog 和@Michael 是对的。但是还有另一种方式,如果不想使用prepareAsync(),就使用prepare()。也就是阻塞,只有在准备好的时候才返回。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多