Search code examples
androidstreamingandroid-mediaplayerandroid-6.0-marshmallowmotorola

Android Media Player Streaming not working


I have created one streaming audio application which is working on some Android devices but except moto g (6.0.1)API.

Exception: IOException OR MEDIA_ERROR_SYSTEM "error : (1, -2147483648)"

Code:

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

Can anyone please help me whats going wrong in this? Do I missing something?


Solution

  • I have had a similar and inexplicable issue. I am using a simple MediaPlayer to stream audio from a site. This works perfectly on a Samsung Galaxy S4 (Android 5.0.1), but on Pixel (Android 8.1.0) the audio won't play.

    I am loading the URL on a play button click, showing a progress spinner until the MediaPlayer onPrepared listener is triggered. When prepared, I'm hiding the progress bar, and starting playback.

    On Pixel, the normal loading / streaming time elapses (so I guess the file is being prepared!) onPrepared is triggered, no errors are shown, but the audio is never played!

    Our server uses a self signed certificate which I thought might have been the issue, but even accessing the file over http it won't play on Pixel. I have also confirmed it's not a codec issue, as moving the file to Google Drive and playing with a direct link in my app the file plays back fine.

    I am not sure if it's a server based issue, but all other files (images etc) are served and display fine (using Glide), and the file is served and can be viewed in Chrome via the same URL fed into the MediaPlayer!

    I have just now moved to ExoPlayer, and it's playing fine on both devices .. so I guess this is the way forward!

    Add dependency

    compile 'com.google.android.exoplayer:exoplayer-core:2.6.1'
    

    When play button is clicked, I'm loading Audio if not already loaded, otherwise starting playback

    if (player == null) {
       loadAudio();
    } else {
       player.setPlayWhenReady(true);
    }
    

    And my 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);
     }
    

    ... and the ExoPlayer listeners for state, so I can swap play / pause buttons in UI on completion etc

    @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;
        }
    
    }
    

    Remember to release the player on stop / destroy

    Hopefully can help someone out there who is scratching their head as much as I was!