瀏覽代碼

Merge branch 'tsumugi/devel' into tsumugi/master

yattoz 5 年之前
父節點
當前提交
9dff2f63d4

+ 2 - 2
app/build.gradle 查看文件

@@ -29,8 +29,8 @@ android {
29 29
         applicationId "fr.forum_thalie.tsumugi"
30 30
         minSdkVersion 16
31 31
         targetSdkVersion 29
32
-        versionCode 112
33
-        versionName "1.1.2"
32
+        versionCode 113
33
+        versionName "1.1.3"
34 34
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
35 35
         vectorDrawables.useSupportLibrary = true
36 36
     }

+ 2 - 0
app/src/main/java/fr/forum_thalie/tsumugi/BootBroadcastReceiver.kt 查看文件

@@ -7,6 +7,7 @@ import android.os.Build
7 7
 import android.util.Log
8 8
 import androidx.preference.PreferenceManager
9 9
 import fr.forum_thalie.tsumugi.alarm.RadioAlarm
10
+import fr.forum_thalie.tsumugi.planning.Planning
10 11
 import fr.forum_thalie.tsumugi.playerstore.PlayerStore
11 12
 
12 13
 class BootBroadcastReceiver : BroadcastReceiver(){
@@ -24,6 +25,7 @@ class BootBroadcastReceiver : BroadcastReceiver(){
24 25
         {
25 26
 
26 27
             RadioAlarm.instance.setNextAlarm(context) // schedule next alarm
28
+            Planning.instance.parseUrl(context = context)
27 29
             if (!PlayerStore.instance.isInitialized)
28 30
                 PlayerStore.instance.initApi()
29 31
             if (PlayerStore.instance.streamerName.value.isNullOrBlank())

+ 1 - 1
app/src/main/java/fr/forum_thalie/tsumugi/RadioService.kt 查看文件

@@ -140,7 +140,7 @@ class RadioService : MediaBrowserServiceCompat() {
140 140
                     PlayerStore.instance.isStreamDown = true
141 141
                 }
142 142
                 else -> {
143
-                    PlayerStore.instance.fetchApi(numberOfSongs >= 2)
143
+                    PlayerStore.instance.fetchApi(/* numberOfSongs >= 2 */)
144 144
                 }
145 145
             }
146 146
         }

+ 17 - 19
app/src/main/java/fr/forum_thalie/tsumugi/playerstore/PlayerStore.kt 查看文件

@@ -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
             }

+ 1 - 1
app/src/main/java/fr/forum_thalie/tsumugi/playerstore/Song.kt 查看文件

@@ -48,7 +48,7 @@ class Song(artistTitle: String = "", _id : Int = 0) {
48 48
     override fun equals(other: Any?) : Boolean
49 49
     {
50 50
         val song: Song = other as Song
51
-        return this.title.value == song.title.value && this.artist.value == song.artist.value
51
+        return this.title.value === song.title.value && this.artist.value === song.artist.value
52 52
     }
53 53
 
54 54
     fun copy(song: Song) {