Android API 23 vs Android API 25 MediaPlayer缓冲速度

问题描述:

我在使MediaPlayer正常工作在API 23时遇到了一些问题。我已经在相同的WiFI网络和/或蜂窝网络上测试过它,结果是相同的。我正在使用MediaPlayer.prepareAsync()准备我的信息流。我已将调试器附加到onPreparedListener(),它永远不会运行。请看下面的图表。在Android API 25Android API 23 vs Android API 25 MediaPlayer缓冲速度

Graph from Android API 23 网络使用

Graph from Android API 25

网络使用在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); 
} 

} 

的研究小时,我已经找到了问题,这是任何人都碰到这个问题未来非常有用了。

我的文件地址像这样:example.com/company example/files/audio.mp3 Android API 23及以下版本的问题是,这被视为无效的URL。您的网址应该是这样的example.com/company%20example/files/audio.mp3 一个简单的办法是在一个String这样使用replaceAll()

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