Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/kotlin/jp/lunaproject/bot/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import jp.lunaproject.bot.api.managers.punishments.BanManager
import jp.lunaproject.bot.api.managers.punishments.MuteManager
import jp.lunaproject.bot.api.redis.RedisController
import jp.lunaproject.bot.api.restful.MainController
import jp.lunaproject.bot.audio.media.YtDlpBinaryManager
import jp.lunaproject.bot.configurations.BotConfig
import jp.lunaproject.bot.configurations.utils.JSONStorage
import jp.lunaproject.bot.listeners.functions.*
Expand Down Expand Up @@ -204,6 +205,7 @@ object Main {
RedisController.connect()

loadCaches()
YtDlpBinaryManager.prepareForStartup()
loadLanguages()
loadBot()

Expand Down Expand Up @@ -517,6 +519,12 @@ object Main {
MuteManager.extends()
}, 0, 1, TimeUnit.HOURS)

if (botConfig.ytdlp.autoUpdate) {
scheduledExecutorService.scheduleWithFixedDelay({
YtDlpBinaryManager.runScheduledUpdate()
}, 0, YtDlpBinaryManager.UPDATE_INTERVAL_HOURS, TimeUnit.HOURS)
}

scheduler.schedule("*/5 * * * *") {
RedisController.setStatuses()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import jp.lunaproject.bot.audio.media.MediaController
import jp.lunaproject.bot.audio.media.RequestMediaData
import jp.lunaproject.bot.audio.media.ResponseMediaData
import jp.lunaproject.bot.audio.media.TrackData
import jp.lunaproject.bot.audio.media.YtDlpAudioResolver
import jp.lunaproject.bot.utils.language.LanguageUtil
import jp.lunaproject.bot.utils.objects.JSONUtil
import net.dv8tion.jda.api.entities.User
Expand Down Expand Up @@ -92,13 +93,36 @@ suspend fun action(connection: Connection, rawData: String) {

is RequestMediaData.Play -> {
val keyword = data.keyword

when (val resolved = YtDlpAudioResolver.resolve(keyword, controller, member)) {
is YtDlpAudioResolver.LoadResult.Track -> {
controller.play(resolved.track)
session.send(ResponseMediaData.PlayTrack(ResponseMediaData.TrackData.of(resolved.track)))
return
}

is YtDlpAudioResolver.LoadResult.Playlist -> {
controller.play(resolved.tracks)

session.send(
ResponseMediaData.PlayTracks(
resolved.name,
resolved.tracks.map { ResponseMediaData.TrackData.of(it) }
)
)
return
}

null -> Unit
}

val res = controller.link.loadItem(if (keyword.matches(_urlRegex)) keyword else "ytsearch: $keyword")

when (res.loadType) {
TrackResponse.LoadType.TRACK_LOADED -> {
val track = TrackData(res.track.toTrack(), member)
controller.play(track)
session.send(ResponseMediaData.PlayTrack(ResponseMediaData.TrackData.of(track.track)))
session.send(ResponseMediaData.PlayTrack(ResponseMediaData.TrackData.of(track)))
return
}

Expand All @@ -110,7 +134,7 @@ suspend fun action(connection: Connection, rawData: String) {
session.send(
ResponseMediaData.PlayTracks(
playlist.name,
tracks.map { ResponseMediaData.TrackData.of(it.track) }
tracks.map { ResponseMediaData.TrackData.of(it) }
)
)
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/jp/lunaproject/bot/audio/AudioController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ open class AudioController(val guild: Guild) {
open var channel: AudioChannel?
get() = _channelId?.let { guild.getChannelById(AudioChannel::class.java, it) }
set(channel) {
// setter は実際の VC 接続操作を行う入口で、成功後のキャッシュ更新は VoiceUpdate イベント側で反映する。
if (channel != null) {
connect(channel)
} else {
Expand Down Expand Up @@ -142,6 +143,7 @@ open class AudioController(val guild: Guild) {
* @author Aoichaan0513
*/
fun updateAudioChannel(channel: AudioChannel?) {
// ここでは JDA から通知された実接続状態だけを保持し、connect/disconnect の成否を後追いで同期する。
_channelId = channel?.idLong
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,10 @@ class PlayListHelper(
.setRequiredRange(1, 1)
.addOptions(
list.map { (i, data) ->
val duration = DateTimeUtil.formatTimestamp(data.track.length.inWholeMilliseconds, true).toNormal
val duration = DateTimeUtil.formatTimestamp(data.durationMillis, true).toNormal

SelectOption.of(data.track.title, data.id.toString())
.withDescription("${data.track.author.truncate(SelectOption.DESCRIPTION_MAX_LENGTH - (duration.length + 3))} / $duration")
SelectOption.of(data.title, data.id.toString())
.withDescription("${data.author.truncate(SelectOption.DESCRIPTION_MAX_LENGTH - (duration.length + 3))} / $duration")
}
)
.build()
Expand Down
40 changes: 23 additions & 17 deletions src/main/kotlin/jp/lunaproject/bot/audio/media/ResponseMediaData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -114,18 +114,17 @@ sealed class ResponseMediaData {
controller.tracks.getOrNull(controller.position.get())
} ?: return null

val track = data.track
return PlayingTrack(
data.id.toString(),
track.title,
track.uri,
data.title,
data.url,
data.artworkUrl,
track.author,
track.length.inWholeMilliseconds.toString(),
track.isSeekable,
track.isStream,
track.source,
track.identifier
data.author,
data.durationMillis.toString(),
data.isSeekable,
data.isStream,
data.source,
data.identifier
)
}
}
Expand Down Expand Up @@ -194,15 +193,15 @@ sealed class ResponseMediaData {
val (track, member) = data
return QueuedTrack(
data.id.toString(),
track.title,
track.uri,
data.title,
data.url,
data.artworkUrl,
track.author,
track.length.inWholeMilliseconds.toString(),
track.isSeekable,
track.isStream,
track.source,
track.identifier,
data.author,
data.durationMillis.toString(),
data.isSeekable,
data.isStream,
data.source,
data.identifier,
Member.of(member)
)
}
Expand Down Expand Up @@ -242,6 +241,13 @@ sealed class ResponseMediaData {

companion object {

fun of(track: jp.lunaproject.bot.audio.media.TrackData) = TrackData(
track.title,
track.url,
track.artworkUrl,
track.author
)

fun of(track: Track) = TrackData(
track.title,
track.uri!!,
Expand Down
45 changes: 42 additions & 3 deletions src/main/kotlin/jp/lunaproject/bot/audio/media/TrackData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,57 @@ import java.util.*

data class TrackData(
val track: Track,
val member: Member
val member: Member,
val metadata: Metadata = Metadata()
) {

// yt-dlp 経由の直リンク再生では、Lavalink 側の Track に元ページの情報が残らないことがある。
// UI 表示はここで持つ補助メタデータを優先して崩れないようにする。

data class Metadata(
val title: String? = null,
val url: String? = null,
val artworkUrl: String? = null,
val author: String? = null,
val durationMillis: Long? = null,
val source: String? = null,
val identifier: String? = null
)

val id: UUID = UUID.randomUUID()

val title
get() = metadata.title ?: track.title

val url
get() = metadata.url ?: track.uri ?: ""
Comment on lines +32 to +33

val author
get() = metadata.author ?: track.author

val durationMillis
get() = metadata.durationMillis ?: track.length.inWholeMilliseconds

val source
get() = metadata.source ?: track.source

val identifier
get() = metadata.identifier ?: track.identifier

val isSeekable
get() = track.isSeekable

val isStream
get() = track.isStream

private var _artworkUrl: String? = null
val artworkUrl: String?
get() {
// サムネイル取得は遅いことがあるため、最初の解決結果をキャッシュする。
if (_artworkUrl == null)
_artworkUrl = track.artworkUrl ?: ""
_artworkUrl = metadata.artworkUrl ?: track.artworkUrl ?: ""
return _artworkUrl?.ifBlank { null }
}

fun copy() = TrackData(track, member)
fun copy() = TrackData(track, member, metadata)
}
Loading