1
1
package org.abimon.eternalJukebox.data.audio
2
2
3
3
import com.github.kittinunf.fuel.Fuel
4
+ import io.vertx.ext.web.RoutingContext
4
5
import kotlinx.coroutines.*
5
- import org.abimon.eternalJukebox.EternalJukebox
6
- import org.abimon.eternalJukebox.MediaWrapper
7
- import org.abimon.eternalJukebox.guaranteeDelete
6
+ import org.abimon.eternalJukebox.*
8
7
import org.abimon.eternalJukebox.objects.*
9
- import org.abimon.eternalJukebox.useThenDelete
10
- import org.abimon.visi.io.DataSource
11
8
import org.abimon.visi.io.FileDataSource
12
9
import org.schabi.newpipe.extractor.*
13
10
import org.schabi.newpipe.extractor.search.SearchInfo
@@ -56,8 +53,8 @@ object YoutubeAudioSource : IAudioSource, CoroutineScope {
56
53
private val hitQuota = AtomicLong (- 1 )
57
54
private val QUOTA_TIMEOUT = TimeUnit .MILLISECONDS .convert(10 , TimeUnit .MINUTES )
58
55
59
- override suspend fun provide (info : JukeboxInfo , clientInfo : ClientInfo ? ): DataSource ? {
60
- logger.trace(" [{}] Attempting to provide audio for {}" , clientInfo? .userUID, info.id)
56
+ override suspend fun provide (info : JukeboxInfo , context : RoutingContext ): Boolean {
57
+ logger.trace(" [{}] Attempting to provide audio for {}" , context. clientInfo.userUID, info.id)
61
58
62
59
var youTubeUrl: String? = null
63
60
val queryText = " ${info.artist} - ${info.title} "
@@ -74,21 +71,21 @@ object YoutubeAudioSource : IAudioSource, CoroutineScope {
74
71
75
72
videoDetails.minByOrNull { abs(info.duration - it.contentDetails.duration.toMillis()) }
76
73
?.let { youTubeUrl = VIDEO_LINK_PREFIX + it.id } ? : run {
77
- logger.warn(" [${clientInfo? .userUID} ] Searches for \" $queryText \" using YouTube Data API v3 turned up nothing" )
74
+ logger.warn(" [${context. clientInfo.userUID} ] Searches for \" $queryText \" using YouTube Data API v3 turned up nothing" )
78
75
}
79
76
}
80
77
if (youTubeUrl == null ) {
81
78
val infoItems = getInfoItemsFromNewPipeSearch(queryText)
82
79
83
80
infoItems.minByOrNull { abs(info.duration - TimeUnit .SECONDS .toMillis(it.duration)) }
84
81
?.let { youTubeUrl = it.url } ? : run {
85
- logger.error(" [${clientInfo? .userUID} ] Searches for \" $queryText \" using NewPipeExtractor turned up nothing" )
82
+ logger.error(" [${context. clientInfo.userUID} ] Searches for \" $queryText \" using NewPipeExtractor turned up nothing" )
86
83
}
87
84
}
88
85
89
- if (youTubeUrl == null ) return null
86
+ if (youTubeUrl == null ) return false
90
87
logger.trace(
91
- " [{}] Settled on {}" , clientInfo? .userUID, youTubeUrl
88
+ " [{}] Settled on {}" , context. clientInfo.userUID, youTubeUrl
92
89
)
93
90
94
91
val tmpFile = File (" $uuid .tmp" )
@@ -110,33 +107,33 @@ object YoutubeAudioSource : IAudioSource, CoroutineScope {
110
107
if (! downloadProcess.waitFor(90 , TimeUnit .SECONDS )) {
111
108
downloadProcess.destroyForcibly().waitFor()
112
109
logger.error(
113
- " [{}] Forcibly destroyed the download process for {}" , clientInfo? .userUID, youTubeUrl
110
+ " [{}] Forcibly destroyed the download process for {}" , context. clientInfo.userUID, youTubeUrl
114
111
)
115
112
}
116
113
}
117
114
118
115
if (! endGoalTmp.exists()) {
119
116
logger.warn(
120
- " [{}] {} does not exist, attempting to convert with ffmpeg" , clientInfo? .userUID, endGoalTmp
117
+ " [{}] {} does not exist, attempting to convert with ffmpeg" , context. clientInfo.userUID, endGoalTmp
121
118
)
122
119
123
120
if (! tmpFile.exists()) {
124
- logger.error(" [{}] {} does not exist, what happened?" , clientInfo? .userUID, tmpFile)
125
- return null
121
+ logger.error(" [{}] {} does not exist, what happened?" , context. clientInfo.userUID, tmpFile)
122
+ return false
126
123
}
127
124
128
125
if (MediaWrapper .ffmpeg.installed) {
129
126
if (withContext(Dispatchers .IO ) { ! MediaWrapper .ffmpeg.convert(tmpFile, endGoalTmp, ffmpegLog) }) {
130
- logger.error(" [{}] Failed to convert {} to {}. Check {}" , clientInfo? .userUID, tmpFile, endGoalTmp, ffmpegLog.name)
131
- return null
127
+ logger.error(" [{}] Failed to convert {} to {}. Check {}" , context. clientInfo.userUID, tmpFile, endGoalTmp, ffmpegLog.name)
128
+ return false
132
129
}
133
130
134
131
if (! endGoalTmp.exists()) {
135
- logger.error(" [{}] {} does not exist, check {}" , clientInfo? .userUID, endGoalTmp, ffmpegLog.name)
136
- return null
132
+ logger.error(" [{}] {} does not exist, check {}" , context. clientInfo.userUID, endGoalTmp, ffmpegLog.name)
133
+ return false
137
134
}
138
135
} else {
139
- logger.debug(" [{}] ffmpeg not installed, nothing we can do" , clientInfo? .userUID)
136
+ logger.debug(" [{}] ffmpeg not installed, nothing we can do" , context. clientInfo.userUID)
140
137
}
141
138
}
142
139
@@ -151,32 +148,32 @@ object YoutubeAudioSource : IAudioSource, CoroutineScope {
151
148
}
152
149
if (videoId != null ) {
153
150
logger.debug(" Storing Location from yt-dlp" )
154
- EternalJukebox .database.storeAudioLocation(info.id, VIDEO_LINK_PREFIX + videoId, clientInfo)
151
+ EternalJukebox .database.storeAudioLocation(info.id, VIDEO_LINK_PREFIX + videoId, context. clientInfo)
155
152
}
156
153
endGoalTmp.useThenDelete {
157
154
EternalJukebox .storage.store(
158
155
" ${info.id} .$format " ,
159
156
EnumStorageType .AUDIO ,
160
157
FileDataSource (it),
161
158
mimes[format] ? : " audio/mpeg" ,
162
- clientInfo
159
+ context. clientInfo
163
160
)
164
161
}
165
162
}
166
163
167
- return EternalJukebox .storage.provide (" ${info.id} .$format " , EnumStorageType .AUDIO , clientInfo )
164
+ return EternalJukebox .storage.safeProvide (" ${info.id} .$format " , EnumStorageType .AUDIO , context )
168
165
} finally {
169
166
tmpFile.guaranteeDelete()
170
167
File (tmpFile.absolutePath + " .part" ).guaranteeDelete()
171
168
withContext(Dispatchers .IO ) {
172
169
tmpLog.useThenDelete {
173
170
EternalJukebox .storage.store(
174
- it.name, EnumStorageType .LOG , FileDataSource (it), " text/plain" , clientInfo
171
+ it.name, EnumStorageType .LOG , FileDataSource (it), " text/plain" , context. clientInfo
175
172
)
176
173
}
177
174
ffmpegLog.useThenDelete {
178
175
EternalJukebox .storage.store(
179
- it.name, EnumStorageType .LOG , FileDataSource (it), " text/plain" , clientInfo
176
+ it.name, EnumStorageType .LOG , FileDataSource (it), " text/plain" , context. clientInfo
180
177
)
181
178
}
182
179
endGoalTmp.useThenDelete {
@@ -185,7 +182,7 @@ object YoutubeAudioSource : IAudioSource, CoroutineScope {
185
182
EnumStorageType .AUDIO ,
186
183
FileDataSource (it),
187
184
mimes[format] ? : " audio/mpeg" ,
188
- clientInfo
185
+ context. clientInfo
189
186
)
190
187
}
191
188
}
0 commit comments