MoonGetter MoonGetter is a robust, Kotlin-first library engineered for seamless stream extraction and video hosting download logic. It offers comprehensive support for Android and is now fully Kotlin Multiplatform (KMP) ready, featuring flexible custom server integration.
- Custom Server Integration β Easily build and integrate your own streaming providers.
- Coroutine-based Architecture β Async-first design for highly scalable extraction logic.
- Transparent HTTP Client Injection β Works seamlessly with both OkHttp and Ktor.
- Custom Error Types β Intuitive error handling via
InvalidServerException
and descriptiveError
enums. - Flexible Cookie Management β Automatic for OkHttp, configurable for Ktor.
Feature | Android | JVM | Kotlin Multiplatform |
---|---|---|---|
Core Library | β | β | β |
Robot Servers API | β | β³(desktop) | β³ (Planned) |
Server Implementations | β | β | β |
β = Supported / β³ = In development / JVM refers to non-Android Kotlin projects.
β Actively maintained / π₯ Deprecated
- β Google Drive
- β Mediafire
- β Streamtape
- β PixelDrain
- β Okru
- β StreamWish
- π₯ Voe (Deprecated)
- β Senvid
- β Vihide
- β Hexload
- β YourUpload
- β Facebook
- β XTwitter
- β LuluStream
- β Mp4Upload
- β Uqload
- β Mixdrop
- β Doodstream
- β Vidguard
- β Filemoon
- β VK
These require the
moongetter-core-robot
module and a platform-specific Robot API.
- π₯ Fireload (Deprecated)
- β 1CloudFile
Coming Soon: GoodStream, Gofile, Abyss
// For stable releases, use Maven Central
repositories {
mavenCentral()
}
This section outlines the dependencies
block specifically for integrating MoonGetter modules within a Kotlin Multiplatform (KMP) project structure. It focuses solely on MoonGetter-related dependencies, showing their placement for common shared code, Android-specific configurations, and iOS (Darwin) targets.
val moonGetterVersion = "2.0.0-alpha02"
dependencies {
// --- Common Main (Shared KMP Logic) ---
commonMain.dependencies {
implementation("io.github.darkryh.moongetter:moongetter-core:$moonGetterVersion")
implementation("io.github.darkryh.moongetter:moongetter-client-ktor:$moonGetterVersion")
implementation("io.github.darkryh.moongetter:moongetter-server-bundle:$moonGetterVersion")
implementation("io.github.darkryh.moongetter:moongetter-core-robot:$moonGetterVersion")
implementation("io.github.darkryh.moongetter:moongetter-server-robot-bundle:$moonGetterVersion")
// Optional: Individual server modules (instead of bundles)
// implementation("io.github.darkryh.moongetter:moongetter-mp4upload:$moonGetterVersion")
}
// --- Android Specific ---
androidMain.dependencies {
// Choose ONE HTTP client:
implementation("io.github.darkryh.moongetter:moongetter-client-okhttp:$moonGetterVersion") // Option 1: MoonGetter OkHttp Client
// OR
// implementation("io.ktor:ktor-client-okhttp:2.3.12") // Option 2: Ktor with OkHttp engine
implementation("io.github.darkryh.moongetter:moongetter-client-cookie-java-net:$moonGetterVersion") // Cookie management
implementation("io.github.darkryh.moongetter:moongetter-client-trustmanager-java-net:$moonGetterVersion") // Trust management
implementation("io.github.darkryh.moongetter:moongetter-android-robot:$moonGetterVersion") // Android Robot APIs
}
// --- iOS Specific ---
iosMain.dependencies {
// REQUIRED: Ktor's Darwin engine for network requests on iOS.
implementation("io.ktor:ktor-client-darwin:2.3.12")
}
// --- Desktop (JVM) Specific ---
desktopMain.dependencies {
// Choose ONE HTTP client:
implementation("io.ktor:ktor-client-cio:2.3.12") // Option 1: Ktor with CIO engine
// OR
// implementation("io.github.darkryh.moongetter:moongetter-client-okhttp:$moonGetterVersion") // Option 2: MoonGetter OkHttp Client
implementation("io.github.darkryh.moongetter:moongetter-client-cookie-java-net:$moonGetterVersion") // Cookie management
implementation("io.github.darkryh.moongetter:moongetter-client-trustmanager-java-net:$moonGetterVersion") // Trust management
}
}
This section outlines the dependencies
block for integrating MoonGetter modules into a standard Java or Kotlin JVM project. This includes typical Android applications or standalone desktop JVM applications that do not use Kotlin Multiplatform.
val moonGetterVersion = "2.0.0-alpha02"
dependencies {
// --- Core & Server Support ---
implementation("io.github.darkryh.moongetter:moongetter-core:$moonGetterVersion")
implementation("io.github.darkryh.moongetter:moongetter-server-bundle:$moonGetterVersion")
implementation("io.github.darkryh.moongetter:moongetter-core-robot:$moonGetterVersion")
implementation("io.github.darkryh.moongetter:moongetter-server-robot-bundle:$moonGetterVersion")
// Optional: Individual server modules
// implementation("io.github.darkryh.moongetter:moongetter-mp4upload:$moonGetterVersion")
// --- HTTP Client & Utilities ---
// Choose your client:
implementation("io.github.darkryh.moongetter:moongetter-client-okhttp:$moonGetterVersion") // Option 1: OkHttp (recommended)
// OR
// implementation("io.github.darkryh.moongetter:moongetter-client-ktor:$moonGetterVersion") // Option 2: Ktor
// + Ktor engine (e.g., "io.ktor:ktor-client-okhttp:2.3.12" or "io.ktor:ktor-client-cio:2.3.12")
implementation("io.github.darkryh.moongetter:moongetter-client-cookie-java-net:$moonGetterVersion") // Cookie management
implementation("io.github.darkryh.moongetter:moongetter-client-trustmanager-java-net:$moonGetterVersion") // Trust management
// Android-specific Robot (only for Android projects)
implementation("io.github.darkryh.moongetter:moongetter-android-robot:$moonGetterVersion")
}
Client Library | Module | Cookie Management | KMP Support |
---|---|---|---|
OkHttp | moongetter-client-okhttp |
β Built-in | β³ Not Supported |
Ktor | moongetter-client-ktor |
β Experimental | |
JavaNetCookieManager | moongetter-client-cookie-java-net |
β (Only for Ktor, optional) | β³ Not Supported |
β = Supported /
β οΈ = Manual setup / β³ = Coming soon
Note:
-
OkHttp has built-in cookie support, no setup needed.
-
Ktor requires you to explicitly inject cookie management (e.g.,
JavaNetCookieManagement
).Example Initialization:
MoonGetter.start(
MoonFactory
.Builder()
.setClient(
client = KtorMoonClient(
engineFactory = httpClientEngineFactory,
cookieManagement = cookieManagement,
trustManager = trustManager
)
)
.setTimeout(timeoutMillis = 12000)
.setEngine(engine = engine)
)
Example with Ktor:
MoonFactory.Builder()
.setClient(
KtorMoonClient(
engineFactory = CIO, //on iOS Darwin
cookieManagement = JavaNetCookieManagement(), //on iOS MoonCookie.Management.newEmptyFactory()
trustManager = JavaMoonTrustManager // on iOS MoonTrust.Manager.newEmptyFactory()
)
)
Example with OkHttp:
MoonFactory.Builder()
.setClient(
OkHttpClient
)
class MyViewModel : ViewModel() {
private val engine = Engine.Builder()
.onCore(
engines = arrayOf(
Mp4UploadFactory,
FilemoonFactory,
StreamtapeFactory,
StreamwishFactory,
// CustomServerFactory (recommended to use `object`)
)
)
.build()
fun getMediaStreams(url: String) = viewModelScope.launch(Dispatchers.IO) {
try {
MoonGetter.start(
MoonFactory
.Builder()
.setClient(
KtorMoonClient(
engineFactory = CIO,//jvm other option Okhttp //on iOS Darwin
cookieManagement = JavaNetCookieManagement(), //on iOS MoonCookie.Management.newEmptyFactory()
trustManager = JavaMoonTrustManager // on iOS MoonTrust.Manager.newEmptyFactory()
)
)
.setTimeout(8000)
.setEngine(engine)
)
val server : Server = MoonGetter.get(url) // returns server
val serverNullable : Server? = MoonGetter.getOrNull(url) // returns server or null, in this case there's no need wrap in try catch
val streams = server?.videos
} catch (e: InvalidServerException) {
Log.e("MoonGetter", "Invalid: ${e.message}", e)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
class CustomServer(
url: String,
client: MoonClient,
headers: HashMap<String, String>,
configData: Configuration.Data
) : Server(url, client, headers, configData) {
private val urlRegex = """https://custom\.domain\.com/aqua/sv\?url=([^&]+)""".toRegex()
override var url: String = urlRegex.find(url)?.groupValues?.get(1)
?: throw InvalidServerException(
Resources.invalidProcessInExpectedUrlEntry(name),
Error.INVALID_PROCESS_IN_EXPECTED_URL_ENTRY
)
override suspend fun onExtract(): List<Video> {
val response = client.GET()
if (!response.isSuccess) throw InvalidServerException(
Resources.unsuccessfulResponse(name),
Error.UNSUCCESSFUL_RESPONSE,
response.statusCode
)
return listOf(
Video(
quality = DEFAULT,
url = PatternManager.singleMatch(
string = response.body.asString(),
regex = "<source src=\"(.*?)\""
) ?: throw InvalidServerException(
Resources.expectedResponseNotFound(name),
Error.EXPECTED_RESPONSE_NOT_FOUND
)
)
)
}
}
object CustomServerFactory : Server.Factory {
override val serverName: String = "MyCustomServer" // Must match the serverName in CustomServer
override val pattern: String = """https://custom\.domain\.com/aqua/sv\?url=([^&]+)""" // Your regex pattern for URLs this server handles
//instance function since kmp doesnt support reflection
override fun create(
url: String,
headers: HashMap<String, String>,
configData: Configuration.Data,
client: MoonClient
): Server = CustomServer(
url = url,
client = client,
headers = headers,
configData = configData
)
}
The MoonGetter
object provides several methods to resolve [Server] instances from URLs.
Before using any of these functions, you must initialize the library with start(factory: Factory.Builder)
.
If it is not initialized, the methods will throw [InvalidServerException] with error [Error.CONFIG_NOT_INITIALIZED].
Resolves a single [Server] for the given URL.
Unlike the getOrNull
variant, this method throws an exception if resolution fails.
-
Parameters
url: String
β Candidate URL to resolve into a server.
-
Returns
- [Server] β A non-null instance corresponding to the provided URL.
-
Throws
- [InvalidServerException] if the factory is not initialized.
- [RuntimeException] for unexpected runtime errors.
Safe variant of get(url)
.
Instead of throwing when no server can be resolved, it returns null
.
-
Parameters
url: String
-
Returns
- [Server]? β A resolved instance if successful, or
null
if none could be found.
- [Server]? β A resolved instance if successful, or
-
Throws
- [InvalidServerException] when the factory has not been initialized.
Resolves multiple [Server] instances in one call, keeping the same order as the input URLs.
All returned elements are non-null.
-
Parameters
urls: List<String>
β List of candidate URLs.
-
Returns
List<Server>
β A list of resolved server instances, one for each input URL.
-
Throws
- [InvalidServerException] if the factory is not initialized.
- [RuntimeException] for unexpected runtime errors.
Sequentially checks a list of URLs until the first valid [Server] is found.
If no valid server is found, it throws an exception.
-
Parameters
urls: List<String>
-
Returns
- [Server] β The first successfully resolved server.
-
Throws
- [InvalidServerException] if the factory is not initialized or no valid server is found.
- [RuntimeException] for unexpected runtime errors.
Safe variant of getUntilFindResource(urls)
.
Instead of throwing when no valid server is found, it returns null
.
getOrNull
, [InvalidServerException] is still thrown if the factory has not been initialized.
-
Parameters
urls: List<String>
-
Returns
- [Server]? β The first valid server found, or
null
if none could be resolved.
- [Server]? β The first valid server found, or
-
Throws
- [InvalidServerException] if the factory has not been initialized.
π Key Notes:
get
variants always return non-null and assume successful resolution.getOrNull
variants return nullable for resolution failures, but still throw if the factory was not initialized.get(urls: List<String>)
always returns a non-null list with non-null elements.
If you'd like to contribute or propose a new feature, feel free to reach out via X / Twitter @Darkryh or open a PR/request.
MoonGetter is in active development to expand KMP support. Swift/iOS support is coming soon.