Skip to content

Instantly share code, notes, and snippets.

@ShivamKumarJha
Created October 26, 2025 14:44
Show Gist options
  • Select an option

  • Save ShivamKumarJha/02dfbef4a119268b460d58322cf16f80 to your computer and use it in GitHub Desktop.

Select an option

Save ShivamKumarJha/02dfbef4a119268b460d58322cf16f80 to your computer and use it in GitHub Desktop.
StreamTape
package com.shivamkumarjha.network_common
import kotlinx.serialization.Serializable
@Serializable
data class HttpRequestData(
val url: String,
val headers: Map<String, String> = emptyMap(),
val queries: Map<String, String> = emptyMap(),
val body: String? = null,
)
package com.shivamkumarjha.media_extractor.extractors
import com.fleeksoft.ksoup.Ksoup
import com.shivamkumarjha.media_common.model.Media
import com.shivamkumarjha.media_common.model.MediaPlayerItem
import com.shivamkumarjha.media_extractor.BaseMediaExtractor
import com.shivamkumarjha.network_client.getEmbedHeaders
import com.shivamkumarjha.network_client.getHost
import com.shivamkumarjha.network_client.getHttpRequestData
import com.shivamkumarjha.network_common.HttpRequestData
import com.shivamkumarjha.network_common.Resource
import com.shivamkumarjha.utility_logging.logger
import io.ktor.client.HttpClient
import io.ktor.client.statement.bodyAsText
import io.ktor.http.isSuccess
internal class StreamTapeExtractor(
private val httpClient: HttpClient,
) : BaseMediaExtractor() {
override val tag: String
get() = "StreamTape"
override suspend fun isSupported(httpRequestData: HttpRequestData): Boolean {
return httpRequestData.url.getHost().contains("streamtape") ||
httpRequestData.url.getHost().contains("tapepops")
}
override suspend fun mediaPlayerItem(
httpRequestData: HttpRequestData,
callback: suspend (MediaPlayerItem) -> Unit
): Resource<MediaPlayerItem> {
val newUrl = if (httpRequestData.url.contains("/v/"))
httpRequestData.url
.replace("/v/", "/e/")
.replace(".com", ".xyz")
.substringBeforeLast("/")
else
httpRequestData.url.replace(".com", ".xyz")
val response = httpClient.getHttpRequestData(httpRequestData.copy(url = newUrl))
if (!response.status.isSuccess()) {
val throwable = Throwable(response.status.toString())
logger.error("Failed mediaPlayerItem $httpRequestData", throwable, tag = tag)
return Resource.Error(null, throwable)
}
val body = response.bodyAsText()
val document = Ksoup.parse(body)
val targetLine = "document.getElementById('robotlink')"
val script = document.selectFirst("script:containsData($targetLine)")
?.data()
?.substringAfter("$targetLine.innerHTML = '")
if (script.isNullOrEmpty()) {
val throwable = Throwable("Not found")
logger.error("BAD unpacked", throwable, tag = tag)
return Resource.Error(null, throwable)
}
val mediaUrl = "https:" + script.substringBefore("'") +
script.substringAfter("+ ('xcd").substringBefore("'")
val mediaItems = listOf(
Media(
httpRequestData = HttpRequestData(
url = mediaUrl,
headers = httpRequestData.url.getEmbedHeaders(),
),
label = httpRequestData.url.getHost(),
description = mediaUrl.getHost(),
)
)
return Resource.Success(MediaPlayerItem(mediaItems))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment