diff --git a/app/src/main/java/com/zionhuang/music/utils/YTPlayerUtils.kt b/app/src/main/java/com/zionhuang/music/utils/YTPlayerUtils.kt index bbd3ed5c8..6442d9ad7 100644 --- a/app/src/main/java/com/zionhuang/music/utils/YTPlayerUtils.kt +++ b/app/src/main/java/com/zionhuang/music/utils/YTPlayerUtils.kt @@ -53,8 +53,16 @@ object YTPlayerUtils { audioQuality: AudioQuality, connectivityManager: ConnectivityManager, ): Result = runCatching { + /** + * This is required for some clients to get working streams however + * it should not be forced for the [MAIN_CLIENT] because the response of the [MAIN_CLIENT] + * is required even if the streams won't work from this client. + * This is why it is allowed to be null. + */ + val signatureTimestamp = getSignatureTimestampOrNull(videoId) + val mainPlayerResponse = - YouTube.player(videoId, playlistId, client = MAIN_CLIENT).getOrThrow() + YouTube.player(videoId, playlistId, MAIN_CLIENT, signatureTimestamp).getOrThrow() val audioConfig = mainPlayerResponse.playerConfig?.audioConfig val videoDetails = mainPlayerResponse.videoDetails @@ -78,7 +86,7 @@ object YTPlayerUtils { // after main client use fallback clients val client = STREAM_FALLBACK_CLIENTS[clientIndex] streamPlayerResponse = - YouTube.player(videoId, playlistId, client).getOrNull() + YouTube.player(videoId, playlistId, client, signatureTimestamp).getOrNull() } // process current client response @@ -181,6 +189,19 @@ object YTPlayerUtils { return false } + /** + * Wrapper around the [NewPipeUtils.getSignatureTimestamp] function which reports exceptions + */ + private fun getSignatureTimestampOrNull( + videoId: String + ): Int? { + return NewPipeUtils.getSignatureTimestamp(videoId) + .onFailure { + reportException(it) + } + .getOrNull() + } + /** * Wrapper around the [NewPipeUtils.getStreamUrl] function which reports exceptions */ diff --git a/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt b/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt index 1e2561a9c..a1756ad2b 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/InnerTube.kt @@ -122,6 +122,7 @@ class InnerTube { client: YouTubeClient, videoId: String, playlistId: String?, + signatureTimestamp: Int?, ) = httpClient.post("player") { ytClient(client, setLogin = true) setBody( @@ -138,9 +139,9 @@ class InnerTube { videoId = videoId, playlistId = playlistId, playbackContext = - if (client.useSignatureTimestamp) { + if (client.useSignatureTimestamp && signatureTimestamp != null) { PlayerBody.PlaybackContext(PlayerBody.PlaybackContext.ContentPlaybackContext( - signatureTimestamp = NewPipeUtils.getSignatureTimestamp(videoId).getOrThrow() + signatureTimestamp )) } else null ) diff --git a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt index 211f2d9c2..7240df7b8 100644 --- a/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt +++ b/innertube/src/main/java/com/zionhuang/innertube/YouTube.kt @@ -431,8 +431,8 @@ object YouTube { } } - suspend fun player(videoId: String, playlistId: String? = null, client: YouTubeClient): Result = runCatching { - innerTube.player(client, videoId, playlistId).body() + suspend fun player(videoId: String, playlistId: String? = null, client: YouTubeClient, signatureTimestamp: Int? = null): Result = runCatching { + innerTube.player(client, videoId, playlistId, signatureTimestamp).body() } suspend fun next(endpoint: WatchEndpoint, continuation: String? = null): Result = runCatching {