From a4427edd1b76060c4b751fd5a04f01b8186a7aca Mon Sep 17 00:00:00 2001 From: ocean <503259349@qq.com> Date: Thu, 12 Jun 2025 14:33:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddownload=E5=9C=B0=E5=9D=80?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../melody/offline/music/util/DownloadUtil.kt | 100 ++++++++++++------ 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/melody/offline/music/util/DownloadUtil.kt b/app/src/main/java/melody/offline/music/util/DownloadUtil.kt index 7f92f69..4198905 100644 --- a/app/src/main/java/melody/offline/music/util/DownloadUtil.kt +++ b/app/src/main/java/melody/offline/music/util/DownloadUtil.kt @@ -3,7 +3,9 @@ package melody.offline.music.util import android.app.Notification import android.content.Context import android.net.Uri +import android.util.Log import androidx.annotation.OptIn +import androidx.core.content.getSystemService import androidx.core.net.toUri import androidx.media3.common.PlaybackException import androidx.media3.common.util.NotificationUtil @@ -36,6 +38,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import melody.offline.music.App +import melody.offline.music.playernew.YTPlayerUtils.playerResponseForPlayback +import melody.offline.music.util.LogTag.LogD import java.net.CookieHandler import java.net.CookieManager import java.net.CookiePolicy @@ -103,40 +107,70 @@ object DownloadUtil { when (videoId) { ringBuffer.getOrNull(0)?.first -> dataSpec.withUri(ringBuffer.getOrNull(0)!!.second) ringBuffer.getOrNull(1)?.first -> dataSpec.withUri(ringBuffer.getOrNull(1)!!.second) - else -> { - val urlResult = runBlocking(Dispatchers.IO) { - Innertube.player(PlayerBody(videoId = videoId)) - }?.mapCatching { body -> - if (body.videoDetails?.videoId != videoId) { - throw VideoIdMismatchException() - } - - when (val status = body.playabilityStatus?.status) { - "OK" -> body.streamingData?.highestQualityFormat?.let { format -> - format.url - } ?: throw PlayableFormatNotFoundException() - - "UNPLAYABLE" -> throw UnplayableException() - "LOGIN_REQUIRED" -> throw LoginRequiredException() - else -> throw PlaybackException( - status, - null, - PlaybackException.ERROR_CODE_REMOTE_ERROR - ) - } - } - LogTag.LogD(TAG, "DownloadUtil urlResult->$urlResult") - - urlResult?.getOrThrow()?.let { url -> - ringBuffer.append(videoId to url.toUri()) - dataSpec.withUri(url.toUri()) - } ?: throw PlaybackException( - null, - urlResult?.exceptionOrNull(), - PlaybackException.ERROR_CODE_REMOTE_ERROR - ) - } +// else -> { +// val urlResult = runBlocking(Dispatchers.IO) { +// Innertube.player(PlayerBody(videoId = videoId)) +// }?.mapCatching { body -> +// if (body.videoDetails?.videoId != videoId) { +// throw VideoIdMismatchException() +// } +// +// when (val status = body.playabilityStatus?.status) { +// "OK" -> body.streamingData?.highestQualityFormat?.let { format -> +// format.url +// } ?: throw PlayableFormatNotFoundException() +// +// "UNPLAYABLE" -> throw UnplayableException() +// "LOGIN_REQUIRED" -> throw LoginRequiredException() +// else -> throw PlaybackException( +// status, +// null, +// PlaybackException.ERROR_CODE_REMOTE_ERROR +// ) +// } +// } +// LogTag.LogD(TAG, "DownloadUtil urlResult->$urlResult") +// +// urlResult?.getOrThrow()?.let { url -> +// ringBuffer.append(videoId to url.toUri()) +// dataSpec.withUri(url.toUri()) +// } ?: throw PlaybackException( +// null, +// urlResult?.exceptionOrNull(), +// PlaybackException.ERROR_CODE_REMOTE_ERROR +// ) +// } } + + // 进入协程安全调用你提供的获取方法 + val playbackResult = runBlocking(Dispatchers.IO) { + playerResponseForPlayback( + videoId = videoId, + connectivityManager = context.getSystemService()!! + ) + } + + val playbackData = playbackResult.getOrElse { ex -> + Log.e(TAG, "Failed to get playback data", ex) + throw PlaybackException( + ex.message ?: "Failed to get playback data", + ex, + PlaybackException.ERROR_CODE_REMOTE_ERROR + ) + } + + val streamUrl = playbackData.streamUrl + if (streamUrl.isEmpty()) { + throw PlaybackException("Stream URL is empty", null, PlaybackException.ERROR_CODE_REMOTE_ERROR) + } + + val uri = streamUrl.toUri() + + // 缓存 + ringBuffer.append(videoId to uri) + + LogD(TAG, "Resolved URL for $videoId: $streamUrl") + dataSpec.withUri(uri) } }