group 'io.swipelab.ux' version '1.0-SNAPSHOT' buildscript { ext.kotlin_version = '1.9.22' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:8.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } rootProject.allprojects { repositories { google() mavenCentral() } } apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { namespace 'io.swipelab.ux' compileSdk 34 defaultConfig { minSdk 21 externalNativeBuild { cmake { cppFlags "" } } } externalNativeBuild { cmake { path "src/main/jni/CMakeLists.txt" } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } sourceSets { main { // libffmpegJNI.so is built by the buildFfmpegJni task into // build/jniLibs// on first build (and any time the // vendored ffmpeg_jni.cc / CMakeLists.txt change). Adding // the directory here lets AGP package the .so into the // AAR without committing native binaries to the repo. jniLibs.srcDirs += "$buildDir/jniLibs" } } } // FFmpeg video decoder build — runs as part of the normal Android // build. On first build for a given checkout it clones Media3 + FFmpeg // into build/ffmpeg-work/ and produces libffmpegJNI.so per ABI (~30 min // for the FFmpeg static-lib step the first time, fast after). Gradle // UP-TO-DATE checking skips the task whenever the vendored JNI source // + CMakeLists are unchanged. See android/ffmpeg/README.md. def ffmpegSrcDir = file("$projectDir/ffmpeg") def ffmpegWorkDir = file("$buildDir/ffmpeg-work") def ffmpegOutDir = file("$buildDir/jniLibs") def ndkCmakeBin = "${android.sdkDirectory}/cmake/3.22.1/bin" def supportedAbis = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'] task buildFfmpegJni(type: Exec) { group = 'build' description = 'Clones Media3 + FFmpeg if needed, builds libffmpegJNI.so per Android ABI' inputs.file "$ffmpegSrcDir/ffmpeg_jni.cc" inputs.file "$ffmpegSrcDir/CMakeLists.txt" inputs.file "$ffmpegSrcDir/build_ffmpeg.sh" supportedAbis.each { abi -> outputs.file "$ffmpegOutDir/$abi/libffmpegJNI.so" } workingDir ffmpegSrcDir commandLine 'bash', "$ffmpegSrcDir/build_ffmpeg.sh" environment 'JNI_SRC', ffmpegSrcDir.absolutePath environment 'NDK_PATH', android.ndkDirectory.absolutePath environment 'CMAKE_PATH', ndkCmakeBin environment 'OUTPUT_DIR', ffmpegOutDir.absolutePath environment 'WORK_DIR', ffmpegWorkDir.absolutePath } afterEvaluate { preBuild.dependsOn buildFfmpegJni } dependencies { // CameraX for scanner preview + frame analysis + ux.camera. // 1.4.0+ ships 16-KB-aligned `libimage_processing_util_jni.so` // (Android 15 requirement); 1.3.x failed the elf-alignment check. def cameraxVersion = '1.4.2' implementation "androidx.camera:camera-core:$cameraxVersion" implementation "androidx.camera:camera-camera2:$cameraxVersion" implementation "androidx.camera:camera-lifecycle:$cameraxVersion" implementation "androidx.camera:camera-view:$cameraxVersion" implementation "androidx.camera:camera-video:$cameraxVersion" // ProcessLifecycleOwner so CameraInstance can release the camera // when the host app backgrounds (and re-acquire on foreground). // camera-lifecycle pulls in lifecycle-common but not the process // observer; this adds it. implementation 'androidx.lifecycle:lifecycle-process:2.7.0' // Pure-Kotlin/Java QR decoder. ~470 KB jar, no Play Services dep. implementation 'com.google.zxing:core:3.5.3' // Media3 for ux.video_player. Same version line video_player_android // 2.9.5 pulls in (1.9.x) so the spike fork can coexist during the // Phase 2/3 migration without dragging in two ExoPlayer copies. def media3Version = '1.9.2' implementation "androidx.media3:media3-exoplayer:$media3Version" implementation "androidx.media3:media3-common:$media3Version" }