diff --git a/.gitignore b/.gitignore
index aa724b7..9184f80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,6 @@
.externalNativeBuild
.cxx
local.properties
+
+# Built FFmpeg AAR - see tools/ffmpeg/ for the build recipe
+app/libs/*.aar
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c824f74
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Jason Ross
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/LICENSES/README.md b/LICENSES/README.md
new file mode 100644
index 0000000..f0ac010
--- /dev/null
+++ b/LICENSES/README.md
@@ -0,0 +1,62 @@
+# Licensing
+
+This project has a **split license**, and the distinction matters.
+
+## Source code — MIT
+
+Everything in this repository that we wrote is MIT licensed. See [`../LICENSE`](../LICENSE).
+
+## Distributed binary (APK / AAB) — GPL-3.0
+
+The shipped application binary is **GPL-3.0**, not MIT.
+
+The app bundles FFmpeg built with `--enable-gpl`, which pulls in **x264** and **x265**
+(both GPL-2.0-or-later). Combining those with the application makes the *distributed
+binary* a GPL work. MIT → GPL is a compatible direction, so our own source stays MIT;
+the combined binary you install is GPL-3.0.
+
+### Why GPL rather than LGPL
+
+Building without `--enable-gpl` would keep the binary LGPL, and most features survive
+that: hardware H.264/HEVC encode via MediaCodec, MP3 via libmp3lame, AV1, VP9, Opus,
+FLAC, and even subtitle burn-in (libass is ISC licensed, not GPL — a common
+misconception).
+
+What GPL specifically buys is **x264/x265 software encode**, which is the only way to
+get CRF and 2-pass rate control. Those are the tools that actually deliver
+quality-per-bitrate for "compress this video well", and no hardware encoder on Android
+exposes either. That capability was judged worth the license.
+
+### Corresponding source
+
+GPL-3.0 requires that complete corresponding source accompany the binary. For each
+release we publish, alongside the APK:
+
+- the exact FFmpeg source tarball or commit used,
+- the full `configure` line, and
+- any patches applied.
+
+FFmpeg's own guidance says to host the source "on the same webserver" as the binary.
+That is not literally possible for a Google Play listing, so the source is attached to
+the corresponding **GitHub Release next to the APK**, and linked from both the Play
+listing and the in-app About screen.
+
+## Third-party components
+
+| Component | License | Notes |
+|---|---|---|
+| AndroidX / Jetpack Compose | Apache-2.0 | |
+| AndroidX Media3 (Transformer, Effect) | Apache-2.0 | primary hardware conversion path |
+| FFmpeg | LGPL-2.1+, **GPL-2.0+ as built here** | `--enable-gpl` |
+| x264 | GPL-2.0+ | the reason the binary is GPL |
+| x265 | GPL-2.0+ | |
+| libass | **ISC** | subtitle burn-in; not GPL |
+| libmp3lame | LGPL | MP3 encode |
+| libvpx, dav1d, SVT-AV1, libopus | BSD-style | |
+
+### Explicitly excluded
+
+- **`--enable-nonfree`** is never used. FFmpeg states it makes the resulting binary
+ *unredistributable*. This rules out `libfdk_aac` and `decklink`.
+- **OpenH264** is not used. Its BSD-2 source license is *not* a patent grant — Cisco's
+ royalty payment covers only Cisco's own precompiled binary module.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..746efce
--- /dev/null
+++ b/README.md
@@ -0,0 +1,82 @@
+# Media Converter
+
+A free and open-source media converter for Android — batch video transcoding and
+compression, audio extraction and conversion, GIF and frame export, and file merging.
+
+Android 13+ (API 33). Built with Jetpack Compose and Material 3.
+
+> **Status: early development.** The project scaffold and UI shell exist; the conversion
+> pipeline is being built out. Not yet usable.
+
+## Licensing at a glance
+
+- **Source code: MIT**
+- **Distributed APK: GPL-3.0** — because it bundles FFmpeg built with x264/x265
+
+That split is deliberate, not an oversight. See [`LICENSES/README.md`](LICENSES/README.md)
+for the reasoning and the corresponding-source obligations.
+
+## Architecture
+
+Two conversion engines behind an explicit router, because neither one covers the job alone.
+
+### AndroidX Media3 Transformer — the hardware path
+
+Handles the common cases: MP4/MOV in and out, H.264/HEVC, resolution and frame-rate
+changes, rotation, overlays, audio to AAC, and stream-copy transmuxing. Fully hardware
+accelerated end to end — MediaCodec decodes to a GL surface and MediaCodec re-encodes,
+so frames never round-trip through the CPU. Roughly 7–8× realtime on 720p.
+
+### FFmpeg — the long tail
+
+Everything Media3 structurally cannot do:
+
+- Containers outside MP4/WebM/Ogg/WAV/AAC — MKV, AVI, FLV, MPEG-TS
+- **MP3 output** — Android has no MP3 encoder at any version; this is a platform gap
+- GIF and image sequences
+- Input codecs with no platform decoder on the device
+- CRF and 2-pass rate control, for the quality tier
+
+### Quality tiers
+
+The router is surfaced to users as a quality choice rather than hidden:
+
+| Tier | Engine | Rate control | Trade-off |
+|---|---|---|---|
+| **Fast** (default) | Media3 / MediaCodec | bitrate-targeted | ~7–8× realtime, low battery cost |
+| **Best quality** | FFmpeg + x264/x265 | CRF or 2-pass | ~realtime or slower, better quality per byte |
+
+## A note on "GPU acceleration"
+
+Android has **no GPU video codec path**. There are three distinct tiers, and conflating
+them causes a lot of confusion:
+
+1. **Fixed-function video codec silicon** — reached through `MediaCodec`. This is what
+ "hardware accelerated" means for encode and decode. It is not the GPU.
+2. **GPU shader cores** — genuinely used, but only for filters, scaling, and color
+ effects on already-decoded frames, via OpenGL ES. Never for entropy coding.
+3. **CPU** — x264, x265, and software decoders.
+
+FFmpeg's `-hwaccel` is meaningful on Android only as `mediacodec`, and even then it
+targets direct-to-Surface playback rather than file-to-file transcoding. Vulkan Video
+exists in FFmpeg 8.0+ but no shipping Android GPU driver exposes it — no `VK_KHR_video_*`
+extension appears in any Android Vulkan Profile tier.
+
+So this app is hardware accelerated via MediaCodec, and GPU accelerated for effects via
+GL shaders. Both are real; neither is "the GPU decoding video."
+
+## Building
+
+Requires JDK 17+ and the Android SDK with API 37.
+
+```
+./gradlew :app:assembleDebug
+```
+
+The FFmpeg native library is built separately from source; that build is not yet wired
+into this repository.
+
+## Contributing
+
+Contributions are welcome. Note that contributions to the source are under MIT, while
+the distributed binary remains GPL-3.0 for the reasons described in `LICENSES/README.md`.
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index f9a698d..5646484 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,41 +1,92 @@
plugins {
alias(libs.plugins.android.application)
+ // Required even under AGP 9: the Compose compiler plugin is NOT built in.
+ alias(libs.plugins.kotlin.compose)
}
android {
- namespace = "com.example.androidmediaconverter"
+ namespace = "dev.jasonmross.mediaconverter"
+
compileSdk {
version = release(37)
}
defaultConfig {
- applicationId = "com.example.androidmediaconverter"
+ applicationId = "dev.jasonmross.mediaconverter"
minSdk = 33
+ // AGP 9 defaults targetSdk to compileSdk, so always state it explicitly.
targetSdk = 37
versionCode = 1
- versionName = "1.0"
+ versionName = "0.1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+
+ // 64-bit only. The 16 KB page-size rules apply to these ABIs; 32-bit is not
+ // required by Play and would add ~2 more copies of the FFmpeg .so files.
+ ndk {
+ abiFilters += listOf("arm64-v8a", "x86_64")
+ }
+ }
+
+ buildFeatures {
+ compose = true
}
buildTypes {
release {
optimization {
+ // Left off until the JNI keep rules land with FFmpeg (see plan, Phase 6).
enable = false
}
}
}
+
compileOptions {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ packaging {
+ jniLibs {
+ // Uncompressed .so, so the APK zip-aligns them on 16 KB boundaries.
+ useLegacyPackaging = false
+ }
}
}
+// Top-level: android.kotlinOptions {} was removed in AGP 9.
+// jvmTarget is inherited from compileOptions.targetCompatibility.
+kotlin {
+ compilerOptions {}
+}
+
dependencies {
- implementation(libs.androidx.appcompat)
implementation(libs.androidx.core.ktx)
- implementation(libs.material)
+ implementation(libs.androidx.activity.compose)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.lifecycle.runtime.compose)
+ implementation(libs.androidx.lifecycle.viewmodel.compose)
+
+ // Media3 Transformer: the hardware conversion path (MediaCodec decode -> GL surface
+ // -> MediaCodec encode). Apache-2.0, so no licensing exposure.
+ implementation(libs.media3.transformer)
+ implementation(libs.media3.effect)
+ implementation(libs.media3.common)
+ implementation(libs.media3.muxer)
+
+ implementation(platform(libs.compose.bom))
+ implementation(libs.compose.ui)
+ implementation(libs.compose.ui.graphics)
+ implementation(libs.compose.ui.tooling.preview)
+ implementation(libs.compose.material3)
+ implementation(libs.compose.material3.windowsize)
+ debugImplementation(libs.compose.ui.tooling)
+
testImplementation(libs.junit)
- androidTestImplementation(libs.androidx.espresso.core)
+
+ androidTestImplementation(platform(libs.compose.bom))
androidTestImplementation(libs.androidx.junit)
-}
\ No newline at end of file
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(libs.compose.ui.test.junit4)
+ debugImplementation(libs.compose.ui.test.manifest)
+}
diff --git a/app/src/androidTest/java/com/example/androidmediaconverter/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/androidmediaconverter/ExampleInstrumentedTest.kt
deleted file mode 100644
index d83a5b4..0000000
--- a/app/src/androidTest/java/com/example/androidmediaconverter/ExampleInstrumentedTest.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.example.androidmediaconverter
-
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.ext.junit.runners.AndroidJUnit4
-
-import org.junit.Test
-import org.junit.runner.RunWith
-
-import org.junit.Assert.*
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-@RunWith(AndroidJUnit4::class)
-class ExampleInstrumentedTest {
- @Test
- fun useAppContext() {
- // Context of the app under test.
- val appContext = InstrumentationRegistry.getInstrumentation().targetContext
- assertEquals("com.example.androidmediaconverter", appContext.packageName)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0d7c056..2117410 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,5 @@
-
+
+ android:theme="@style/Theme.MediaConverter">
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Color.kt b/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Color.kt
new file mode 100644
index 0000000..8734722
--- /dev/null
+++ b/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Color.kt
@@ -0,0 +1,12 @@
+package dev.jasonmross.mediaconverter.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+// Static fallback palette, used when dynamic color is unavailable or disabled.
+val Purple80 = Color(0xFFD0BCFF)
+val PurpleGrey80 = Color(0xFFCCC2DC)
+val Pink80 = Color(0xFFEFB8C8)
+
+val Purple40 = Color(0xFF6650a4)
+val PurpleGrey40 = Color(0xFF625b71)
+val Pink40 = Color(0xFF7D5260)
diff --git a/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Theme.kt b/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Theme.kt
new file mode 100644
index 0000000..74e4d36
--- /dev/null
+++ b/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Theme.kt
@@ -0,0 +1,51 @@
+package dev.jasonmross.mediaconverter.ui.theme
+
+import android.app.Activity
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.dynamicDarkColorScheme
+import androidx.compose.material3.dynamicLightColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+
+private val DarkColorScheme = darkColorScheme(
+ primary = Purple80,
+ secondary = PurpleGrey80,
+ tertiary = Pink80,
+)
+
+private val LightColorScheme = lightColorScheme(
+ primary = Purple40,
+ secondary = PurpleGrey40,
+ tertiary = Pink40,
+)
+
+/**
+ * Material 3 theme.
+ *
+ * Dynamic color (Material You) needs API 31+; minSdk is 33, so it is available
+ * unconditionally and no version guard is required. It stays switchable so users can
+ * opt back to the brand palette.
+ */
+@Composable
+fun MediaConverterTheme(
+ darkTheme: Boolean = isSystemInDarkTheme(),
+ dynamicColor: Boolean = true,
+ content: @Composable () -> Unit,
+) {
+ val context = LocalContext.current
+ val colorScheme = when {
+ dynamicColor && darkTheme -> dynamicDarkColorScheme(context)
+ dynamicColor -> dynamicLightColorScheme(context)
+ darkTheme -> DarkColorScheme
+ else -> LightColorScheme
+ }
+
+ MaterialTheme(
+ colorScheme = colorScheme,
+ typography = Typography,
+ content = content,
+ )
+}
diff --git a/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Type.kt b/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Type.kt
new file mode 100644
index 0000000..1f69a0f
--- /dev/null
+++ b/app/src/main/java/dev/jasonmross/mediaconverter/ui/theme/Type.kt
@@ -0,0 +1,5 @@
+package dev.jasonmross.mediaconverter.ui.theme
+
+import androidx.compose.material3.Typography
+
+val Typography = Typography()
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index ad32eb5..03efa9d 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -1,16 +1,3 @@
-
-
-
-
\ No newline at end of file
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
deleted file mode 100644
index f8c6127..0000000
--- a/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- #FFBB86FC
- #FF6200EE
- #FF3700B3
- #FF03DAC5
- #FF018786
- #FF000000
- #FFFFFFFF
-
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 44bd81a..12cf0d2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,3 @@
- Android MediaConverter
-
\ No newline at end of file
+ Media Converter
+
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index bc926e4..ab2e9ac 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -1,16 +1,3 @@
-
-
-
-
\ No newline at end of file
+
+
+
diff --git a/app/src/test/java/com/example/androidmediaconverter/ExampleUnitTest.kt b/app/src/test/java/com/example/androidmediaconverter/ExampleUnitTest.kt
deleted file mode 100644
index 4d22957..0000000
--- a/app/src/test/java/com/example/androidmediaconverter/ExampleUnitTest.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.example.androidmediaconverter
-
-import org.junit.Test
-
-import org.junit.Assert.*
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-class ExampleUnitTest {
- @Test
- fun addition_isCorrect() {
- assertEquals(4, 2 + 2)
- }
-}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e76968f..be39fc8 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,20 +1,74 @@
[versions]
+# Build tooling.
+# NOTE: AGP 9 has BUILT-IN Kotlin support. Applying org.jetbrains.kotlin.android
+# FAILS the build. AGP 9.3.1 brings kotlin-gradle-plugin 2.2.10 transitively, so the
+# Compose compiler plugin below must match that version, not the newest Kotlin release.
agp = "9.3.1"
-coreKtx = "1.10.1"
+kotlin = "2.2.10"
+ksp = "2.3.11"
+
+# AndroidX / Compose
+composeBom = "2026.08.00"
+coreKtx = "1.19.0"
+activityCompose = "1.13.0"
+lifecycle = "2.11.0"
+navigation = "2.9.8"
+work = "2.11.2"
+datastore = "1.2.1"
+media3 = "1.11.0"
+room = "2.8.4"
+documentfile = "1.1.0"
+annotation = "1.10.0"
+
+# Test
junit = "4.13.2"
-junitVersion = "1.1.5"
-espressoCore = "3.5.1"
-appcompat = "1.6.1"
-material = "1.10.0"
+androidxJunit = "1.3.0"
+espressoCore = "3.7.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
+androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
+androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycle" }
+androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycle" }
+
+# Compose — versions come from the BOM, so no version.ref here.
+compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
+compose-material3 = { group = "androidx.compose.material3", name = "material3" }
+compose-material3-windowsize = { group = "androidx.compose.material3", name = "material3-window-size-class" }
+compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
+compose-ui = { group = "androidx.compose.ui", name = "ui" }
+compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
+compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
+compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
+compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
+compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
+
+androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" }
+androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "work" }
+androidx-work-testing = { group = "androidx.work", name = "work-testing", version.ref = "work" }
+androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" }
+androidx-documentfile = { group = "androidx.documentfile", name = "documentfile", version.ref = "documentfile" }
+androidx-annotation = { group = "androidx.annotation", name = "annotation", version.ref = "annotation" }
+
+# Media3 — the hardware fast path (Apache-2.0).
+media3-transformer = { group = "androidx.media3", name = "media3-transformer", version.ref = "media3" }
+media3-effect = { group = "androidx.media3", name = "media3-effect", version.ref = "media3" }
+media3-common = { group = "androidx.media3", name = "media3-common", version.ref = "media3" }
+media3-exoplayer = { group = "androidx.media3", name = "media3-exoplayer", version.ref = "media3" }
+media3-muxer = { group = "androidx.media3", name = "media3-muxer", version.ref = "media3" }
+
+# Room — job history. Added in a later phase; KSP plugin stays unapplied until then.
+androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
+androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
+androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
+
junit = { group = "junit", name = "junit", version.ref = "junit" }
-androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxJunit" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
-androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
-material = { group = "com.google.android.material", name = "material", version.ref = "material" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
-
+kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
+ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
+# DO NOT add org.jetbrains.kotlin.android — AGP 9 built-in Kotlin makes it a build failure.
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 84fe593..259543b 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -22,5 +22,5 @@ dependencyResolutionManagement {
}
}
-rootProject.name = "Android(MediaConverter"
+rootProject.name = "AndroidMediaConverter"
include(":app")