У меня та же проблема: Android MediaPlayer вызывает onCompletion до того, как он уже закончен
Кто-нибудь знает, как установить DataSource в файл, когда mp3 загружается в той же позиции? Ответ заголовка сервера:
Connection: keep-alive
Content-Disposition: inline; filename="1. Example.mp3"
Content-Length: 59623009
Content-Type: audio/mp3
Date: Wed, 26 Feb 2020 10:15:10 GMT
Server: nginx/1.10.3 (Ubuntu)
Я пытаюсь реализовать службу Android, которая воспроизводит музыку c по URL. MediaPlayer запускается как обычно и воспроизводит песню, но через некоторое время вызывает onCompletion (), когда песня не закончена. Я настроил onErrorListener, но он не вызывается.
Как мне перехватить endOfStream (когда песня полностью загружена) и изменить источник данных на локальный файл?
private val mediaSessionCallback: MediaSessionCompat.Callback? = object : MediaSessionCompat.Callback() {
override fun onPlay() {
val audioFocusResult = audioManager?.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)
if (audioFocusResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
super.onPlay()
session!!.isActive = true
mediaPlayer?.start()
refreshActivityStatus(PlaybackStateCompat.STATE_PLAYING)
refreshNotificationAndForegroundStatus(PlaybackStateCompat.STATE_PLAYING)
}
}
override fun onPause() {
super.onPause()
mediaPlayer?.pause()
refreshActivityStatus(PlaybackStateCompat.STATE_PAUSED)
refreshNotificationAndForegroundStatus(PlaybackStateCompat.STATE_PAUSED)
audioManager?.abandonAudioFocus(afChangeListener)
}
override fun onStop() {
super.onStop()
mediaPlayer?.stop()
mediaPlayer?.release()
mediaPlayer = null
mediaPlayer = MediaPlayer()
mediaPlayer?.setAudioStreamType(AudioManager.STREAM_MUSIC)
mediaPlayer?.setWakeMode(applicationContext, PowerManager.PARTIAL_WAKE_LOCK)
refreshActivityStatus(PlaybackStateCompat.STATE_STOPPED)
refreshNotificationAndForegroundStatus(PlaybackStateCompat.STATE_STOPPED)
session!!.isActive = false
audioManager?.abandonAudioFocus(afChangeListener)
}
override fun onSeekTo(pos: Long) {
super.onSeekTo(pos)
mediaPlayer?.seekTo(pos.toInt())
}
override fun onPrepareFromUri(uri: Uri?, extras: Bundle?) {
super.onPrepareFromUri(uri, extras)
playlistName = extras!!.getString(PlatformConstants.PLAYLIST_NAME_FLAG_PARAMETER, DEFAULT_PLAYLIST_NAME)
mediaPlayer?.setOnPreparedListener {
it.start()
val playbackStateCompat = PlaybackStateCompat.Builder()
.setActions(PlaybackStateCompat.ACTION_PLAY_FROM_URI)
.setState(PlaybackStateCompat.STATE_PLAYING, 0, 1.0f)
.build()
session?.setPlaybackState(playbackStateCompat)
refreshNotificationAndForegroundStatus(PlaybackStateCompat.STATE_PLAYING)
val mediaMetadataCompat = MediaMetadataCompat.Builder()
.putLong("duration", it.duration.toLong())
.build()
session?.setMetadata(mediaMetadataCompat)
handler.post(observer)
}
mediaPlayer?.setOnCompletionListener {
val playbackStateCompat = PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_SKIPPING_TO_NEXT, mediaPlayer?.currentPosition!!.toLong(), 1.0f)
.build()
session?.setPlaybackState(playbackStateCompat)
}
val songURL = uri.toString()
if (extras.getBoolean(PlatformConstants.DOWNLOADED_FLAG_PARAMETER, false)) {
val fileInputStream = FileInputStream(songURL)
mediaPlayer?.setDataSource(fileInputStream.fd)
} else {
mediaPlayer?.setDataSource(baseURL + songURL)
}
mediaPlayer?.prepareAsync()
}
}