|
@@ -7,6 +7,7 @@ import android.support.v4.media.session.PlaybackStateCompat
|
7
|
7
|
import android.util.Log
|
8
|
8
|
import androidx.lifecycle.MutableLiveData
|
9
|
9
|
import fr.forum_thalie.tsumugi.*
|
|
10
|
+import fr.forum_thalie.tsumugi.planning.Planning
|
10
|
11
|
import org.json.JSONObject
|
11
|
12
|
import java.net.URL
|
12
|
13
|
import java.text.ParseException
|
|
@@ -58,9 +59,10 @@ class PlayerStore {
|
58
|
59
|
|
59
|
60
|
private fun getTimestamp(s: String) : Long
|
60
|
61
|
{
|
61
|
|
- val dateFormat = SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault())
|
|
62
|
+ val dateFormat = SimpleDateFormat("yyyy-MM-dd hh:mm:ss z", Locale.getDefault())
|
62
|
63
|
try {
|
63
|
|
- val t: Date? = dateFormat.parse(s)
|
|
64
|
+ val t: Date? = dateFormat.parse("$s ${Planning.instance.timeZone.id}")
|
|
65
|
+ //[REMOVE LOG CALLS]Log.d(tag, "date: $s -> $t")
|
64
|
66
|
return t!!.time
|
65
|
67
|
} catch (e: ParseException) {
|
66
|
68
|
e.printStackTrace()
|
|
@@ -90,16 +92,17 @@ class PlayerStore {
|
90
|
92
|
|
91
|
93
|
currentSong.stopTime.value = ends
|
92
|
94
|
|
|
95
|
+ val apiTime = getTimestamp(res.getJSONObject("station").getString("schedulerTime"))
|
93
|
96
|
// I noticed that the server has a big (3 to 9 seconds !!) offset for current time.
|
94
|
97
|
// we can measure it when the player is playing, to compensate it and have our progress bar perfectly timed
|
95
|
98
|
// latencyCompensator is set to null when beginPlaying() (we can't measure it at the moment we start playing, since we're in the middle of a song),
|
96
|
99
|
// at this moment, we set it to 0. Then, next time the updateApi is called when we're playing, we measure the latency and we set out latencyComparator.
|
97
|
100
|
if(isCompensatingLatency)
|
98
|
101
|
{
|
99
|
|
- latencyCompensator = getTimestamp(res.getJSONObject("station").getString("schedulerTime")) - (currentSong.startTime.value ?: getTimestamp(res.getJSONObject("station").getString("schedulerTime")))
|
100
|
|
- //[REMOVE LOG CALLS]Log.d((tag, "latency compensator set to ${(latencyCompensator).toFloat()/1000} s")
|
|
102
|
+ latencyCompensator = apiTime - (currentSong.startTime.value!!)
|
|
103
|
+ //[REMOVE LOG CALLS]Log.d(tag, "latency compensator set to ${(latencyCompensator).toFloat() / 1000} s")
|
101
|
104
|
}
|
102
|
|
- currentTime.value = getTimestamp(res.getJSONObject("station").getString("schedulerTime")) - (latencyCompensator)
|
|
105
|
+ currentTime.value = apiTime - (latencyCompensator)
|
103
|
106
|
|
104
|
107
|
/*
|
105
|
108
|
val listeners = resMain.getInt("listeners")
|
|
@@ -163,17 +166,8 @@ class PlayerStore {
|
163
|
166
|
// ##################################################
|
164
|
167
|
|
165
|
168
|
fun updateQueue() {
|
166
|
|
- if (queue.isNotEmpty()) {
|
167
|
|
- queue.remove(queue.first())
|
168
|
|
- //[REMOVE LOG CALLS]Log.d((tag, queue.toString())
|
169
|
|
- fetchLastRequest()
|
170
|
|
- isQueueUpdated.value = true
|
171
|
|
- } else if (isInitialized) {
|
172
|
|
- fetchLastRequest()
|
173
|
|
- } else {
|
174
|
|
- //[REMOVE LOG CALLS]Log.d((tag, "queue is empty! fetching anyway !!")
|
175
|
|
- fetchLastRequest()
|
176
|
|
- }
|
|
169
|
+ //[REMOVE LOG CALLS]Log.d(tag, queue.toString())
|
|
170
|
+ fetchLastRequest()
|
177
|
171
|
}
|
178
|
172
|
|
179
|
173
|
fun updateLp() {
|
|
@@ -192,6 +186,7 @@ class PlayerStore {
|
192
|
186
|
|
193
|
187
|
private fun fetchLastRequest()
|
194
|
188
|
{
|
|
189
|
+ isQueueUpdated.value = false
|
195
|
190
|
val sleepScrape: (Any?) -> String = {
|
196
|
191
|
/* we can maximize our chances to retrieve the last queued song by specifically waiting for the number of seconds we measure between ICY metadata and API change.
|
197
|
192
|
we add 2 seconds just to get a higher probability that the API has correctly updated. (the latency compensator can have a jitter of 1 second usually)
|
|
@@ -225,18 +220,21 @@ class PlayerStore {
|
225
|
220
|
initApi()
|
226
|
221
|
} else
|
227
|
222
|
*/
|
228
|
|
- if (resMain.has("next") /*&& queue.isNotEmpty()*/) {
|
|
223
|
+ if (resMain.has("next")) {
|
229
|
224
|
val queueJSON =
|
230
|
225
|
resMain.getJSONObject("next")
|
231
|
226
|
val t = extractSong(queueJSON)
|
232
|
|
- if (queue.isNotEmpty() && (t == queue.last() || t == currentSong))
|
|
227
|
+ if (queue.isNotEmpty() && (t == queue.last() || t == currentSong) && isQueueUpdated.value == false)
|
233
|
228
|
{
|
234
|
|
- //[REMOVE LOG CALLS]Log.d((tag, playerStoreTag + "Song already in there: $t")
|
|
229
|
+ //[REMOVE LOG CALLS]Log.d(tag, playerStoreTag + "Song already in there: $t\nQueue:$queue")
|
235
|
230
|
Async(sleepScrape, post)
|
236
|
231
|
} else {
|
|
232
|
+ if (queue.isNotEmpty())
|
|
233
|
+ queue.remove(queue.first())
|
237
|
234
|
queue.add(queue.size, t)
|
238
|
235
|
//[REMOVE LOG CALLS]Log.d(tag, playerStoreTag + "added last queue song: $t")
|
239
|
236
|
isQueueUpdated.value = true
|
|
237
|
+ return // FUUUCK IT WAS CALLING THE ASYNC ONE MORE TIME AFTERWARDS !?
|
240
|
238
|
}
|
241
|
239
|
}
|
242
|
240
|
}
|