mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-30 14:49:47 +02:00
Merge pull request #12 from svdztn/media_btn
Media button & connect fail
This commit is contained in:
commit
d05cf46574
6 changed files with 102 additions and 9 deletions
|
@ -64,7 +64,7 @@ class Server extends EventEmitter {
|
||||||
var res = await this.ping(serverUrl)
|
var res = await this.ping(serverUrl)
|
||||||
|
|
||||||
if (!res || !res.success) {
|
if (!res || !res.success) {
|
||||||
this.setServerUrl(null)
|
//this.setServerUrl(null)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var authRes = await this.authorize(serverUrl, token)
|
var authRes = await this.authorize(serverUrl, token)
|
||||||
|
|
|
@ -35,7 +35,6 @@ class MyNativeAudio : Plugin() {
|
||||||
jsobj.put("playWhenReady", playWhenReady)
|
jsobj.put("playWhenReady", playWhenReady)
|
||||||
notifyListeners("onPrepareMedia", jsobj)
|
notifyListeners("onPrepareMedia", jsobj)
|
||||||
}
|
}
|
||||||
override fun onCar() {}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
mainActivity.pluginCallback = foregroundServiceReady
|
mainActivity.pluginCallback = foregroundServiceReady
|
||||||
|
|
|
@ -32,6 +32,11 @@ import com.google.android.exoplayer2.source.hls.HlsMediaSource
|
||||||
import com.google.android.exoplayer2.ui.PlayerNotificationManager
|
import com.google.android.exoplayer2.ui.PlayerNotificationManager
|
||||||
import com.google.android.exoplayer2.upstream.*
|
import com.google.android.exoplayer2.upstream.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.concurrent.schedule
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
|
||||||
|
|
||||||
const val NOTIFICATION_LARGE_ICON_SIZE = 144 // px
|
const val NOTIFICATION_LARGE_ICON_SIZE = 144 // px
|
||||||
|
@ -46,7 +51,6 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
fun onPlayingUpdate(isPlaying: Boolean)
|
fun onPlayingUpdate(isPlaying: Boolean)
|
||||||
fun onMetadata(metadata: JSObject)
|
fun onMetadata(metadata: JSObject)
|
||||||
fun onPrepare(audiobookId:String, playWhenReady:Boolean)
|
fun onPrepare(audiobookId:String, playWhenReady:Boolean)
|
||||||
fun onCar()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val tag = "PlayerService"
|
private val tag = "PlayerService"
|
||||||
|
@ -73,6 +77,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
|
|
||||||
private var audiobooks = mutableListOf<Audiobook>()
|
private var audiobooks = mutableListOf<Audiobook>()
|
||||||
|
|
||||||
|
private var mediaButtonClickCount: Int = 0
|
||||||
|
var mediaButtonClickTimeout: Long = 1000 //ms
|
||||||
|
var seekAmount: Long = 20000 //ms
|
||||||
|
|
||||||
fun setCustomObjectListener(mylistener: MyCustomObjectListener) {
|
fun setCustomObjectListener(mylistener: MyCustomObjectListener) {
|
||||||
listener = mylistener
|
listener = mylistener
|
||||||
}
|
}
|
||||||
|
@ -296,6 +304,13 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
|
|
||||||
//attach player to playerNotificationManager
|
//attach player to playerNotificationManager
|
||||||
playerNotificationManager.setPlayer(mPlayer)
|
playerNotificationManager.setPlayer(mPlayer)
|
||||||
|
|
||||||
|
mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS)
|
||||||
|
mediaSession.setCallback(object : MediaSessionCompat.Callback() {
|
||||||
|
override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean {
|
||||||
|
return handleCallMediaButton(mediaButtonEvent)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class DescriptionAdapter(private val controller: MediaControllerCompat) :
|
private inner class DescriptionAdapter(private val controller: MediaControllerCompat) :
|
||||||
|
@ -531,8 +546,6 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
// No further calls will be made to other media browsing methods.
|
// No further calls will be made to other media browsing methods.
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
listener.onCar()
|
|
||||||
|
|
||||||
val extras = Bundle()
|
val extras = Bundle()
|
||||||
extras.putInt(
|
extras.putInt(
|
||||||
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
|
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
|
||||||
|
@ -583,5 +596,71 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
||||||
}
|
}
|
||||||
result.sendResult(mediaItems)
|
result.sendResult(mediaItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun handleCallMediaButton(intent: Intent): Boolean {
|
||||||
|
if(Intent.ACTION_MEDIA_BUTTON == intent.getAction()) {
|
||||||
|
var keyEvent = intent.getParcelableExtra<KeyEvent>(Intent.EXTRA_KEY_EVENT)
|
||||||
|
if (keyEvent?.getAction() == KeyEvent.ACTION_UP) {
|
||||||
|
when (keyEvent?.getKeyCode()) {
|
||||||
|
KeyEvent.KEYCODE_HEADSETHOOK -> {
|
||||||
|
if(0 == mediaButtonClickCount) {
|
||||||
|
if (mPlayer.isPlaying)
|
||||||
|
pause()
|
||||||
|
else
|
||||||
|
play()
|
||||||
|
}
|
||||||
|
handleMediaButtonClickCount()
|
||||||
|
}
|
||||||
|
KeyEvent.KEYCODE_MEDIA_PLAY -> {
|
||||||
|
if(0 == mediaButtonClickCount) play()
|
||||||
|
handleMediaButtonClickCount()
|
||||||
|
}
|
||||||
|
KeyEvent.KEYCODE_MEDIA_PAUSE -> {
|
||||||
|
if(0 == mediaButtonClickCount) pause()
|
||||||
|
handleMediaButtonClickCount()
|
||||||
|
}
|
||||||
|
KeyEvent.KEYCODE_MEDIA_NEXT -> {
|
||||||
|
seekForward(seekAmount)
|
||||||
|
}
|
||||||
|
KeyEvent.KEYCODE_MEDIA_PREVIOUS -> {
|
||||||
|
seekBackward(seekAmount)
|
||||||
|
}
|
||||||
|
KeyEvent.KEYCODE_MEDIA_STOP -> {
|
||||||
|
terminateStream()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Log.d(tag, "KeyCode:${keyEvent?.getKeyCode()}")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleMediaButtonClickCount() {
|
||||||
|
mediaButtonClickCount++
|
||||||
|
if (1 == mediaButtonClickCount) {
|
||||||
|
Timer().schedule(mediaButtonClickTimeout) {
|
||||||
|
handler.sendEmptyMessage(mediaButtonClickCount)
|
||||||
|
mediaButtonClickCount = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val handler : Handler = @SuppressLint("HandlerLeak")
|
||||||
|
object : Handler(){
|
||||||
|
override fun handleMessage(msg: Message) {
|
||||||
|
super.handleMessage(msg)
|
||||||
|
if (2 == msg.what) {
|
||||||
|
seekBackward(seekAmount)
|
||||||
|
play()
|
||||||
|
}
|
||||||
|
else if (msg.what >= 3) {
|
||||||
|
seekForward(seekAmount)
|
||||||
|
play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
userToken() {
|
||||||
|
return this.$store.getters['user/getToken']
|
||||||
|
},
|
||||||
currentChapter() {
|
currentChapter() {
|
||||||
if (!this.audiobook || !this.chapters.length) return null
|
if (!this.audiobook || !this.chapters.length) return null
|
||||||
return this.chapters.find((ch) => ch.start <= this.currentTime && ch.end > this.currentTime)
|
return this.chapters.find((ch) => ch.start <= this.currentTime && ch.end > this.currentTime)
|
||||||
|
@ -112,7 +115,9 @@ export default {
|
||||||
var _clean = this.cover.replace(/\\/g, '/')
|
var _clean = this.cover.replace(/\\/g, '/')
|
||||||
if (_clean.startsWith('/local')) {
|
if (_clean.startsWith('/local')) {
|
||||||
var _cover = process.env.NODE_ENV !== 'production' && process.env.PROD !== '1' ? _clean.replace('/local', '') : _clean
|
var _cover = process.env.NODE_ENV !== 'production' && process.env.PROD !== '1' ? _clean.replace('/local', '') : _clean
|
||||||
return `${this.$store.state.serverUrl}${_cover}`
|
return `${this.$store.state.serverUrl}${_cover}?token=${this.userToken}&ts=${Date.now()}`
|
||||||
|
} else if (_clean.startsWith('/metadata')) {
|
||||||
|
return `${this.$store.state.serverUrl}${_clean}?token=${this.userToken}&ts=${Date.now()}`
|
||||||
}
|
}
|
||||||
return _clean
|
return _clean
|
||||||
}
|
}
|
||||||
|
@ -257,7 +262,7 @@ export default {
|
||||||
cover: this.download.coverUrl || null,
|
cover: this.download.coverUrl || null,
|
||||||
duration: String(Math.floor(this.duration * 1000)),
|
duration: String(Math.floor(this.duration * 1000)),
|
||||||
series: this.seriesTxt,
|
series: this.seriesTxt,
|
||||||
token: this.$store.getters['user/getToken'],
|
token: this.userToken,
|
||||||
contentUrl: this.playingDownload.contentUrl,
|
contentUrl: this.playingDownload.contentUrl,
|
||||||
isLocal: true
|
isLocal: true
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
userToken() {
|
||||||
|
return this.$store.getters['user/getToken']
|
||||||
|
},
|
||||||
book() {
|
book() {
|
||||||
return this.audiobook.book || {}
|
return this.audiobook.book || {}
|
||||||
},
|
},
|
||||||
|
@ -99,7 +102,9 @@ export default {
|
||||||
var _clean = this.cover.replace(/\\/g, '/')
|
var _clean = this.cover.replace(/\\/g, '/')
|
||||||
if (_clean.startsWith('/local')) {
|
if (_clean.startsWith('/local')) {
|
||||||
var _cover = process.env.NODE_ENV !== 'production' && process.env.PROD !== '1' ? _clean.replace('/local', '') : _clean
|
var _cover = process.env.NODE_ENV !== 'production' && process.env.PROD !== '1' ? _clean.replace('/local', '') : _clean
|
||||||
return `${this.serverUrl}${_cover}`
|
return `${this.$store.state.serverUrl}${_cover}?token=${this.userToken}&ts=${Date.now()}`
|
||||||
|
} else if (_clean.startsWith('/metadata')) {
|
||||||
|
return `${this.$store.state.serverUrl}${_clean}?token=${this.userToken}&ts=${Date.now()}`
|
||||||
}
|
}
|
||||||
return _clean
|
return _clean
|
||||||
},
|
},
|
||||||
|
|
|
@ -117,6 +117,9 @@ export default {
|
||||||
userAudiobook() {
|
userAudiobook() {
|
||||||
return this.userAudiobooks[this.audiobookId] || null
|
return this.userAudiobooks[this.audiobookId] || null
|
||||||
},
|
},
|
||||||
|
userToken() {
|
||||||
|
return this.$store.getters['user/getToken']
|
||||||
|
},
|
||||||
localUserAudiobooks() {
|
localUserAudiobooks() {
|
||||||
return this.$store.state.user.localUserAudiobooks || {}
|
return this.$store.state.user.localUserAudiobooks || {}
|
||||||
},
|
},
|
||||||
|
@ -291,7 +294,9 @@ export default {
|
||||||
var _clean = cover.replace(/\\/g, '/')
|
var _clean = cover.replace(/\\/g, '/')
|
||||||
if (_clean.startsWith('/local')) {
|
if (_clean.startsWith('/local')) {
|
||||||
var _cover = process.env.NODE_ENV !== 'production' && process.env.PROD !== '1' ? _clean.replace('/local', '') : _clean
|
var _cover = process.env.NODE_ENV !== 'production' && process.env.PROD !== '1' ? _clean.replace('/local', '') : _clean
|
||||||
return `${this.$store.state.serverUrl}${_cover}`
|
return `${this.$store.state.serverUrl}${_cover}?token=${this.userToken}&ts=${Date.now()}`
|
||||||
|
} else if (_clean.startsWith('/metadata')) {
|
||||||
|
return `${this.$store.state.serverUrl}${_clean}?token=${this.userToken}&ts=${Date.now()}`
|
||||||
}
|
}
|
||||||
return _clean
|
return _clean
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue