MediaPlayer的Android API 23与Android API 25的缓冲速度

时间:2017-09-13 08:27:40

标签: java android android-mediaplayer buffering

我在让MediaPlayer在API 23上正常工作时遇到了一些问题。我已经在SAME WiFI网络和/或蜂窝网络上测试了这一点,结果是一样的。我正在使用MediaPlayer.prepareAsync()来准备我的流。我已将调试器附加到onPreparedListener(),它从未运行过。请看下面的图表。

Graph from Android API 25

Android API 25上的网络使用

Graph from Android API 23 Android API 23上的网络使用

Android Studio中的“监视器”选项卡中有图像。 .mp3文件大约需要10秒钟。就像你可以看到的那样,Android API 23每2到3秒只会非常缓慢地加载一小部分歌曲。

虽然Android API 25会在2秒内立即加载。

主要问题是需要花费很长时间才能在Android API 23上加载歌曲。有没有人有类似的问题并且知道如何修复它?我的部分代码将在下面的代码示例中

public class CustomMediaPlayer implements MediaPlayer.OnPreparedListener {

private Context context;

private MediaPlayer mediaPlayer;
private boolean mediaPlayerReady;
private MaterialDialog loadingDialog;
private MaterialDialog playingDialog;
private TextView textTime;
private SeekBar seekBar;
private Handler handler;
private Runnable updateSongTime;

private String audioFileTitle;
private String audioFileUrl;
private int customPlayerView;


public CustomMediaPlayer(Context context) {
    this.context = context;
    this.mediaPlayerReady = false;
}

public void setSongName(String audioFileTitle) {
    this.audioFileTitle = audioFileTitle;
}

public void setSongUrl(String audioFileUrl) {
    this.audioFileUrl = audioFileUrl;
}

public void setCustomView(int customPlayerView) {
    this.customPlayerView = customPlayerView;
}

public void show() {
    PrepareDialogs();
    MediaPlayerCreate();
    HandlerRunnableCreate();
    MediaPlayerPrepare();
}

private void PrepareDialogs() {
    this.loadingDialog = new MaterialDialog.Builder(this.context)
            .title("Loading...")
            .content("Please wait")
            .progress(true, 0)
            .cancelable(true)
            .build();

    this.loadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            mediaPlayer.release();
            handler.removeCallbacks(updateSongTime);
            dialog.dismiss();
        }
    });

    this.playingDialog = new MaterialDialog.Builder(this.context)
            .title(this.audioFileTitle)
            .customView(this.customPlayerView, false)
            .neutralText("Close")
            .onNeutral(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    mediaPlayer.release();
                    handler.removeCallbacks(updateSongTime);
                    dialog.dismiss();
                }
            })
            .cancelable(false)
            .build();

    this.playingDialog.getCustomView().findViewById(R.id.image_play_pause).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ImageView image = (ImageView) v;
            if(mediaPlayer.isPlaying()) {
                image.setImageResource(R.drawable.ic_play);
                mediaPlayer.pause();
            } else {
                image.setImageResource(R.drawable.ic_pause);
                mediaPlayer.start();
            }
            v = image;
        }
    });

    this.textTime = (TextView) this.playingDialog.getCustomView().findViewById(R.id.text_time);
    this.seekBar = (SeekBar) this.playingDialog.getCustomView().findViewById(R.id.seek_bar);

    this.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            mediaPlayer.pause();
            handler.removeCallbacks(updateSongTime);
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mediaPlayer.seekTo(seekBar.getProgress());
            mediaPlayer.start();
            handler.postDelayed(updateSongTime, 100);
        }
    });
}

private void MediaPlayerCreate() {
    this.mediaPlayer = new MediaPlayer();
    this.mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    try {
        this.mediaPlayer.setDataSource(this.audioFileUrl);
        this.mediaPlayerReady = true;
    } catch(IOException e) {
        e.printStackTrace();
    }

    this.mediaPlayer.setOnPreparedListener(this);
}

private void HandlerRunnableCreate() {
    this.handler = new Handler();
    this.updateSongTime = new Runnable() {
        public void run() {
            try {
                if (mediaPlayer.isPlaying()) {
                    int startTime = mediaPlayer.getCurrentPosition();
                    seekBar.setProgress(startTime);
                    seekBar.setMax(mediaPlayer.getDuration());
                }
                handler.postDelayed(this, 100);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
        }
    };
}

private void MediaPlayerPrepare() {
    if (this.mediaPlayerReady) {
        this.loadingDialog.show();
        this.mediaPlayer.prepareAsync();
    } else {
        Toast.makeText(this.context, "Media Player not ready", Toast.LENGTH_LONG).show();
    }
}

@Override
public void onPrepared(MediaPlayer mp) {
    loadingDialog.dismiss();
    mediaPlayer.start();
    playingDialog.show();
    handler.postDelayed(updateSongTime, 100);
}

}

1 个答案:

答案 0 :(得分:0)

经过HOURS研究后,我发现了这个问题,对于遇到这个问题的人来说非常有用。

我的文件网址如下所示:example.com/company example/files/audio.mp3 Android API 23及以下版本的问题在于它被视为无效的网址。您的网址应如下所示example.com/company%20example/files/audio.mp3 一个简单的解决方法是使用replaceAll()上的String,如下所示:

String url = oldUrl.replaceAll(" ", "%20")

请注意,当您的网址无效时,Android根本不会出现任何错误。因此,请确保您的网址不包含任何空格。

修改 在使用无效URL进行更多操作之后,这是可行的方法:

URL url = new URL(oldURL);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String encodedUrl = uri.toASCIIString();