From b977ea7976df1cb6c17e8336031f4d6194dbd52a Mon Sep 17 00:00:00 2001 From: deniscerri <64997243+deniscerri@users.noreply.github.com> Date: Sat, 12 Sep 2026 10:21:31 +0200 Subject: [PATCH] init packages concurrently --- .../deniscerri/ytdl/core/RuntimeManager.kt | 178 ++++++++++-------- .../deniscerri/ytdl/core/packages/Aria2c.kt | 14 +- .../com/deniscerri/ytdl/core/packages/Deno.kt | 16 +- .../deniscerri/ytdl/core/packages/FFmpeg.kt | 16 +- .../deniscerri/ytdl/core/packages/NodeJS.kt | 16 +- .../ytdl/core/packages/PackageBase.kt | 4 +- .../deniscerri/ytdl/core/packages/Python.kt | 16 +- .../deniscerri/ytdl/core/packages/QuickJS.kt | 16 +- 8 files changed, 146 insertions(+), 130 deletions(-) diff --git a/app/src/main/java/com/deniscerri/ytdl/core/RuntimeManager.kt b/app/src/main/java/com/deniscerri/ytdl/core/RuntimeManager.kt index e08e2944..d04d9a80 100644 --- a/app/src/main/java/com/deniscerri/ytdl/core/RuntimeManager.kt +++ b/app/src/main/java/com/deniscerri/ytdl/core/RuntimeManager.kt @@ -19,6 +19,10 @@ import com.deniscerri.ytdl.core.stream.StreamGobbler import com.deniscerri.ytdl.core.stream.StreamProcessExtractor import com.deniscerri.ytdl.database.models.PackageItem import com.deniscerri.ytdl.util.FileUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.filter @@ -84,84 +88,90 @@ object RuntimeManager { if (initialized) return synchronized(initLock) { - val baseDir = File(appContext.noBackupFilesDir, BASENAME).apply { if (!exists()) mkdir() } - - val python = Python.getInstance() - val ffmpeg = FFmpeg.getInstance() - val aria2c = Aria2c.getInstance() - val nodeJS = NodeJS.getInstance() - val quickJS = QuickJS.getInstance() - val deno = Deno.getInstance() - - python.init(appContext) - ffmpeg.init(appContext) - aria2c.init(appContext) - nodeJS.init(appContext) - quickJS.init(appContext) - deno.init(appContext) - - //find location of libraries either from bundled or downloaded paths - pythonLocation = python.location - ffmpegLocation = ffmpeg.location - aria2Location = aria2c.location - nodeLocation = nodeJS.location - denoLocation = deno.location - quickJsLocation = quickJS.location - - val ytdlpDir = File(baseDir, ytdlpDirName) - ytdlpPath = File(ytdlpDir, ytdlpBin) - initYTDLP(appContext, ytdlpDir) - - val locations = listOf( - pythonLocation, - ffmpegLocation, - aria2Location, - nodeLocation, - quickJsLocation, - denoLocation, - ) - - val ldPaths = mutableListOf() - locations.forEach { - val usrLib = File(it.ldDir, "usr/lib") - if (usrLib.exists()) { - ldPaths.add(usrLib.absolutePath) - } else if (it.ldDir.exists()) { - ldPaths.add(it.ldDir.absolutePath) - } - } - ldPaths.add(appContext.applicationInfo.nativeLibraryDir) - ENV_LD_LIBRARY_PATH = ldPaths.distinct().joinToString(":") - - val binPaths = locations.filter { it.binDir.exists() }.map { it.binDir.absolutePath }.toMutableList() - binPaths.add(System.getenv("PATH") ?: "/system/bin") - PATH = binPaths.distinct().joinToString(":") - - ENV_SSL_CERT_FILE = if (pythonLocation.isDownloaded) { - File(pythonLocation.ldDir.parentFile, "usr/etc/tls/cert.pem").absolutePath - } else { - pythonLocation.ldDir.absolutePath + "/usr/etc/tls/cert.pem" - } - - OPEN_SSL_CONF = "" - if (nodeLocation.ldDir.exists()) { - OPEN_SSL_CONF = if (nodeLocation.isDownloaded) { - File(nodeLocation.ldDir.parentFile, "usr/etc/tls/openssl.cnf").absolutePath - } else { - nodeLocation.ldDir.absolutePath + "/usr/etc/tls/openssl.cnf" - } - } - - ENV_PYTHONHOME = if (pythonLocation.isDownloaded) { - pythonLocation.ldDir.absolutePath + "/usr" - } else { - pythonLocation.ldDir.absolutePath + "/usr" - } - TMPDIR = appContext.cacheDir.absolutePath - - NPM_CONFIG_PREFIX = File(appContext.filesDir, ".npm-global").absolutePath - NPM_CONFIG_CACHE = File(appContext.filesDir, ".npm-cache").absolutePath - //TODO + if (initialized) return + + runBlocking(Dispatchers.IO) { + try { + val baseDir = File(appContext.noBackupFilesDir, BASENAME).apply { if (!exists()) mkdir() } + + val python = Python.getInstance() + val ffmpeg = FFmpeg.getInstance() + val aria2c = Aria2c.getInstance() + val nodeJS = NodeJS.getInstance() + val quickJS = QuickJS.getInstance() + val deno = Deno.getInstance() + + coroutineScope { + val packages = listOf(python, ffmpeg, aria2c, nodeJS, quickJS, deno) + packages.map { pkg -> + async { + pkg.init(appContext) + } + }.awaitAll() + } + + //find location of libraries either from bundled or downloaded paths + pythonLocation = python.location + ffmpegLocation = ffmpeg.location + aria2Location = aria2c.location + nodeLocation = nodeJS.location + denoLocation = deno.location + quickJsLocation = quickJS.location + + val ytdlpDir = File(baseDir, ytdlpDirName) + ytdlpPath = File(ytdlpDir, ytdlpBin) + initYTDLP(appContext, ytdlpDir) + + val locations = listOf( + pythonLocation, + ffmpegLocation, + aria2Location, + nodeLocation, + quickJsLocation, + denoLocation, + ) + + val ldPaths = mutableListOf() + locations.forEach { + val usrLib = File(it.ldDir, "usr/lib") + if (usrLib.exists()) { + ldPaths.add(usrLib.absolutePath) + } else if (it.ldDir.exists()) { + ldPaths.add(it.ldDir.absolutePath) + } + } + ldPaths.add(appContext.applicationInfo.nativeLibraryDir) + ENV_LD_LIBRARY_PATH = ldPaths.distinct().joinToString(":") + + val binPaths = locations.filter { it.binDir.exists() }.map { it.binDir.absolutePath }.toMutableList() + binPaths.add(System.getenv("PATH") ?: "/system/bin") + PATH = binPaths.distinct().joinToString(":") + + ENV_SSL_CERT_FILE = if (pythonLocation.isDownloaded) { + File(pythonLocation.ldDir.parentFile, "usr/etc/tls/cert.pem").absolutePath + } else { + pythonLocation.ldDir.absolutePath + "/usr/etc/tls/cert.pem" + } + + OPEN_SSL_CONF = "" + if (nodeLocation.ldDir.exists()) { + OPEN_SSL_CONF = if (nodeLocation.isDownloaded) { + File(nodeLocation.ldDir.parentFile, "usr/etc/tls/openssl.cnf").absolutePath + } else { + nodeLocation.ldDir.absolutePath + "/usr/etc/tls/openssl.cnf" + } + } + + ENV_PYTHONHOME = if (pythonLocation.isDownloaded) { + pythonLocation.ldDir.absolutePath + "/usr" + } else { + pythonLocation.ldDir.absolutePath + "/usr" + } + TMPDIR = appContext.cacheDir.absolutePath + + NPM_CONFIG_PREFIX = File(appContext.filesDir, ".npm-global").absolutePath + NPM_CONFIG_CACHE = File(appContext.filesDir, ".npm-cache").absolutePath + //TODO // if (nodeLocation.executable.exists()) { // NPM_CLI_PATH = File(nodeLocation.ldDir.absolutePath, "usr/lib/node_modules/npm/bin/npm-cli.js").absolutePath // @@ -170,9 +180,15 @@ object RuntimeManager { // NODE_OPTIONS = "--require ${optionsFile.absolutePath}" // } - initialized = true - initLatch.countDown() - updateLatch.countDown() + initialized = true + } catch (e: Exception) { + e.printStackTrace() + initialized = false + } finally { + initLatch.countDown() + updateLatch.countDown() + } + } } } diff --git a/app/src/main/java/com/deniscerri/ytdl/core/packages/Aria2c.kt b/app/src/main/java/com/deniscerri/ytdl/core/packages/Aria2c.kt index 7cfb3bef..6747ee3c 100644 --- a/app/src/main/java/com/deniscerri/ytdl/core/packages/Aria2c.kt +++ b/app/src/main/java/com/deniscerri/ytdl/core/packages/Aria2c.kt @@ -1,12 +1,12 @@ package com.deniscerri.ytdl.core.packages object Aria2c : PackageBase() { - override val executableName: String = "aria2c" - override val packageFolderName: String = "aria2c" - override val bundledZipName: String = "libaria2c.zip.so" + override val executableName: String get() = "aria2c" + override val packageFolderName: String get() = "aria2c" + override val bundledZipName: String get() = "libaria2c.zip.so" override val canUninstall: Boolean = false - override val bundledVersion: String = "v1.37.0" - override val githubRepo: String = "deniscerri/ytdlnis-packages" - override val githubPackageName: String = "aria2c" - override val apkPackage: String = "com.deniscerri.ytdl.aria2c" + override val bundledVersion: String get() = "v1.37.0" + override val githubRepo: String get() = "deniscerri/ytdlnis-packages" + override val githubPackageName: String get() = "aria2c" + override val apkPackage: String get() = "com.deniscerri.ytdl.aria2c" } \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdl/core/packages/Deno.kt b/app/src/main/java/com/deniscerri/ytdl/core/packages/Deno.kt index c6999b2b..ea4bd109 100644 --- a/app/src/main/java/com/deniscerri/ytdl/core/packages/Deno.kt +++ b/app/src/main/java/com/deniscerri/ytdl/core/packages/Deno.kt @@ -1,12 +1,12 @@ package com.deniscerri.ytdl.core.packages object Deno : PackageBase() { - override val executableName: String = "deno" - override val packageFolderName: String = "deno" - override val bundledZipName: String = "libdeno.zip.so" - override val canUninstall: Boolean = true - override val bundledVersion: String = "" - override val githubRepo: String = "deniscerri/ytdlnis-packages" - override val githubPackageName: String = "deno" - override val apkPackage: String = "com.deniscerri.ytdl.deno" + override val executableName: String get() = "deno" + override val packageFolderName: String get() = "deno" + override val bundledZipName: String get() = "libdeno.zip.so" + override val canUninstall: Boolean get() = true + override val bundledVersion: String get() = "" + override val githubRepo: String get() = "deniscerri/ytdlnis-packages" + override val githubPackageName: String get() = "deno" + override val apkPackage: String get() = "com.deniscerri.ytdl.deno" } \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdl/core/packages/FFmpeg.kt b/app/src/main/java/com/deniscerri/ytdl/core/packages/FFmpeg.kt index 10eca420..872ff2b8 100644 --- a/app/src/main/java/com/deniscerri/ytdl/core/packages/FFmpeg.kt +++ b/app/src/main/java/com/deniscerri/ytdl/core/packages/FFmpeg.kt @@ -1,12 +1,12 @@ package com.deniscerri.ytdl.core.packages object FFmpeg : PackageBase() { - override val executableName: String = "ffmpeg" - override val packageFolderName: String = "ffmpeg" - override val bundledZipName: String = "libffmpeg.zip.so" - override val canUninstall: Boolean = false - override val bundledVersion: String = "v7.0.1" - override val githubRepo: String = "deniscerri/ytdlnis-packages" - override val githubPackageName: String = "ffmpeg" - override val apkPackage: String = "com.deniscerri.ytdl.ffmpeg" + override val executableName: String get() = "ffmpeg" + override val packageFolderName: String get() = "ffmpeg" + override val bundledZipName: String get() = "libffmpeg.zip.so" + override val canUninstall: Boolean get() = false + override val bundledVersion: String get() = "v7.0.1" + override val githubRepo: String get() = "deniscerri/ytdlnis-packages" + override val githubPackageName: String get() = "ffmpeg" + override val apkPackage: String get() = "com.deniscerri.ytdl.ffmpeg" } \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdl/core/packages/NodeJS.kt b/app/src/main/java/com/deniscerri/ytdl/core/packages/NodeJS.kt index bdea9bd9..613cbc3c 100644 --- a/app/src/main/java/com/deniscerri/ytdl/core/packages/NodeJS.kt +++ b/app/src/main/java/com/deniscerri/ytdl/core/packages/NodeJS.kt @@ -1,14 +1,14 @@ package com.deniscerri.ytdl.core.packages object NodeJS : PackageBase() { - override val executableName: String = "node" - override val packageFolderName: String = "node" - override val bundledZipName: String = "libnode.zip.so" - override val canUninstall: Boolean = true - override val bundledVersion: String = "" - override val githubRepo: String = "deniscerri/ytdlnis-packages" - override val githubPackageName: String = "nodejs" - override val apkPackage: String = "com.deniscerri.ytdl.nodejs" + override val executableName: String get() = "node" + override val packageFolderName: String get() = "node" + override val bundledZipName: String get() = "libnode.zip.so" + override val canUninstall: Boolean get() = true + override val bundledVersion: String get() = "" + override val githubRepo: String get() = "deniscerri/ytdlnis-packages" + override val githubPackageName: String get() = "nodejs" + override val apkPackage: String get() = "com.deniscerri.ytdl.nodejs" fun getDNSSetup() : String { return """ diff --git a/app/src/main/java/com/deniscerri/ytdl/core/packages/PackageBase.kt b/app/src/main/java/com/deniscerri/ytdl/core/packages/PackageBase.kt index 23b104b0..449a8de1 100644 --- a/app/src/main/java/com/deniscerri/ytdl/core/packages/PackageBase.kt +++ b/app/src/main/java/com/deniscerri/ytdl/core/packages/PackageBase.kt @@ -125,7 +125,7 @@ abstract class PackageBase { targetDir.mkdirs() try { ZipUtils.unzip(bundledZip, targetDir) - prefs.edit(commit = true) { + prefs.edit { if (packageApkVersion != null) { putString(downloadedVersionKey, packageApkVersion) } else { @@ -256,7 +256,7 @@ abstract class PackageBase { private fun saveState(context: Context, version: String) { val prefs = PreferenceManager.getDefaultSharedPreferences(context) - prefs.edit(commit = true) { + prefs.edit { putString(downloadedVersionKey, version) } } diff --git a/app/src/main/java/com/deniscerri/ytdl/core/packages/Python.kt b/app/src/main/java/com/deniscerri/ytdl/core/packages/Python.kt index d0bc32f5..01e27f28 100644 --- a/app/src/main/java/com/deniscerri/ytdl/core/packages/Python.kt +++ b/app/src/main/java/com/deniscerri/ytdl/core/packages/Python.kt @@ -3,12 +3,12 @@ package com.deniscerri.ytdl.core.packages import com.deniscerri.ytdl.BuildConfig object Python : PackageBase() { - override val executableName: String = "python" - override val packageFolderName: String = "python" - override val bundledZipName: String = "libpython.zip.so" - override val bundledVersion: String = if (BuildConfig.FLAVOR == "izzy") "v3.12.11" else "v3.14.6" - override val canUninstall: Boolean = false - override val githubRepo: String = "deniscerri/ytdlnis-packages" - override val githubPackageName: String = "python" - override val apkPackage: String = "com.deniscerri.ytdl.python" + override val executableName: String get() = "python" + override val packageFolderName: String get() = "python" + override val bundledZipName: String get() = "libpython.zip.so" + override val bundledVersion: String get() = if (BuildConfig.FLAVOR == "izzy") "v3.12.11" else "v3.14.6" + override val canUninstall: Boolean get() = false + override val githubRepo: String get() = "deniscerri/ytdlnis-packages" + override val githubPackageName: String get() = "python" + override val apkPackage: String get() = "com.deniscerri.ytdl.python" } \ No newline at end of file diff --git a/app/src/main/java/com/deniscerri/ytdl/core/packages/QuickJS.kt b/app/src/main/java/com/deniscerri/ytdl/core/packages/QuickJS.kt index 02f89a01..7550658d 100644 --- a/app/src/main/java/com/deniscerri/ytdl/core/packages/QuickJS.kt +++ b/app/src/main/java/com/deniscerri/ytdl/core/packages/QuickJS.kt @@ -1,12 +1,12 @@ package com.deniscerri.ytdl.core.packages object QuickJS : PackageBase() { - override val executableName: String = "qjs" - override val packageFolderName: String = "quickjs" - override val bundledZipName: String = "libqjs.zip.so" - override val bundledVersion: String = "2025-04-26" - override val canUninstall: Boolean = false - override val githubRepo: String = "" - override val githubPackageName: String = "" - override val apkPackage: String = "" + override val executableName: String get() = "qjs" + override val packageFolderName: String get() = "quickjs" + override val bundledZipName: String get() = "libqjs.zip.so" + override val bundledVersion: String get() = "2025-04-26" + override val canUninstall: Boolean get() = false + override val githubRepo: String get() = "" + override val githubPackageName: String get() = "" + override val apkPackage: String get() = "" } \ No newline at end of file