-
Notifications
You must be signed in to change notification settings - Fork 1
fix: create plugins using media3 lib #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| plugins { | ||
| alias(libs.plugins.android.library) | ||
| id 'maven-publish' | ||
| } | ||
|
|
||
| android { | ||
| namespace 'com.tejpratapsingh.motionlib.media3' | ||
| compileSdk 36 | ||
|
|
||
| defaultConfig { | ||
| minSdk 28 | ||
|
|
||
| testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
| consumerProguardFiles "consumer-rules.pro" | ||
| } | ||
|
|
||
| buildTypes { | ||
| release { | ||
| minifyEnabled false | ||
| proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
| } | ||
| } | ||
| compileOptions { | ||
| sourceCompatibility JavaVersion.VERSION_11 | ||
| targetCompatibility JavaVersion.VERSION_11 | ||
| } | ||
| publishing { | ||
| singleVariant("release") | ||
| } | ||
| } | ||
|
|
||
| afterEvaluate { | ||
| publishing { | ||
| publications { | ||
| release(MavenPublication) { | ||
| from components.release | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation project(path: ':modules:core') | ||
| implementation project(path: ':modules:motionlib') | ||
|
|
||
| implementation libs.androidx.media3.common | ||
| implementation libs.androidx.media3.exoplayer | ||
| // Assuming we add media3-effect to libs.versions.toml if missing, | ||
| // but based on research it should be available or we can use the same version as common | ||
| implementation "androidx.media3:media3-effect:${libs.versions.media3Version.get()}" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify media3-effect artifact availability at version 1.10.0
curl -s "https://repo1.maven.org/maven2/androidx/media3/media3-effect/1.10.0/" | grep -q "media3-effect-1.10.0.aar" && echo "✓ media3-effect:1.10.0 exists" || echo "✗ media3-effect:1.10.0 not found"
# Check if media3-effect is in the version catalog
rg -n "media3.effect|media3-effect" gradle/libs.versions.tomlRepository: tejpratap46/AndroidVideoMotion Length of output: 107 🏁 Script executed: #!/bin/bash
# Find available versions of media3-effect in Maven Central
echo "=== Checking available media3-effect versions ==="
curl -s "https://repo1.maven.org/maven2/androidx/media3/media3-effect/" | grep -oP '">[\d.]+/<' | tr -d '">' | sort -V | tail -10
# Check the gradle/libs.versions.toml file
echo -e "\n=== Checking gradle/libs.versions.toml for media3 references ==="
rg -A 5 "media3" gradle/libs.versions.toml || echo "No media3 references found"
# Read the build.gradle file around line 50
echo -e "\n=== Checking build.gradle around line 50 ==="
sed -n '40,60p' modules/media3-motion-ext/build.gradleRepository: tejpratap46/AndroidVideoMotion Length of output: 1570 🏁 Script executed: #!/bin/bash
# Better verification of media3-effect artifact existence using Maven metadata
echo "=== Checking media3-effect in Maven Central ==="
curl -s "https://repo1.maven.org/maven2/androidx/media3/media3-effect/maven-metadata.xml" | grep -oP '<version>\K[^<]+' | tail -5
# Also check specifically for 1.10.0
echo -e "\n=== Checking for media3-effect 1.10.0 directly ==="
curl -s -I "https://repo1.maven.org/maven2/androidx/media3/media3-effect/1.10.0/media3-effect-1.10.0.aar" | head -1
# Check what other media3 artifacts are available at that version
echo -e "\n=== Other media3 artifacts at version 1.10.0 ==="
curl -s "https://repo1.maven.org/maven2/androidx/media3/" | grep -oP '>media3-[^/<]+' | sort -u | head -10Repository: tejpratap46/AndroidVideoMotion Length of output: 241 🏁 Script executed: #!/bin/bash
# Verify the artifact truly exists with Python for more reliable checking
python3 << 'PY'
import urllib.request
import urllib.error
url = "https://repo1.maven.org/maven2/androidx/media3/media3-effect/1.10.0/media3-effect-1.10.0.aar"
try:
response = urllib.request.urlopen(url, timeout=5)
print(f"✓ media3-effect:1.10.0 exists (HTTP {response.status})")
except urllib.error.HTTPError as e:
print(f"✗ media3-effect:1.10.0 not found (HTTP {e.code})")
except Exception as e:
print(f"? Could not verify: {e}")
PY
# Also verify other media3 artifacts at same version to confirm pattern
echo -e "\n=== Verifying media3-common at 1.10.0 ==="
python3 << 'PY'
import urllib.request
url = "https://repo1.maven.org/maven2/androidx/media3/media3-common/1.10.0/media3-common-1.10.0.aar"
try:
response = urllib.request.urlopen(url, timeout=5)
print(f"✓ media3-common:1.10.0 exists")
except:
print(f"✗ media3-common:1.10.0 not found")
PYRepository: tejpratap46/AndroidVideoMotion Length of output: 304 Add Line 50 uses string interpolation to construct the dependency, while lines 46-47 reference the version catalog ( 🤖 Prompt for AI Agents |
||
|
|
||
| testImplementation libs.junit | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,64 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.tejpratapsingh.motionlib.media3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import android.graphics.ColorMatrix | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.annotation.OptIn | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.media3.common.util.UnstableApi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.media3.effect.RgbMatrix | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @OptIn(UnstableApi::class) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| object Media3Utils { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Converts a Media3 4x4 RGB matrix to an Android 5x4 ColorMatrix. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Media3 matrix is assumed to be a 16-float array representing a 4x4 matrix. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Android ColorMatrix is a 20-float array (4 rows, 5 columns). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fun toColorMatrix(media3Matrix: FloatArray): ColorMatrix { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (media3Matrix.size != 16) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ColorMatrix() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Media3 matrix (column-major standard for GL): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // [ m0 m4 m8 m12 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // [ m1 m5 m9 m13 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // [ m2 m6 m10 m14 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // [ m3 m7 m11 m15 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Android ColorMatrix (row-major): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // [ a b c d e ] -> R' = aR + bG + cB + dA + e | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // [ f g h i j ] -> G' = fR + gG + hB + iA + j | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // [ k l m n o ] -> B' = kR + lG + mB + nA + o | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // [ p q r s t ] -> A' = pR + qG + rB + sA + t | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val colorMatrixArray = FloatArray(20) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Row 0 (Red) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[0] = media3Matrix[0] // m0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[1] = media3Matrix[4] // m4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[2] = media3Matrix[8] // m8 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[3] = 0f // d (Alpha contribution to Red) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[4] = media3Matrix[12] * 255f // e (Offset, normalized to 0-255) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Row 1 (Green) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[5] = media3Matrix[1] // m1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[6] = media3Matrix[5] // m5 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[7] = media3Matrix[9] // m9 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[8] = 0f // i | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[9] = media3Matrix[13] * 255f // j | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Row 2 (Blue) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[10] = media3Matrix[2] // m2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[11] = media3Matrix[6] // m6 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[12] = media3Matrix[10]// m10 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[13] = 0f // n | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[14] = media3Matrix[14] * 255f // o | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+39
to
+53
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛑 Logic Error: Missing bounds check before array access will cause ArrayIndexOutOfBoundsException. Add validation to prevent crashes when accessing media3Matrix indices 12, 13, and 14.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Row 3 (Alpha) - Identity | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[15] = 0f | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[16] = 0f | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[17] = 0f | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[18] = 1f | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorMatrixArray[19] = 0f | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ColorMatrix(colorMatrixArray) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,60 @@ | ||||||||||||||||||||||||||
| package com.tejpratapsingh.motionlib.media3.effects | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| import android.graphics.ColorMatrixColorFilter | ||||||||||||||||||||||||||
| import android.graphics.RenderEffect | ||||||||||||||||||||||||||
| import android.os.Build | ||||||||||||||||||||||||||
| import android.view.View | ||||||||||||||||||||||||||
| import androidx.annotation.OptIn | ||||||||||||||||||||||||||
| import androidx.media3.common.util.UnstableApi | ||||||||||||||||||||||||||
| import androidx.media3.effect.Brightness | ||||||||||||||||||||||||||
| import com.tejpratapsingh.motionlib.core.MotionEffect | ||||||||||||||||||||||||||
| import com.tejpratapsingh.motionlib.core.MotionView | ||||||||||||||||||||||||||
| import com.tejpratapsingh.motionlib.core.animation.Easings | ||||||||||||||||||||||||||
| import com.tejpratapsingh.motionlib.core.animation.Interpolators | ||||||||||||||||||||||||||
| import com.tejpratapsingh.motionlib.core.animation.MotionInterpolator | ||||||||||||||||||||||||||
| import com.tejpratapsingh.motionlib.media3.Media3Utils | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * A [MotionEffect] that adjusts brightness using [androidx.media3.effect.Brightness]. | ||||||||||||||||||||||||||
| * Animates brightness from [fromBrightness] to [toBrightness]. | ||||||||||||||||||||||||||
| * Brightness ranges from -1 (black) to 1 (white). 0 is no change. | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| @OptIn(UnstableApi::class) | ||||||||||||||||||||||||||
| class BrightnessEffect( | ||||||||||||||||||||||||||
| override val startFrame: Int, | ||||||||||||||||||||||||||
| override val endFrame: Int, | ||||||||||||||||||||||||||
| val fromBrightness: Float = 0.0f, | ||||||||||||||||||||||||||
| val toBrightness: Float = 1.0f, | ||||||||||||||||||||||||||
| ) : MotionEffect { | ||||||||||||||||||||||||||
| override lateinit var motionView: MotionView | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| override fun forFrame(frame: Int): MotionView { | ||||||||||||||||||||||||||
| if (motionView !is View) return motionView | ||||||||||||||||||||||||||
| val view = motionView as View | ||||||||||||||||||||||||||
|
Comment on lines
+31
to
+33
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛑 Crash Risk: Missing lateinit initialization check causes UninitializedPropertyAccessException. Add check before accessing motionView property to prevent runtime crashes.
Suggested change
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return motionView | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (frame !in startFrame..endFrame) { | ||||||||||||||||||||||||||
| if (frame > endFrame) { | ||||||||||||||||||||||||||
| view.setRenderEffect(null) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| return motionView | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+37
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When scrubbing backwards or jumping to a frame before
Suggested change
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| val brightnessValue = MotionInterpolator.interpolateForRange( | ||||||||||||||||||||||||||
| interpolator = Interpolators(Easings.LINEAR), | ||||||||||||||||||||||||||
| currentFrame = frame, | ||||||||||||||||||||||||||
| frameRange = Pair(startFrame, endFrame), | ||||||||||||||||||||||||||
| valueRange = Pair(fromBrightness, toBrightness), | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| val brightnessEffect = Brightness(brightnessValue) | ||||||||||||||||||||||||||
| val matrix = brightnessEffect.getMatrix(0L, false) | ||||||||||||||||||||||||||
| val colorMatrix = Media3Utils.toColorMatrix(matrix) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| val colorFilter = ColorMatrixColorFilter(colorMatrix) | ||||||||||||||||||||||||||
| view.setRenderEffect(RenderEffect.createColorFilterEffect(colorFilter)) | ||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All effect classes overwrite each other via All five effect implementations call
📍 Affects 3 files
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return motionView | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| package com.tejpratapsingh.motionlib.media3.effects | ||
|
|
||
| import android.graphics.ColorMatrixColorFilter | ||
| import android.graphics.RenderEffect | ||
| import android.os.Build | ||
| import android.view.View | ||
| import androidx.annotation.OptIn | ||
| import androidx.media3.common.util.UnstableApi | ||
| import androidx.media3.effect.Contrast | ||
| import com.tejpratapsingh.motionlib.core.MotionEffect | ||
| import com.tejpratapsingh.motionlib.core.MotionView | ||
| import com.tejpratapsingh.motionlib.core.animation.Easings | ||
| import com.tejpratapsingh.motionlib.core.animation.Interpolators | ||
| import com.tejpratapsingh.motionlib.core.animation.MotionInterpolator | ||
| import com.tejpratapsingh.motionlib.media3.Media3Utils | ||
|
|
||
| /** | ||
| * A [MotionEffect] that adjusts contrast using [androidx.media3.effect.Contrast]. | ||
| * Animates contrast from [fromContrast] to [toContrast]. | ||
| * Contrast 1.0 is no change. 0.0 is uniform gray. > 1.0 increases contrast. | ||
| */ | ||
| @OptIn(UnstableApi::class) | ||
| class ContrastEffect( | ||
| override val startFrame: Int, | ||
| override val endFrame: Int, | ||
| val fromContrast: Float = 1.0f, | ||
| val toContrast: Float = 2.0f, | ||
| ) : MotionEffect { | ||
| override lateinit var motionView: MotionView | ||
|
|
||
| override fun forFrame(frame: Int): MotionView { | ||
| if (motionView !is View) return motionView | ||
| val view = motionView as View | ||
|
|
||
| if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return motionView | ||
|
|
||
| if (frame !in startFrame..endFrame) { | ||
| if (frame > endFrame) { | ||
| view.setRenderEffect(null) | ||
| } | ||
| return motionView | ||
|
Comment on lines
+36
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When scrubbing backwards or jumping to a frame before if (frame !in startFrame..endFrame) {
if (view.renderEffect != null) {
view.setRenderEffect(null)
}
return motionView
} |
||
| } | ||
|
|
||
| val contrastValue = MotionInterpolator.interpolateForRange( | ||
| interpolator = Interpolators(Easings.LINEAR), | ||
| currentFrame = frame, | ||
| frameRange = Pair(startFrame, endFrame), | ||
| valueRange = Pair(fromContrast, toContrast), | ||
| ) | ||
|
|
||
| val contrastEffect = Contrast(contrastValue) | ||
| val matrix = contrastEffect.getMatrix(0L, false) | ||
| val colorMatrix = Media3Utils.toColorMatrix(matrix) | ||
|
|
||
| val colorFilter = ColorMatrixColorFilter(colorMatrix) | ||
| view.setRenderEffect(RenderEffect.createColorFilterEffect(colorFilter)) | ||
|
|
||
| return motionView | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package com.tejpratapsingh.motionlib.media3.effects | ||
|
|
||
| import android.graphics.ColorMatrixColorFilter | ||
| import android.graphics.RenderEffect | ||
| import android.os.Build | ||
| import android.view.View | ||
| import androidx.annotation.OptIn | ||
| import androidx.media3.common.util.UnstableApi | ||
| import androidx.media3.effect.RgbFilter | ||
| import com.tejpratapsingh.motionlib.core.MotionEffect | ||
| import com.tejpratapsingh.motionlib.core.MotionView | ||
| import com.tejpratapsingh.motionlib.media3.Media3Utils | ||
|
|
||
| /** | ||
| * A [MotionEffect] that applies a grayscale filter using [androidx.media3.effect.RgbFilter]. | ||
| */ | ||
| @OptIn(UnstableApi::class) | ||
| class GrayscaleEffect( | ||
| override val startFrame: Int, | ||
| override val endFrame: Int, | ||
| ) : MotionEffect { | ||
| override lateinit var motionView: MotionView | ||
|
|
||
| override fun forFrame(frame: Int): MotionView { | ||
| if (motionView !is View) return motionView | ||
| val view = motionView as View | ||
|
|
||
| if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return motionView | ||
|
|
||
| if (frame !in startFrame..endFrame) { | ||
| if (frame > endFrame) { | ||
| view.setRenderEffect(null) | ||
| } | ||
| return motionView | ||
| } | ||
|
|
||
| val grayscaleFilter = RgbFilter.createGrayscaleFilter() | ||
| val matrix = grayscaleFilter.getMatrix(0L, false) | ||
| val colorMatrix = Media3Utils.toColorMatrix(matrix) | ||
|
|
||
| val colorFilter = ColorMatrixColorFilter(colorMatrix) | ||
| view.setRenderEffect(RenderEffect.createColorFilterEffect(colorFilter)) | ||
|
|
||
| return motionView | ||
| } | ||
| } | ||
|
Comment on lines
+18
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since class GrayscaleEffect(
override val startFrame: Int,
override val endFrame: Int,
) : MotionEffect {
override lateinit var motionView: MotionView
private var cachedRenderEffect: RenderEffect? = null
override fun forFrame(frame: Int): MotionView {
if (motionView !is View) return motionView
val view = motionView as View
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return motionView
if (frame !in startFrame..endFrame) {
if (view.renderEffect != null) {
view.setRenderEffect(null)
}
return motionView
}
if (cachedRenderEffect == null) {
val grayscaleFilter = RgbFilter.createGrayscaleFilter()
val matrix = grayscaleFilter.getMatrix(0L, false)
val colorMatrix = Media3Utils.toColorMatrix(matrix)
val colorFilter = ColorMatrixColorFilter(colorMatrix)
cachedRenderEffect = RenderEffect.createColorFilterEffect(colorFilter)
}
view.setRenderEffect(cachedRenderEffect)
return motionView
}
} |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package com.tejpratapsingh.motionlib.media3.effects | ||
|
|
||
| import android.graphics.ColorMatrixColorFilter | ||
| import android.graphics.RenderEffect | ||
| import android.os.Build | ||
| import android.view.View | ||
| import androidx.annotation.OptIn | ||
| import androidx.media3.common.util.UnstableApi | ||
| import androidx.media3.effect.RgbFilter | ||
| import com.tejpratapsingh.motionlib.core.MotionEffect | ||
| import com.tejpratapsingh.motionlib.core.MotionView | ||
| import com.tejpratapsingh.motionlib.media3.Media3Utils | ||
|
|
||
| /** | ||
| * A [MotionEffect] that applies an inverted color filter using [androidx.media3.effect.RgbFilter]. | ||
| */ | ||
| @OptIn(UnstableApi::class) | ||
| class InvertEffect( | ||
| override val startFrame: Int, | ||
| override val endFrame: Int, | ||
| ) : MotionEffect { | ||
| override lateinit var motionView: MotionView | ||
|
|
||
| override fun forFrame(frame: Int): MotionView { | ||
| if (motionView !is View) return motionView | ||
| val view = motionView as View | ||
|
|
||
| if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return motionView | ||
|
|
||
| if (frame !in startFrame..endFrame) { | ||
| if (frame > endFrame) { | ||
| view.setRenderEffect(null) | ||
| } | ||
| return motionView | ||
| } | ||
|
|
||
| val invertedFilter = RgbFilter.createInvertedFilter() | ||
| val matrix = invertedFilter.getMatrix(0L, false) | ||
| val colorMatrix = Media3Utils.toColorMatrix(matrix) | ||
|
|
||
| val colorFilter = ColorMatrixColorFilter(colorMatrix) | ||
| view.setRenderEffect(RenderEffect.createColorFilterEffect(colorFilter)) | ||
|
|
||
| return motionView | ||
| } | ||
| } | ||
|
Comment on lines
+18
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since class InvertEffect(
override val startFrame: Int,
override val endFrame: Int,
) : MotionEffect {
override lateinit var motionView: MotionView
private var cachedRenderEffect: RenderEffect? = null
override fun forFrame(frame: Int): MotionView {
if (motionView !is View) return motionView
val view = motionView as View
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return motionView
if (frame !in startFrame..endFrame) {
if (view.renderEffect != null) {
view.setRenderEffect(null)
}
return motionView
}
if (cachedRenderEffect == null) {
val invertedFilter = RgbFilter.createInvertedFilter()
val matrix = invertedFilter.getMatrix(0L, false)
val colorMatrix = Media3Utils.toColorMatrix(matrix)
val colorFilter = ColorMatrixColorFilter(colorMatrix)
cachedRenderEffect = RenderEffect.createColorFilterEffect(colorFilter)
}
view.setRenderEffect(cachedRenderEffect)
return motionView
}
} |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using string interpolation with
libs.versions.media3Version.get(), it is more idiomatic and cleaner to define themedia3-effectdependency in yourlibs.versions.tomlversion catalog and reference it directly as a type-safe accessor.