【问题标题】:Android MediaPlayer java.io.IOException: Prepare failed.: status=0x1Android MediaPlayer java.io.IOException: Prepare failed.: status=0x1
【发布时间】:2019-04-02 16:31:15
【问题描述】:

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

我尝试了几种不同的流,但似乎无法让 MediaPlayer 工作。我曾考虑过使用 Google 的 ExoPlayer,但它有点复杂,我不想跳槽,以防我遗漏了什么。

媒体播放器:

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

我还加入了android权限:

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

我已尝试使用原始流类型(但它会引发已弃用的警告):

player.setAudioStreamType(AudioManager.STREAM_MUSIC);

所以我改用.setAudioAttributes(...) 我试图只运行prepare() 而不是prepareAsync(),它给出了问题的标题,但我仍然导致同样的错误。我调查了实际的错误定义也没有运气(Android MediaPlayer error (1, -2147483648))。我认为这不是源问题,因为我尝试了多个其他流。如果我跳过了可能导致我的错误的重要内容,请告诉我。

编辑 如果它有帮助的话,我一直在调查我的电话,我发现 MediaPlayer 从来没有打电话给onPrepared(...)。我检查了我一直在测试的所有媒体的内容类型,它们都是音频/MPEG 标头。所以我不明白为什么 MediaPlay 不访问 onPrepared。

【问题讨论】:

  • 发布的答案对我有用
  • @Ashvinsolanki 如果你看看我的 cmets,我就明白了。感谢您的帮助!

标签: android android-mediaplayer urlstream


【解决方案1】:
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://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted/52652182。由于某种原因,我仍然遇到同样的错误,我尝试了 SHOUTcast 和 Icecast 服务器,但都没有运气。 @fancyjyl
  • 由于某种原因出现相同的错误..我尝试了三个具有相同结果的流..我不明白为什么它不会连接到任何流。我不断收到No Network Security Config specified, using platform default 和一些关于 makeHTTPConnection Cookie Manager 的消息,最后它为 MediaPlayerNative 和 MediaPlayer 打印相同的错误 (1, -2147483648)。@fancyjyl
  • 我想通了,当我回顾我的清单文件时,我把android:usesCleartextTraffic="true"放在&lt;activity&gt; ... &lt;/activity&gt;下面而不是&lt;application&gt; ... &lt;/application&gt;谢谢你的帮助!
【解决方案2】:

试试这段代码 用real device 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>

参考::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>

【讨论】:

    【解决方案3】:

    在我的情况下,我用这段代码解决了这个错误,因为我在华为型号中收到错误。

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

    【讨论】:

      【解决方案4】:

      我的原始文件夹中有一个本地音乐文件,并且此错误一直在特定设备上发生。原来问题出在文件格式上。将.m4a改成.mp3,问题就解决了。

      我猜这是与设备支持的编解码器相关的设备特定问题。

      【讨论】:

        猜你喜欢
        • 2022-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-28
        • 1970-01-01
        相关资源
        最近更新 更多