我创建了一个流式音频应用程序,它正在某些Android设备上运行,但moto g(6.0.1)API除外。
异常:IOException或MEDIA_ERROR_SYSTEM"错误:(1,-2147483648)"
代码:
URL url = new URL("streaming extracted url");
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String urlStr = uri.toASCIIString();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(urlStr);
player.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
}
});
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.reset();
}
});
player.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
return false;
}
});
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
player.start();
}
});
有人可以帮我解决这个问题吗?我错过了什么吗?
答案 0 :(得分:0)
我遇到过类似且无法解释的问题。我正在使用简单的MediaPlayer来流式传输来自网站的音频。这适用于三星Galaxy S4(Android 5.0.1),但在Pixel(Android 8.1.0)上,音频不会播放。
我正在点击播放按钮上加载URL,显示进度微调器,直到触发MediaPlayer onPrepared侦听器。准备好后,我隐藏了进度条,然后开始播放。
On Pixel,正常的加载/流时间过去(所以我猜文件正在准备中!)onPrepared被触发,没有显示错误,但音频从未播放过!
我们的服务器使用自签名证书,我认为可能是问题,但即使通过http访问文件它也不会在Pixel上播放。我还确认它不是编解码器问题,因为将文件移动到Google云端硬盘并在我的应用中使用直接链接播放该文件可以正常播放。
我不确定它是否是基于服务器的问题,但所有其他文件(图片等)都已投放并显示正常(使用Glide),文件已投放,可通过相同的网址在Chrome中查看加入MediaPlayer!
我刚刚搬到ExoPlayer,它在两台设备上播放都很好..所以我想这是前进的方向!
添加依赖
compile 'com.google.android.exoplayer:exoplayer-core:2.6.1'
单击播放按钮时,如果尚未加载音频,我将加载音频,否则开始播放
if (player == null) {
loadAudio();
} else {
player.setPlayWhenReady(true);
}
我的loadAudio()
private void loadAudio() {
String userAgent = Util.getUserAgent(getActivity(), "SimpleExoPlayer");
Uri uri = Uri.parse(audioUrl);
DataSource.Factory dataSourceFactory = new DefaultHttpDataSourceFactory(
userAgent, null,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
true);
// This is the MediaSource representing the media to be played.
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(uri);
TrackSelector trackSelector = new DefaultTrackSelector();
player = ExoPlayerFactory.newSimpleInstance(getActivity(), trackSelector);
player.addListener(this);
player.prepare(mediaSource);
player.setPlayWhenReady(true);
}
...和状态的ExoPlayer监听器,所以我可以在完成时交换UI中的播放/暂停按钮等
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
audioProgress.setVisibility(View.VISIBLE);
break;
case Player.STATE_ENDED:
handler.removeCallbacks(UpdateAudioTime);
buttonControllerPlay.setVisibility(View.VISIBLE);
buttonControllerPause.setVisibility(View.GONE);
seekBar.setProgress(0);
break;
case Player.STATE_IDLE:
break;
case Player.STATE_READY:
audioProgress.setVisibility(View.GONE);
finalTime = player.getDuration();
startTime = player.getCurrentPosition();
seekBar.setMax((int) finalTime);
seekBar.setProgress((int) startTime);
handler.postDelayed(UpdateAudioTime, 100);
break;
default:
break;
}
}
请记住在停止/销毁时释放播放器
希望可以帮助那些像我一样摸不着头脑的人!
答案 1 :(得分:0)
我已使用以下代码在Moto G5(Android 7.0)上传输音频并且工作正常:
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
mediaPlayer.setAudioAttributes(audioAttributes)
这可以解释这个问题:
应用程序开发人员在创建时应使用音频属性 更新Android 5.0的应用程序。但是,应用程序不是 需要利用属性;他们可以处理遗产 流类型只是或不知道属性(即通用 媒体播放器,对其内容一无所知 播放)。
在这种情况下,框架保持向后兼容性 旧设备和Android版本通过自动翻译旧版本 音频流类型到音频属性。但是,框架确实如此 不强制或保证跨设备,制造商, 或Android版本。