Android MediaPlayer 出现错误:java.io.IOException: 准备失败:status=0x1。

13

我正在使用Android的MediaPlayer在我的应用程序中设置URL流。我已经尝试了几篇不同的文章来处理退出代码和错误:(1,-2147483648)。

我尝试了几种不同的流,但好像无法让MediaPlayer正常工作。我考虑过转到Google的ExoPlayer,但它更复杂,我不想跳船,以防我错过了什么。

MediaPlayer:

private MediaPlayer player;
String url = "http://199.180.75.118:80/stream";     //temp stream
private void initializeMediaPlayer() {
    player = new MediaPlayer();
    player.setAudioAttributes( new AudioAttributes.Builder()
        .setUsage(AudioAttributes.USAGE_MEDIA)
        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
        .build());

    try { 
        player.setDataSource(url);
        player.prepareAsync();
        player.setOnPreparedListener(new OnPreparedListener() {
            public void onPrepared(MediaPlayer mp) {
                mp.start();
            }
        });
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } 
}

我还包括了安卓权限:

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

我尝试使用原始流类型(但它会抛出一个已弃用的警告):

player.setAudioStreamType(AudioManager.STREAM_MUSIC);
因此,我改用.setAudioAttributes(...)。我尝试只运行prepare()而不是prepareAsync(),这给出了问题的标题,但我仍然遇到同样的错误。我查看了实际错误定义,但没有找到解决方法(Android MediaPlayer error (1, -2147483648))。我认为这不是源代码的问题,因为我已经尝试过多个其他流。如果我跳过了可能导致错误的关键步骤,请告诉我。

编辑 如果有帮助的话,我一直在检查我的调用,发现MediaPlayer从未调用onPrepared(...)。我检查了所有我测试的媒体的Content-Type,它们都是audio/MPEG头文件。所以我不明白为什么MediaPlayer无法访问onPrepared。


1
发布了适用于我的答案。 - Ashvin solanki
@Ashvinsolanki 如果你看我的评论,我已经弄清楚了。谢谢你的帮助! - Lonely Twinky
6个回答

24
private void initializeMediaPlayer() {
        player = new MediaPlayer();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            player.setAudioAttributes(new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_MEDIA)
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                    .build());
        } else {
            player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
        try {
            player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mp.start();
                }
            });
            player.setDataSource(url);
            player.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在几秒钟内调用onPrepared。

在Android 9中,请查看此链接https://developer.android.com/training/articles/security-config

在AndroidManifest.xml中添加networkSecurityConfig属性。

...
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
...

在src/res/xml文件夹中添加network_security_config.xml文件

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

我仍然遇到相同的错误,并且我按照以下步骤创建了明文设置:https://dev59.com/w1cO5IYBdhLWcg3wWgU0#52652182。出于某种原因,我仍然遇到相同的错误,我已经尝试使用SHOUTcast和Icecast服务器,但没有成功。@fancyjyl - Lonely Twinky
出于某种原因,出现了相同的错误。我已经尝试了三个流并得到了相同的结果。我不明白为什么它无法连接到任何流。我一直收到未指定网络安全配置,使用平台默认值和一些关于makeHTTPConnection Cookie Manager的消息,最后打印出MediaPlayerNative和MediaPlayer的相同错误(1,-2147483648)。 - Lonely Twinky
我找到了问题所在,当我回顾我的清单文件时,我发现我把android:usesCleartextTraffic="true"放在了<activity> ... </activity>下面,而不是<application> ... </application>。感谢您的帮助! - Lonely Twinky

8

尝试使用此代码 已在真实设备Vivo V7+ Android 8.1.0上测试

    private MediaPlayer player;
    String url = "http://199.180.75.118:80/stream";     //temp stream
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void initializeMediaPlayer() {
        player = new MediaPlayer();
        player.setAudioAttributes( new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build());

        try {
            //change with setDataSource(Context,Uri);
            player.setDataSource(this, Uri.parse(url));
            player.prepareAsync();
            player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    //mp.start();
                    player.start();
                }
            });
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

请确保在清单文件中定义了权限。

Manifest.xml

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

<Application
  android:usesCleartextTraffic="true"
  ....
  >
  //.....
  </Application>

Ref :: https://developer.android.com/training/articles/security-config

网络安全配置

网络安全配置功能允许应用程序在不修改应用程序代码的情况下,通过安全的声明性配置文件自定义其网络安全设置。这些设置可以针对特定域和特定应用程序进行配置。此功能的主要能力如下:

  • 自定义信任锚点: 自定义应用程序安全连接所信任的证书颁发机构 (CA)。例如,信任特定的自签名证书或限制应用程序信任的公共 CA 集。
  • 仅供调试使用的覆盖: 在没有增加已安装基础风险的情况下,安全地调试应用程序中的安全连接。
  • 明文流量退出: 保护应用程序免受意外使用明文流量的影响。
  • 证书固定: 限制应用程序对特定证书的安全连接。

添加网络安全配置文件

网络安全配置功能使用 XML 文件,在其中指定应用程序的设置。您必须在应用程序的清单中包含一个条目,以指向此文件。以下清单代码摘录演示了如何创建此条目:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
                    ... >
        ...
    </application>
</manifest>

network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

2

我通过将我的文件更改为另一个名称来解决了这个问题,我的音频文件的初始文件名是“john:doe.wav”,Mediaplayer无法播放带有此“:”特殊字符和许多其他字符的文件,因此将文件名更改为“johndoe.wav”解决了这个问题。


1
在我的情况下,我用这段代码解决了这个错误,因为我在华为手机上收到了错误信息。
private void setUpMediaRecorder() {
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mMediaRecorder.setOutputFile(mVideoFileName);
    mMediaRecorder.setVideoEncodingBitRate(10000000);
    mMediaRecorder.setVideoFrameRate(30);
    mMediaRecorder.setVideoSize(320, 240);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    switch (mSensorOrientation) {
        case SENSOR_ORIENTATION_DEFAULT_DEGREES:
            mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
            break;
        case SENSOR_ORIENTATION_INVERSE_DEGREES:
            mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
            break;
    }
    try {
        mMediaRecorder.prepare();
    } catch (Exception e) {
        e.printStackTrace();
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mMediaRecorder.setOutputFile(mVideoFileName);
        mMediaRecorder.setVideoEncodingBitRate(10000000);
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setVideoSize(320, 240);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
        switch (mSensorOrientation) {
            case SENSOR_ORIENTATION_DEFAULT_DEGREES:
                mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
                break;
            case SENSOR_ORIENTATION_INVERSE_DEGREES:
                mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
                break;
        }
        try {
            mMediaRecorder.prepare();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}

1
我在raw文件夹中有一个本地音乐文件,但在某些设备上出现了错误。后来发现问题出在文件格式上。将其从.m4a更改为.mp3,问题得以解决。
我想这是与设备支持的编解码器有关的特定设备问题。

0

我的问题可能与你的不同,但由于我遇到了相同的错误消息而来到这里,所以我来分享一下我是如何解决它的:

在我的情况下,我试图读取一个我用opencv在电脑上创建并复制到手机上的视频。

我的错误是将其编码为MJPG,而我应该使用H264这个答案指引了我找到了解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接