Android MediaPlayer java.io.IOException: Prepare failed.: st



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

我已经尝试了几个不同的流,但我似乎无法让媒体播放器工作。我曾考虑过移动谷歌的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();
} 
}

我还包含了安卓权限:

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

我尝试使用原始流类型(但它抛出了一个不推荐使用的警告):

player.setAudioStreamType(AudioManager.STREAM_MUSIC);

所以我改用了.setAudioAttributes(...)我试图只运行prepare()而不是给出问题标题的prepareAsync(),但我仍然导致相同的错误。我已经研究了实际的错误定义,但没有运气(Android媒体播放器错误(1,-2147483648))。我不认为这是一个源问题,因为我已经尝试了多个其他流。如果我跳过了可能导致错误的关键内容,请告诉我。

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

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

在几秒钟内准备好呼叫。

在安卓 9 中,检查此https://developer.android.com/training/articles/security-config

AndroidManifest.xml add 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>

尝试使用此代码 经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>

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

就我而言,我用这段代码解决了这个错误,因为我在华为模型中收到了错误。

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

我的原始文件夹中有一个本地音乐文件,此错误在特定设备上不断发生。事实证明,问题出在文件格式上。将其从.m4a更改为.mp3,问题就解决了。

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

我的问题可能与您的原因不同,但由于我带着相同的错误消息来到这里,以下是我如何解决它:

就我而言,我试图阅读我在计算机上使用opencv创建并复制到手机上的视频。

错误是我应该使用H264时将其编码为MJPG。 这个答案为我指明了解决方案。

最新更新