6.7.0 - Alpha - 新增 mediainfo 模块
This commit is contained in:
@@ -3,7 +3,8 @@
|
|||||||
"v6.7.0": {
|
"v6.7.0": {
|
||||||
"released_date": "2025/06/10",
|
"released_date": "2025/06/10",
|
||||||
"feature": [
|
"feature": [
|
||||||
"zip 模块, 用于文件压缩与解压缩操作 (Ref to [Auto.js Pro](https://g.pro.autojs.org/)) (参阅 项目文档 > [Zip](https://docs.autojs6.com/#/zip))"
|
"zip 模块, 用于文件压缩与解压缩操作 (Ref to [Auto.js Pro](https://g.pro.autojs.org/)) (参阅 项目文档 > [Zip](https://docs.autojs6.com/#/zip))",
|
||||||
|
"mediainfo 模块, 用于查看媒体文件的详细信息 (参阅 项目文档 > [媒体信息](https://docs.autojs6.com/#/mediainfo))"
|
||||||
],
|
],
|
||||||
"fix": [
|
"fix": [
|
||||||
"使用 XML 语法将 JavaScript 表达式作为属性值时, this 对象可能出现指向错误的问题",
|
"使用 XML 语法将 JavaScript 表达式作为属性值时, this 对象可能出现指向错误的问题",
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import org.autojs.autojs.runtime.api.augment.jsox.Jsox
|
|||||||
import org.autojs.autojs.runtime.api.augment.jsox.Mathx
|
import org.autojs.autojs.runtime.api.augment.jsox.Mathx
|
||||||
import org.autojs.autojs.runtime.api.augment.jsox.Numberx
|
import org.autojs.autojs.runtime.api.augment.jsox.Numberx
|
||||||
import org.autojs.autojs.runtime.api.augment.media.Media
|
import org.autojs.autojs.runtime.api.augment.media.Media
|
||||||
|
import org.autojs.autojs.runtime.api.augment.mediainfo.Mediainfo
|
||||||
import org.autojs.autojs.runtime.api.augment.mime.Mime
|
import org.autojs.autojs.runtime.api.augment.mime.Mime
|
||||||
import org.autojs.autojs.runtime.api.augment.nanoid.NanoID
|
import org.autojs.autojs.runtime.api.augment.nanoid.NanoID
|
||||||
import org.autojs.autojs.runtime.api.augment.notice.Notice
|
import org.autojs.autojs.runtime.api.augment.notice.Notice
|
||||||
@@ -109,6 +110,7 @@ import org.autojs.autojs.util.SdkVersionUtils
|
|||||||
import org.autojs.autojs.util.StringUtils
|
import org.autojs.autojs.util.StringUtils
|
||||||
import org.autojs.autojs.util.ViewUtils
|
import org.autojs.autojs.util.ViewUtils
|
||||||
import org.autojs.autojs6.R
|
import org.autojs.autojs6.R
|
||||||
|
import org.mediainfo.android.MediaInfo
|
||||||
import org.mozilla.javascript.BaseFunction
|
import org.mozilla.javascript.BaseFunction
|
||||||
import org.mozilla.javascript.ContextFactory
|
import org.mozilla.javascript.ContextFactory
|
||||||
import org.mozilla.javascript.RhinoException
|
import org.mozilla.javascript.RhinoException
|
||||||
@@ -366,6 +368,10 @@ class ScriptRuntime private constructor(builder: Builder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@ScriptInterface
|
||||||
|
val mediaInfo = MediaInfo()
|
||||||
|
|
||||||
private lateinit var augmentedApp: ScriptableObject
|
private lateinit var augmentedApp: ScriptableObject
|
||||||
|
|
||||||
private lateinit var augmentedAutojs: ScriptableObject
|
private lateinit var augmentedAutojs: ScriptableObject
|
||||||
@@ -769,6 +775,7 @@ class ScriptRuntime private constructor(builder: Builder) {
|
|||||||
NanoID.augment(target, true)
|
NanoID.augment(target, true)
|
||||||
Pinyin.augment(target, true)
|
Pinyin.augment(target, true)
|
||||||
Pinyin4j.augment(target, true)
|
Pinyin4j.augment(target, true)
|
||||||
|
Mediainfo(this).augment(target, true)
|
||||||
|
|
||||||
augmentedApp.defineProp(Autojs::class.java.simpleName.lowercase(), augmentedAutojs)
|
augmentedApp.defineProp(Autojs::class.java.simpleName.lowercase(), augmentedAutojs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.autojs.autojs.runtime.api.augment.mediainfo
|
||||||
|
|
||||||
|
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
|
||||||
|
import org.autojs.autojs.runtime.ScriptRuntime
|
||||||
|
import org.autojs.autojs.runtime.api.augment.Augmentable
|
||||||
|
import org.autojs.autojs.runtime.api.augment.Invokable
|
||||||
|
import org.mozilla.javascript.NativeObject
|
||||||
|
|
||||||
|
@Suppress("unused", "UNUSED_PARAMETER")
|
||||||
|
class Mediainfo(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
||||||
|
|
||||||
|
override val selfAssignmentFunctions = listOf(
|
||||||
|
::read.name,
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun invoke(vararg args: Any?): NativeObject = ensureArgumentsOnlyOne(args) { path ->
|
||||||
|
read(scriptRuntime, arrayOf(path))
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@RhinoRuntimeFunctionInterface
|
||||||
|
fun read(scriptRuntime: ScriptRuntime, args: Array<out Any?>): NativeObject = ensureArgumentsOnlyOne(args) { path ->
|
||||||
|
MediainfoNativeObject(scriptRuntime, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
package org.autojs.autojs.runtime.api.augment.mediainfo
|
||||||
|
|
||||||
|
import org.autojs.autojs.annotation.RhinoFunctionBody
|
||||||
|
import org.autojs.autojs.annotation.RhinoStandardFunctionInterface
|
||||||
|
import org.autojs.autojs.extension.AnyExtensions.isJsNullish
|
||||||
|
import org.autojs.autojs.extension.AnyExtensions.jsBrief
|
||||||
|
import org.autojs.autojs.extension.FlexibleArray.Companion.ensureArgumentsIsEmpty
|
||||||
|
import org.autojs.autojs.extension.ScriptableExtensions.defineProp
|
||||||
|
import org.autojs.autojs.extension.ScriptableExtensions.getProp
|
||||||
|
import org.autojs.autojs.runtime.ScriptRuntime
|
||||||
|
import org.autojs.autojs.runtime.api.StringReadable
|
||||||
|
import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
|
||||||
|
import org.autojs.autojs.util.RhinoUtils
|
||||||
|
import org.autojs.autojs.util.RhinoUtils.NOT_CONSTRUCTABLE
|
||||||
|
import org.autojs.autojs.util.RhinoUtils.coerceString
|
||||||
|
import org.autojs.autojs.util.RhinoUtils.newBaseFunction
|
||||||
|
import org.autojs.autojs.util.RhinoUtils.newNativeObject
|
||||||
|
import org.mediainfo.android.MediaInfo
|
||||||
|
import org.mozilla.javascript.Context
|
||||||
|
import org.mozilla.javascript.Function
|
||||||
|
import org.mozilla.javascript.NativeObject
|
||||||
|
import org.mozilla.javascript.Scriptable
|
||||||
|
|
||||||
|
@Suppress("unused", "UNUSED_PARAMETER")
|
||||||
|
class MediainfoNativeObject(
|
||||||
|
private val scriptRuntime: ScriptRuntime,
|
||||||
|
rawPath: Any?,
|
||||||
|
) : NativeObject(), StringReadable {
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val path: String = when {
|
||||||
|
rawPath.isJsNullish() -> throw WrappedIllegalArgumentException("Argument path ${rawPath.jsBrief()} is invalid for mediainfo")
|
||||||
|
else -> {
|
||||||
|
val pathString = coerceString(rawPath)
|
||||||
|
require(pathString.isNotBlank()) {
|
||||||
|
"Argument \"path\" ${pathString.jsBrief()} for mediainfo cannot be empty"
|
||||||
|
}
|
||||||
|
scriptRuntime.files.nonNullPath(pathString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var informToPrint: String = ""
|
||||||
|
|
||||||
|
init {
|
||||||
|
RhinoUtils.initNativeObjectPrototype(this)
|
||||||
|
defineProperty(StringReadable.KEY, newBaseFunction(StringReadable.KEY, { toStringReadable() }, NOT_CONSTRUCTABLE), READONLY or DONTENUM or PERMANENT)
|
||||||
|
defineProperty("path", path, READONLY or PERMANENT)
|
||||||
|
initProperties()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initProperties() {
|
||||||
|
val inform = scriptRuntime.mediaInfo.getMI(path)
|
||||||
|
defineProperty("inform", inform, READONLY or PERMANENT)
|
||||||
|
MediaInfo.StreamKind.entries.forEach { streamKind ->
|
||||||
|
val funcName = streamKind.name.lowercase()
|
||||||
|
defineProperty(funcName, newBaseFunction(funcName, { argList ->
|
||||||
|
val parameter = argList.takeUnless { it.isEmpty() }?.get(0)?.let { coerceString(it) } ?: ""
|
||||||
|
scriptRuntime.mediaInfo.get(path, streamKind, 0, parameter)
|
||||||
|
}, NOT_CONSTRUCTABLE), READONLY or PERMANENT)
|
||||||
|
}
|
||||||
|
applyInform(inform)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun applyInform(inform: String) {
|
||||||
|
var currentObj: Scriptable? = null
|
||||||
|
var currentSectionName: String?
|
||||||
|
|
||||||
|
inform.lineSequence().forEach { raw ->
|
||||||
|
val line = raw.trimEnd()
|
||||||
|
if (line.isBlank()) return@forEach
|
||||||
|
when {
|
||||||
|
!line.contains(':') -> {
|
||||||
|
currentSectionName = line.lowercase()
|
||||||
|
currentObj = this.getProp(currentSectionName) as? Scriptable
|
||||||
|
?: newNativeObject().also { defineProperty(currentSectionName, it, READONLY or PERMANENT) }
|
||||||
|
if (informToPrint.isNotBlank()) informToPrint += " },\n"
|
||||||
|
informToPrint += " $currentSectionName: {\n"
|
||||||
|
}
|
||||||
|
currentObj != null -> {
|
||||||
|
val idx = line.indexOf(':')
|
||||||
|
val key = line.substring(0, idx).trim().toCamel()
|
||||||
|
val value = line.substring(idx + 1).trim()
|
||||||
|
currentObj.defineProp(key, value, READONLY or PERMANENT)
|
||||||
|
informToPrint += " $key: \"$value\",\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (informToPrint.isNotBlank()) informToPrint += " },"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.toCamel(): String = this
|
||||||
|
.replace(Regex("\\((s|es|ies)\\)"), "$1")
|
||||||
|
.split(Regex("[^A-Za-z0-9]+"))
|
||||||
|
.filter { it.isNotEmpty() }
|
||||||
|
.joinToString("") { part ->
|
||||||
|
part.lowercase().replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
|
||||||
|
}.replaceFirstChar { it.lowercase() }
|
||||||
|
|
||||||
|
override fun toStringReadable() = toStringRhino(this)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@RhinoStandardFunctionInterface
|
||||||
|
fun toString(cx: Context, thisObj: Scriptable, args: Array<Any?>, funObj: Function): String = ensureArgumentsIsEmpty(args) {
|
||||||
|
toStringRhino(thisObj as MediainfoNativeObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@RhinoFunctionBody
|
||||||
|
fun toStringRhino(thisObj: MediainfoNativeObject): String {
|
||||||
|
val objectName = MediainfoNativeObject::class.java.simpleName
|
||||||
|
val inform = thisObj.informToPrint
|
||||||
|
return when {
|
||||||
|
inform.isBlank() -> "$objectName {}"
|
||||||
|
else -> "$objectName {\n$inform\n}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -32,15 +32,6 @@ import java.util.function.Supplier
|
|||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.reflect.KMutableProperty1
|
import kotlin.reflect.KMutableProperty1
|
||||||
|
|
||||||
// @Caution by SuperMonster003 on May 6, 2023.
|
|
||||||
// ! On device running with Android 7.x, importing NotificationManagerCompat will cause an exception:
|
|
||||||
// ! java.lang.ClassNotFoundException: Didn't find class "android.app.NotificationChannel" on path: DexPathList ...
|
|
||||||
// ! zh-CN:
|
|
||||||
// ! 在安卓 7.x 设备上, 导入 NotificationManagerCompat 类将导致异常:
|
|
||||||
// ! java.lang.ClassNotFoundException: 无法找到 "android.app.NotificationChannel" 类在此路径: DexPathList ...
|
|
||||||
// !
|
|
||||||
// # import androidx.core.app.NotificationManagerCompat
|
|
||||||
|
|
||||||
@Suppress("unused", "UNUSED_PARAMETER")
|
@Suppress("unused", "UNUSED_PARAMETER")
|
||||||
class Notice(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
class Notice(private val scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), Invokable {
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Tue Jun 10 18:30:41 CST 2025
|
#Wed Jun 11 18:10:41 CST 2025
|
||||||
BUILD_TIME=1749551441206
|
BUILD_TIME=1749636641459
|
||||||
COMPILE_SDK_VERSION=35
|
COMPILE_SDK_VERSION=35
|
||||||
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
IMAGE_QUANT_CMAKE_VERSION=3.22.1
|
||||||
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
IMAGE_QUANT_NDK_VERSION=26.1.10909125
|
||||||
@@ -19,6 +19,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13
|
|||||||
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
|
||||||
TARGET_SDK_VERSION=35
|
TARGET_SDK_VERSION=35
|
||||||
TARGET_SDK_VERSION_INRT=29
|
TARGET_SDK_VERSION_INRT=29
|
||||||
VERSION_BUILD=3289
|
VERSION_BUILD=3292
|
||||||
VERSION_NAME=6.7.0 Alpha
|
VERSION_NAME=6.7.0 Alpha
|
||||||
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
VSCODE_EXT_REQUIRED_VERSION=1.0.8
|
||||||
|
|||||||
Reference in New Issue
Block a user