Skip to content

Commit

Permalink
Added seekTo function, added Duration into MediaInfo object
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafal committed Apr 26, 2018
1 parent 41cc4e0 commit 928f28e
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 19 deletions.
Binary file modified .idea/caches/build_file_checksums.ser
Binary file not shown.
23 changes: 22 additions & 1 deletion .idea/runConfigurations/LaunchOnly.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val manager = MediaManagerFactory.getServiceMediaManager(this)
val manager = MediaManagerFactory.getMediaManager(this)

contentView!!.resume_button.setOnClickListener {
manager.resume()
Expand All @@ -28,14 +28,19 @@ class MainActivity : AppCompatActivity() {
manager.stop()
}

contentView!!.seek_button.setOnClickListener {
manager.seekTo(2000)
}

disposable = manager.getMediaInfoObservable().subscribe {
println(it)
}
if (savedInstanceState == null) {
manager.loadExternalFileMusic("Music/stephen_stay.mp3")
}

}
// internal, seekTo, czas całkowity

override fun onDestroy() {
super.onDestroy()
Expand Down
19 changes: 16 additions & 3 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,27 @@
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/stop_button"
android:id="@+id/stop_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="200dp"
android:layout_marginStart="8dp"
android:layout_marginTop="136dp"
android:text="stop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/seek_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="200dp"
android:layout_marginStart="8dp"
android:layout_marginTop="136dp"
android:text="stop"
android:layout_marginTop="204dp"
android:text="seek"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.1.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
1 change: 1 addition & 0 deletions rxaudiomanager/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.github.dcendents.android-maven'


android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package git.luolix.top.coneey.rxaudiomanager
import android.content.Context
import android.media.MediaPlayer
import git.luolix.top.coneey.rxaudiomanager.serviceMediaManager.ServiceMediaManager
import git.luolix.top.coneey.rxaudiomanager.simpleMediaManager.SimpleMediaPlayer
import git.luolix.top.coneey.rxaudiomanager.simpleMediaManager.SimpleMediaManager

class MediaManagerFactory {


companion object {
fun getMediaManager(context: Context, player: MediaPlayer = MediaPlayer()) = SimpleMediaPlayer(context, player)
fun getMediaManager(context: Context, player: MediaPlayer = MediaPlayer()) = SimpleMediaManager(context, player)
fun getServiceMediaManager(context: Context) = ServiceMediaManager(context)

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package git.luolix.top.coneey.rxaudiomanager.mediaListener

typealias Second = Int
typealias Millisecond = Int
typealias Percent = Int

data class MediaInfo(val state: MediaState, val bufferProgress: Percent, val currentTime: Second)
data class MediaInfo(val state: MediaState, val bufferProgress: Percent,
val currentTimeMilis: Millisecond,
val currentTime: Second,
val duration: Second)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.BiFunction
import io.reactivex.functions.Function3
import io.reactivex.functions.Function4
import io.reactivex.rxkotlin.subscribeBy
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.BehaviorSubject
Expand All @@ -28,9 +28,12 @@ class MediaStateResolver(private val player: MediaPlayer) : MediaPlayer.OnPrepar
private val stateSubject: Subject<MediaState> = BehaviorSubject.create()
private val bufferSubject: Subject<Percent> = BehaviorSubject.create()
private val positionSubject: Subject<Second> = BehaviorSubject.create()
private val durationSubject: Subject<Second> = BehaviorSubject.create()

private val infoFunction3 = Function3 { t1: MediaState, t2: Percent, t3: Second -> MediaInfo(t1, t2, t3) }
val infoSubject: Observable<MediaInfo> = Observable.combineLatest(stateSubject.startWith(MediaState.STOPPED), bufferSubject.startWith(100), positionSubject.startWith(0), infoFunction3)
private val infoFunction4 = Function4 { t1: MediaState, t2: Percent, t3: Second, t4: Second -> MediaInfo(t1, t2, t3, t3 / 1000, t4) }
val infoSubject: Observable<MediaInfo> = Observable.combineLatest(
stateSubject.startWith(MediaState.STOPPED), bufferSubject.startWith(100),
positionSubject.startWith(0), durationSubject.startWith(0), infoFunction4)

fun initialize(): Observable<MediaInfo> {
player.let {
Expand Down Expand Up @@ -92,6 +95,7 @@ class MediaStateResolver(private val player: MediaPlayer) : MediaPlayer.OnPrepar
internal fun startPlayer(mp: MediaPlayer) {
mp.start()
stateSubject.onNext(MediaState.RUNNING)
durationSubject.onNext(mp.duration)
startRefreshInterval(mp)
}

Expand All @@ -103,7 +107,7 @@ class MediaStateResolver(private val player: MediaPlayer) : MediaPlayer.OnPrepar

refreshIntervalDisposable?.dispose()
refreshIntervalDisposable = Observable
.combineLatest(Observable.interval(1, TimeUnit.SECONDS, Schedulers.newThread()), stateSubject, stateAndTimeBiFUnction)
.combineLatest(Observable.interval(500, TimeUnit.MILLISECONDS, Schedulers.newThread()), stateSubject, stateAndTimeBiFUnction)
.filter { it.second == MediaState.RUNNING }
.subscribeBy(onNext = { positionSubject.onNext(mp.currentPosition) })
}
Expand Down Expand Up @@ -135,5 +139,11 @@ class MediaStateResolver(private val player: MediaPlayer) : MediaPlayer.OnPrepar
}
}

fun seekTo(millisecond: Millisecond) {
if (player.isPlaying)
player.seekTo(millisecond)
positionSubject.onNext(millisecond)
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ class PlayerService : LifecycleService() {
private fun listenForMedia() {
if (mediaServiceDisposable == null) {
mediaServiceDisposable = MediaServiceCommandEmitter.commandSubject.subscribe {
println("COMMAND ARRIVED $it")
when (it) {
is ServiceCommand.Finish -> stopSelf()
is ServiceCommand.Stop -> mediaManager.stop()
is ServiceCommand.LoadStreamMusic -> mediaManager.loadStreamMusic(it.url, it.attr)
is ServiceCommand.LoadResourceMusic -> mediaManager.loadResourceMusic(it.resourceId, it.attr)
is ServiceCommand.LoadFileMusic -> mediaManager.loadExternalFileMusic(it.filePath, it.attr)
is ServiceCommand.LoadExternalFileMusic -> mediaManager.loadExternalFileMusic(it.filePath, it.attr)
is ServiceCommand.LoadInternalFileMusic -> mediaManager.loadInternalFileMusic(it.filePath, it.attr)
is ServiceCommand.Pause -> mediaManager.pause()
is ServiceCommand.Resume -> mediaManager.resume()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package git.luolix.top.coneey.rxaudiomanager.serviceMediaManager

import android.media.AudioAttributes
import git.luolix.top.coneey.rxaudiomanager.mediaListener.Millisecond

sealed class ServiceCommand {
class Stop : ServiceCommand()
class Pause : ServiceCommand()
class Resume : ServiceCommand()
class Finish : ServiceCommand()
class SeekTo(millisecond: Millisecond) : ServiceCommand()
class LoadStreamMusic(val url: String, val attr: AudioAttributes?) : ServiceCommand()
class LoadResourceMusic(val resourceId: Int, val attr: AudioAttributes?) : ServiceCommand()
class LoadFileMusic(val filePath: String, val attr: AudioAttributes?) : ServiceCommand()
class LoadExternalFileMusic(val filePath: String, val attr: AudioAttributes?) : ServiceCommand()
class LoadInternalFileMusic(val filePath: String, val attr: AudioAttributes?) : ServiceCommand()
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.media.MediaPlayer
import android.os.Environment
import git.luolix.top.coneey.rxaudiomanager.mediaListener.MediaInfo
import git.luolix.top.coneey.rxaudiomanager.mediaListener.MediaStateResolver
import git.luolix.top.coneey.rxaudiomanager.mediaListener.Millisecond
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import io.reactivex.rxkotlin.subscribeBy
Expand All @@ -31,8 +32,8 @@ open class InternalMediaPlayer(val player: MediaPlayer, val context: Context,
init {
resolver.initialize()
initializeLifeCycle()

mediaDisposable = mediaSubject
.doOnNext { println("SOMETHING ARRIVED ${it.second}") }
.subscribeBy(
onError = { throw it },
onNext = { startMusic(it) }
Expand Down Expand Up @@ -64,6 +65,19 @@ open class InternalMediaPlayer(val player: MediaPlayer, val context: Context,
mediaSubject.onNext((attributes ?: audioAttributes) to path)
}

override fun loadInternalFileMusic(filePath: String, attributes: AudioAttributes?) {
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build()
val path = "${context.cacheDir}/$filePath"
mediaSubject.onNext((attributes ?: audioAttributes) to path)
}

override fun seekTo(millisecond: Millisecond) {

resolver.seekTo(millisecond)
}

override fun getMediaInfoObservable(): Observable<MediaInfo> = resolver.infoSubject


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package git.luolix.top.coneey.rxaudiomanager.simpleMediaManager

import android.media.AudioAttributes
import git.luolix.top.coneey.rxaudiomanager.mediaListener.MediaInfo
import git.luolix.top.coneey.rxaudiomanager.mediaListener.Millisecond
import io.reactivex.Observable

interface MediaManager {

fun loadStreamMusic(url: String, attributes: AudioAttributes? = null)
fun loadResourceMusic(resourceId: Int, attributes: AudioAttributes? = null)
fun loadExternalFileMusic(filePath: String, attributes: AudioAttributes? = null)
fun loadInternalFileMusic(filePath: String, attributes: AudioAttributes? = null)
fun seekTo(millisecond: Millisecond)
fun finish()
fun pause()
fun resume()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package git.luolix.top.coneey.rxaudiomanager.simpleMediaManager

import android.media.AudioAttributes
import git.luolix.top.coneey.rxaudiomanager.mediaListener.MediaInfo
import git.luolix.top.coneey.rxaudiomanager.mediaListener.Millisecond
import git.luolix.top.coneey.rxaudiomanager.serviceMediaManager.ServiceCommand
import io.reactivex.Observable
import io.reactivex.subjects.BehaviorSubject
Expand All @@ -25,7 +26,15 @@ object MediaServiceCommandEmitter : MediaManager {
}

override fun loadExternalFileMusic(filePath: String, attributes: AudioAttributes?) {
commandSubject.onNext(ServiceCommand.LoadFileMusic(filePath, attributes))
commandSubject.onNext(ServiceCommand.LoadExternalFileMusic(filePath, attributes))
}

override fun loadInternalFileMusic(filePath: String, attributes: AudioAttributes?) {
commandSubject.onNext(ServiceCommand.LoadInternalFileMusic(filePath, attributes))
}

override fun seekTo(millisecond: Millisecond) {
commandSubject.onNext(ServiceCommand.SeekTo(millisecond))
}

override fun finish() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import android.media.MediaPlayer
import android.support.v7.app.AppCompatActivity
import com.tbruyelle.rxpermissions2.RxPermissions

class SimpleMediaPlayer internal constructor(private val context: Context, player: MediaPlayer,
private val internalMediaPlayer: InternalMediaPlayer = InternalMediaPlayer(player, context))
class SimpleMediaManager internal constructor(private val context: Context, player: MediaPlayer,
private val internalMediaPlayer: InternalMediaPlayer = InternalMediaPlayer(player, context))
: MediaManager by internalMediaPlayer {

override fun loadExternalFileMusic(filePath: String, attributes: AudioAttributes?) {
Expand Down

0 comments on commit 928f28e

Please sign in to comment.