【问题标题】:Android Media Player Streaming not workingAndroid 媒体播放器流媒体不起作用
【发布时间】:2018-01-07 17:59:15
【问题描述】:

我创建了一个流式音频应用程序,它可以在某些 Android 设备上运行,但 moto g (6.0.1)API 除外。

异常:IOException OR 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();
                }
            });

任何人都可以帮我解决这个问题吗?我错过了什么吗?

【问题讨论】:

    标签: android streaming android-mediaplayer android-6.0-marshmallow motorola


    【解决方案1】:

    我也遇到过类似的莫名其妙的问题。我正在使用一个简单的 MediaPlayer 从站点流式传输音频。这在三星 Galaxy S4 (Android 5.0.1) 上完美运行,但在 Pixel (Android 8.1.0) 上无法播放音频。

    我在播放按钮单击时加载 URL,显示进度微调器,直到触发 MediaPlayer onPrepared 侦听器。准备好后,我会隐藏进度条并开始播放。

    在 Pixel 上,正常的加载/流式传输时间已经过去(所以我猜文件正在准备中!) onPrepared 被触发,没有显示错误,但从不播放音频!

    我们的服务器使用自签名证书,我认为这可能是问题所在,但即使通过 http 访问文件,它也无法在 Pixel 上播放。我还确认这不是编解码器问题,因为将文件移动到 Google Drive 并在我的应用程序中使用直接链接播放文件可以正常播放。

    我不确定这是否是基于服务器的问题,但所有其他文件(图像等)都已提供并显示正常(使用 Glide),并且该文件已提供并可通过输入到 Chrome 中的相同 URL 在 Chrome 中查看媒体播放器!

    我刚刚转移到 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;
        }
    
    }
    

    记得在停止/销毁时释放播放器

    希望能帮助那些和我一样摸不着头脑的人!

    【讨论】:

    • 谢谢..!! @WallyHale 我一定会尝试 ExoPlayer... 迟到你会知道评论或接受你的答案。
    • 我会在更改版本号和其他一些内容时更新上述答案。此外,虽然很明显,但值得注意的是,我在片段中运行,因此 getActivity() 调用上下文。现在跳上电脑更新代码....
    【解决方案2】:

    我已使用以下代码在 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 版本。

    来源https://source.android.com/devices/audio/attributes

    【讨论】:

      猜你喜欢
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多