Поток mp3 медиаплеера из Content-Disposition: встроенный URI - PullRequest
0 голосов
/ 26 февраля 2020

У меня та же проблема: 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()
        }
}
...