mirror of
https://github.com/clangen/musikcube.git
synced 2025-01-02 11:58:27 +00:00
Added the ability to select playback engine (ExoPlayer, ExoPlayer
Gapless, or MediaPlayer).
This commit is contained in:
parent
b065751b0a
commit
0a6851544e
@ -1,11 +1,13 @@
|
||||
package io.casey.musikcube.remote.service.playback
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import io.casey.musikcube.remote.Application
|
||||
import io.casey.musikcube.remote.service.playback.impl.player.ExoPlayerWrapper
|
||||
import io.casey.musikcube.remote.service.playback.impl.player.GaplessExoPlayerWrapper
|
||||
import io.casey.musikcube.remote.service.playback.impl.player.MediaPlayerWrapper
|
||||
import io.casey.musikcube.remote.service.playback.impl.streaming.offline.OfflineTrack
|
||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||
import io.casey.musikcube.remote.util.Preconditions
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
@ -13,8 +15,17 @@ import io.reactivex.schedulers.Schedulers
|
||||
import java.util.*
|
||||
|
||||
abstract class PlayerWrapper {
|
||||
private enum class Type {
|
||||
MediaPlayer, ExoPlayer
|
||||
private enum class Type(prefIndex: Int) {
|
||||
ExoPlayer(0), ExoPlayerGapless(1), MediaPlayer(2);
|
||||
|
||||
companion object {
|
||||
fun fromPrefIndex(index: Int): Type =
|
||||
when(index) {
|
||||
2 -> MediaPlayer
|
||||
1 -> ExoPlayerGapless
|
||||
else -> ExoPlayer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class State {
|
||||
@ -140,9 +151,16 @@ abstract class PlayerWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
fun newInstance(): PlayerWrapper {
|
||||
return if (TYPE == Type.ExoPlayer)
|
||||
GaplessExoPlayerWrapper() else MediaPlayerWrapper()
|
||||
fun newInstance(prefs: SharedPreferences): PlayerWrapper {
|
||||
val type = prefs.getInt(
|
||||
Prefs.Key.PLAYBACK_ENGINE_INDEX,
|
||||
Prefs.Default.PLAYBACK_ENGINE_INDEX)
|
||||
|
||||
return when (Type.fromPrefIndex(type)) {
|
||||
Type.ExoPlayer -> ExoPlayerWrapper()
|
||||
Type.ExoPlayerGapless -> GaplessExoPlayerWrapper()
|
||||
Type.MediaPlayer -> MediaPlayerWrapper()
|
||||
}
|
||||
}
|
||||
|
||||
fun addActivePlayer(player: PlayerWrapper) {
|
||||
|
@ -621,7 +621,7 @@ class StreamingPlaybackService(context: Context) : IPlaybackService {
|
||||
|
||||
if (uri != null && uri != playContext.nextPlayer?.uri) {
|
||||
playContext.reset(playContext.nextPlayer)
|
||||
playContext.nextPlayer = PlayerWrapper.newInstance()
|
||||
playContext.nextPlayer = PlayerWrapper.newInstance(prefs)
|
||||
playContext.nextPlayer?.setOnStateChangedListener(onNextPlayerStateChanged)
|
||||
playContext.nextPlayer?.prefetch(uri, playContext.nextMetadata!!)
|
||||
}
|
||||
@ -720,7 +720,7 @@ class StreamingPlaybackService(context: Context) : IPlaybackService {
|
||||
val uri = getUri(playContext.currentMetadata)
|
||||
|
||||
if (uri != null) {
|
||||
playContext.currentPlayer = PlayerWrapper.newInstance()
|
||||
playContext.currentPlayer = PlayerWrapper.newInstance(prefs)
|
||||
playContext.currentPlayer?.setOnStateChangedListener(onCurrentPlayerStateChanged)
|
||||
playContext.currentPlayer?.play(uri, playContext.currentMetadata!!)
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import io.casey.musikcube.remote.ui.settings.model.Connection
|
||||
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
||||
import io.casey.musikcube.remote.ui.shared.extension.*
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||
import java.util.*
|
||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs.Default as Defaults
|
||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs.Key as Keys
|
||||
@ -40,11 +41,16 @@ class SettingsActivity : BaseActivity() {
|
||||
private lateinit var certCheckbox: CheckBox
|
||||
private lateinit var bitrateSpinner: Spinner
|
||||
private lateinit var cacheSpinner: Spinner
|
||||
private lateinit var playbackEngineSpinner: Spinner
|
||||
private lateinit var prefs: SharedPreferences
|
||||
private lateinit var playback: PlaybackMixin
|
||||
private lateinit var data: DataProviderMixin
|
||||
|
||||
private var engineType = -1
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
data = mixin(DataProviderMixin())
|
||||
playback = mixin(PlaybackMixin())
|
||||
component.inject(this)
|
||||
super.onCreate(savedInstanceState)
|
||||
prefs = this.getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE)
|
||||
@ -116,16 +122,31 @@ class SettingsActivity : BaseActivity() {
|
||||
bitrateSpinner.setSelection(prefs.getInt(
|
||||
Keys.TRANSCODER_BITRATE_INDEX, Defaults.TRANSCODER_BITRATE_INDEX))
|
||||
|
||||
/* disk cache */
|
||||
val cacheSizes = ArrayAdapter.createFromResource(
|
||||
this, R.array.disk_cache_array, android.R.layout.simple_spinner_item)
|
||||
|
||||
/* disk cache */
|
||||
cacheSizes.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
|
||||
cacheSpinner.adapter = cacheSizes
|
||||
cacheSpinner.setSelection(prefs.getInt(
|
||||
Keys.DISK_CACHE_SIZE_INDEX, Defaults.DISK_CACHE_SIZE_INDEX))
|
||||
|
||||
/* playback engine */
|
||||
val engines = ArrayAdapter.createFromResource(
|
||||
this, R.array.playback_engine_array, android.R.layout.simple_spinner_item)
|
||||
|
||||
engines.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
|
||||
val engineType = prefs.getInt(Keys.PLAYBACK_ENGINE_INDEX, Defaults.PLAYBACK_ENGINE_INDEX)
|
||||
|
||||
if (this.engineType == -1) {
|
||||
this.engineType = engineType
|
||||
}
|
||||
|
||||
playbackEngineSpinner.adapter = engines
|
||||
playbackEngineSpinner.setSelection(engineType)
|
||||
|
||||
/* advanced */
|
||||
albumArtCheckbox.isChecked = prefs.getBoolean(
|
||||
Keys.LASTFM_ENABLED, Defaults.LASTFM_ENABLED)
|
||||
@ -165,8 +186,8 @@ class SettingsActivity : BaseActivity() {
|
||||
if (value) {
|
||||
if (!dialogVisible(DisableCertValidationAlertDialog.TAG)) {
|
||||
showDialog(
|
||||
DisableCertValidationAlertDialog.newInstance(),
|
||||
DisableCertValidationAlertDialog.TAG)
|
||||
DisableCertValidationAlertDialog.newInstance(),
|
||||
DisableCertValidationAlertDialog.TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,6 +202,7 @@ class SettingsActivity : BaseActivity() {
|
||||
this.softwareVolume = findViewById(R.id.software_volume)
|
||||
this.bitrateSpinner = findViewById(R.id.transcoder_bitrate_spinner)
|
||||
this.cacheSpinner = findViewById(R.id.streaming_disk_cache_spinner)
|
||||
this.playbackEngineSpinner = findViewById(R.id.streaming_playback_engine)
|
||||
this.sslCheckbox = findViewById(R.id.ssl_checkbox)
|
||||
this.certCheckbox = findViewById(R.id.cert_validation)
|
||||
}
|
||||
@ -192,8 +214,8 @@ class SettingsActivity : BaseActivity() {
|
||||
|
||||
findViewById<View>(R.id.button_load).setOnClickListener{_ ->
|
||||
startActivityForResult(
|
||||
ConnectionsActivity.getStartIntent(this),
|
||||
CONNECTIONS_REQUEST_CODE)
|
||||
ConnectionsActivity.getStartIntent(this),
|
||||
CONNECTIONS_REQUEST_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,6 +261,12 @@ class SettingsActivity : BaseActivity() {
|
||||
val password = passwordText.text.toString()
|
||||
|
||||
try {
|
||||
val engineType = playbackEngineSpinner.selectedItemPosition
|
||||
|
||||
val streaming = prefs.getBoolean(
|
||||
Prefs.Key.STREAMING_PLAYBACK,
|
||||
Prefs.Default.STREAMING_PLAYBACK)
|
||||
|
||||
prefs.edit()
|
||||
.putString(Keys.ADDRESS, addr)
|
||||
.putInt(Keys.MAIN_PORT, if (port.isNotEmpty()) port.toInt() else 0)
|
||||
@ -251,12 +279,17 @@ class SettingsActivity : BaseActivity() {
|
||||
.putBoolean(Keys.CERT_VALIDATION_DISABLED, certCheckbox.isChecked)
|
||||
.putInt(Keys.TRANSCODER_BITRATE_INDEX, bitrateSpinner.selectedItemPosition)
|
||||
.putInt(Keys.DISK_CACHE_SIZE_INDEX, cacheSpinner.selectedItemPosition)
|
||||
.putInt(Keys.PLAYBACK_ENGINE_INDEX, engineType)
|
||||
.apply()
|
||||
|
||||
if (!softwareVolume.isChecked) {
|
||||
PlayerWrapper.setVolume(1.0f)
|
||||
}
|
||||
|
||||
if (streaming && engineType != this.engineType) {
|
||||
playback.service.stop()
|
||||
}
|
||||
|
||||
StreamProxy.reload()
|
||||
data.wss.disconnect()
|
||||
|
||||
|
@ -16,6 +16,7 @@ class Prefs {
|
||||
val TRANSCODER_BITRATE_INDEX = "transcoder_bitrate_index"
|
||||
val DISK_CACHE_SIZE_INDEX = "disk_cache_size_index"
|
||||
val UPDATE_DIALOG_SUPPRESSED_VERSION = "update_dialog_suppressed_version"
|
||||
val PLAYBACK_ENGINE_INDEX = "playback_engine_index"
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +34,7 @@ class Prefs {
|
||||
val CERT_VALIDATION_DISABLED = false
|
||||
val TRANSCODER_BITRATE_INDEX = 0
|
||||
val DISK_CACHE_SIZE_INDEX = 2
|
||||
val PLAYBACK_ENGINE_INDEX = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,23 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="8dp"
|
||||
android:text="@string/settings_playback_engine"/>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/streaming_playback_engine"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="24dp"/>
|
||||
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="playback_engine_array">
|
||||
<item>@string/settings_playback_engine_exo</item>
|
||||
<item>@string/settings_playback_engine_exo_gapless</item>
|
||||
<item>@string/settings_playback_engine_mp</item>
|
||||
</string-array>
|
||||
</resources>
|
@ -106,6 +106,10 @@
|
||||
<string name="settings_invalid_connection_no_name_message">one or more connection fields are invalid.\n\nensure you\'ve entered a hostname and port numbers.</string>
|
||||
<string name="settings_confirm_delete_title">confirm delete</string>
|
||||
<string name="settings_confirm_delete_message">are you sure you want to delete \'%s\'?</string>
|
||||
<string name="settings_playback_engine">playback engine</string>
|
||||
<string name="settings_playback_engine_exo">ExoPlayer (stable)</string>
|
||||
<string name="settings_playback_engine_exo_gapless">ExoPlayer Gapless (experimental)</string>
|
||||
<string name="settings_playback_engine_mp">MediaPlayer (deprecated)</string>
|
||||
<string name="connections_no_presets">no saved connection presets.</string>
|
||||
<string name="empty_show_offline_tracks_button">show offline songs</string>
|
||||
<string name="empty_no_offline_tracks_message">oops, you don\'t seem to have any songs available offline.\n\nnext time you\'re connected, stream some music!</string>
|
||||
@ -135,5 +139,4 @@
|
||||
<string name="playlist_not_created">could not create playlist \'%s\'</string>
|
||||
<string name="playlist_deleted">playlist \'%s\' deleted</string>
|
||||
<string name="playlist_not_deleted">could not delete playlist \'%s\'</string>
|
||||
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user