Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.andyshon.ucanspeak.ui.catalogTab.catalog.player
- import android.app.*
- import android.content.Intent
- import android.net.Uri
- import android.os.Binder
- import android.os.Handler
- import android.os.IBinder
- import com.andyshon.ucanspeak.events.*
- import com.google.android.exoplayer2.*
- import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
- import com.google.android.exoplayer2.source.ExtractorMediaSource
- import com.google.android.exoplayer2.source.TrackGroupArray
- import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
- import com.google.android.exoplayer2.trackselection.TrackSelectionArray
- import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
- import com.google.android.exoplayer2.util.Util
- import timber.log.Timber
- import java.util.*
- import android.support.v4.content.LocalBroadcastManager
- import com.andyshon.ucanspeak.data.entity.LessonFilePhraseEntity
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_CLOSE_NOTIFICATION
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_CREATE_NOTIFICATION
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_PLAY_PAUSE
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_PLAY_PAUSE_FROM_FLOW_PLAYER
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_REWIND_BACK
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_REWIND_BACK_INVISIBLE
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_REWIND_BACK_VISIBLE
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_REWIND_NEXT
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_REWIND_NEXT_INVISIBLE
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_REWIND_NEXT_VISIBLE
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_REWIND_SEEKBAR
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_SET_NEW_AUDIO_FILE
- import com.andyshon.ucanspeak.data.preference.Preference.PlayerService.PLAYER_SERVICE_STOP
- import com.google.android.exoplayer2.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF
- import com.google.android.exoplayer2.Player
- class PlayerService : Service() {
- companion object {
- var isViewAttachedToBottom = false
- var rxEventBus: RxEventBus? = null
- var phrases: ArrayList<LessonFilePhraseEntity> = arrayListOf()
- }
- var exoPlayer: SimpleExoPlayer? = null
- private var myBinder = MyBinder()
- private lateinit var playerNotificationManager: PlayerNotificationManager
- private var audioDuration = 0L
- private var curPos = 0
- private var lessonName = ""
- private var lessonDescription = ""
- var fileLink = ""
- override fun onCreate() {
- val renderersFactory = DefaultRenderersFactory(this, null, EXTENSION_RENDERER_MODE_OFF)
- val trackSelector = DefaultTrackSelector()
- exoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector)
- exoPlayer?.addListener(object : Player.EventListener {
- override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
- if (playWhenReady && playbackState == Player.STATE_READY) {
- // media actually playing
- audioDuration = exoPlayer?.duration ?: 0
- sendSetSeekBarMaxValue()
- Handler().postDelayed(onEverySecond, 100)
- }
- else {
- if (playbackState == 4) {
- sendStopPlayer()
- }
- }
- }
- override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {}
- override fun onSeekProcessed() {}
- override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {}
- override fun onPlayerError(error: ExoPlaybackException?) {}
- override fun onLoadingChanged(isLoading: Boolean) {}
- override fun onPositionDiscontinuity(reason: Int) {}
- override fun onRepeatModeChanged(repeatMode: Int) {}
- override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {}
- override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {}
- })
- }
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- isViewAttachedToBottom = true
- if (intent?.hasExtra(PLAYER_SERVICE_CREATE_NOTIFICATION) == true) {
- if (playerNotificationManager.isShowNotification.not()) {
- playerNotificationManager.createNotification(this, false, lessonName, lessonDescription)
- }
- }
- if (intent?.hasExtra(PLAYER_SERVICE_PLAY_PAUSE_FROM_FLOW_PLAYER) == true) {
- sendUpdatePlayButton(exoPlayer?.playWhenReady!!)
- }
- if (intent?.hasExtra(PLAYER_SERVICE_PLAY_PAUSE_FROM_FLOW_PLAYER) == true) {
- exoPlayer?.playWhenReady = exoPlayer?.playWhenReady?.not()!!
- sendUpdatePlayButton(exoPlayer?.playWhenReady!!)
- updateNotificationBtnPlay(exoPlayer?.playWhenReady ?: false)
- }
- if (intent?.hasExtra(PLAYER_SERVICE_REWIND_NEXT) == true) {
- rewindForward()
- }
- if (intent?.hasExtra(PLAYER_SERVICE_REWIND_BACK) == true) {
- rewindBack()
- }
- if (intent?.hasExtra(PLAYER_SERVICE_REWIND_SEEKBAR) == true) {
- val progress = intent.getIntExtra(PLAYER_SERVICE_REWIND_SEEKBAR, 0)
- exoPlayer?.seekTo(progress.toLong())
- }
- if (intent?.hasExtra(PLAYER_SERVICE_CLOSE_NOTIFICATION) == true) {
- closeNotification()
- }
- if (intent?.hasExtra(PLAYER_SERVICE_PLAY_PAUSE) == true) {
- exoPlayer?.playWhenReady = exoPlayer?.playWhenReady?.not() ?: false
- sendUpdatePlayButton(exoPlayer?.playWhenReady ?: false)
- updateNotificationBtnPlay(exoPlayer?.playWhenReady ?: false)
- }
- if (intent?.hasExtra(PLAYER_SERVICE_SET_NEW_AUDIO_FILE) == true) {
- fileLink = intent.getStringExtra(PLAYER_SERVICE_SET_NEW_AUDIO_FILE)
- lessonName = intent.getStringExtra("lessonName")
- lessonDescription = intent.getStringExtra("lessonDescription")
- sendUpdatePlayButton(true)
- sendSetLessonName()
- val userAgent = Util.getUserAgent(this, "Play Audio")
- val mediaSource = ExtractorMediaSource(
- Uri.parse(fileLink),
- DefaultDataSourceFactory(this, userAgent),
- DefaultExtractorsFactory(), null, null
- )
- exoPlayer?.prepare(mediaSource)
- exoPlayer?.playWhenReady = true
- playerNotificationManager = PlayerNotificationManager(this, exoPlayer!!)
- playerNotificationManager.createNotification(this,true, lessonName, lessonDescription)
- }
- return START_NOT_STICKY
- }
- private fun closeNotification() {
- isViewAttachedToBottom = false
- exoPlayer?.playWhenReady = false
- playerNotificationManager.closeNotification()
- }
- private fun rewindBack() {
- setCurPos(--curPos)
- if (curPos > 0) {
- if (curPos == 0) {
- sendBtnBackInvisible()
- } else {
- sendBtnBackVisible()
- }
- val previousPhrase = phrases[curPos - 1]
- exoPlayer?.seekTo(previousPhrase.position.toLong() * 1000)
- sendUpdateSeekBar(exoPlayer?.currentPosition?.toInt()!!)
- }
- else {
- sendBtnBackInvisible()
- }
- }
- private fun rewindForward() {
- setCurPos(++curPos)
- if (curPos < phrases.size - 1) {
- if (curPos == phrases.size - 2) {
- sendBtnForwardInvisible()
- } else {
- sendBtnForwardVisible()
- }
- val nextPhrase = phrases[curPos + 1]
- exoPlayer?.seekTo(nextPhrase.position.toLong() * 1000)
- sendUpdateSeekBar(exoPlayer?.currentPosition?.toInt()!!)
- }
- else {
- sendBtnForwardInvisible()
- }
- }
- fun updateNotificationBtnPlay(play: Boolean) {
- playerNotificationManager.updateNotificationBtnPlay(play)
- sendUpdatePlayButton(exoPlayer?.playWhenReady!!)
- }
- val onEverySecond = object : Runnable {
- override fun run() {
- if (exoPlayer != null) {
- if (phrases.isNotEmpty()) {
- try {
- sendSetSeekBarMaxValue()
- sendUpdateSeekBar(exoPlayer?.currentPosition?.toInt()!!)
- val seconds = exoPlayer?.currentPosition?.toInt()!! / 1000
- if (seconds >= phrases[1].position) sendBtnBackVisible()
- else sendBtnBackInvisible()
- if (seconds >= phrases[phrases.size - 1].position) sendBtnForwardInvisible()
- else sendBtnForwardVisible()
- sendUpdateTimeText()
- if (exoPlayer?.currentPosition ?: 0 >= audioDuration || exoPlayer?.playWhenReady == false) {
- Timber.e("Stop self")
- }
- else {
- sendUpdatePhrase()
- Handler().postDelayed(this, 100)
- }
- } catch (e: IllegalStateException) { }
- }
- }
- else { }
- }
- }
- fun setCurPos(pos: Int) {
- curPos = pos
- }
- // --- SEND INTENTS TO ACTIVITY ---
- private fun sendIntent(params: MutableMap<String, Any>) {
- val intent = Intent("intentKey")
- params.forEach { (key, value) ->
- run {
- when (value) {
- is Int -> intent.putExtra(key, value)
- is Long ->intent.putExtra(key, value)
- is Boolean -> intent.putExtra(key, value)
- is String -> intent.putExtra(key, value)
- else -> { }
- }
- }
- }
- LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
- }
- private fun sendStopPlayer() {
- sendIntent(mutableMapOf(Pair(PLAYER_SERVICE_STOP, true)))
- }
- private fun sendBtnBackVisible() {
- sendIntent(mutableMapOf(Pair(PLAYER_SERVICE_REWIND_BACK_VISIBLE, true)))
- }
- private fun sendBtnBackInvisible() {
- sendIntent(mutableMapOf(Pair(PLAYER_SERVICE_REWIND_BACK_INVISIBLE, true)))
- }
- private fun sendBtnForwardVisible() {
- sendIntent(mutableMapOf(Pair(PLAYER_SERVICE_REWIND_NEXT_VISIBLE, true)))
- }
- private fun sendBtnForwardInvisible() {
- sendIntent(mutableMapOf(Pair(PLAYER_SERVICE_REWIND_NEXT_INVISIBLE, true)))
- }
- private fun sendSetSeekBarMaxValue() {
- sendIntent(mutableMapOf(Pair("SEEKBAR_MAX_VALUE", audioDuration)))
- }
- private fun sendUpdatePlayButton(play: Boolean) {
- sendIntent(mutableMapOf(Pair(PLAYER_SERVICE_PLAY_PAUSE, play)))
- }
- private fun sendSetLessonName() {
- sendIntent(mutableMapOf(Pair("lessonName", lessonName), Pair("lessonDescription", lessonDescription)))
- }
- private fun sendUpdateSeekBar(msg: Int) {
- sendIntent(mutableMapOf(Pair("key", msg)))
- }
- private fun sendUpdatePhrase() {
- sendIntent(mutableMapOf(Pair("updatePhrase", true)))
- }
- private fun sendUpdateTimeText() {
- sendIntent(mutableMapOf(Pair("current", exoPlayer?.currentPosition ?: 0), Pair("audioDuration", audioDuration)))
- }
- // --- SEND INTENTS TO ACTIVITY ---
- override fun onDestroy() {
- isViewAttachedToBottom = false
- exoPlayer?.release()
- }
- override fun onBind(intent: Intent): IBinder {
- return myBinder
- }
- internal inner class MyBinder : Binder() {
- val service: PlayerService
- get() = this@PlayerService
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement