feat: Move over the media API
This commit is contained in:
parent
f7218f57cb
commit
5dcfc7239a
@ -17,6 +17,8 @@ import org.moxxy.moxxy_native.contacts.ContactsImplementation
|
||||
import org.moxxy.moxxy_native.contacts.MoxxyContactsApi
|
||||
import org.moxxy.moxxy_native.cryptography.CryptographyImplementation
|
||||
import org.moxxy.moxxy_native.cryptography.MoxxyCryptographyApi
|
||||
import org.moxxy.moxxy_native.media.MediaImplementation
|
||||
import org.moxxy.moxxy_native.media.MoxxyMediaApi
|
||||
import org.moxxy.moxxy_native.notifications.MessagingNotification
|
||||
import org.moxxy.moxxy_native.notifications.MoxxyNotificationsApi
|
||||
import org.moxxy.moxxy_native.notifications.NotificationChannel
|
||||
@ -65,6 +67,7 @@ class MoxxyNativePlugin : FlutterPlugin, ActivityAware, MoxxyPickerApi, MoxxyNot
|
||||
private val cryptographyImplementation = CryptographyImplementation()
|
||||
private lateinit var contactsImplementation: ContactsImplementation
|
||||
private lateinit var platformImplementation: PlatformImplementation
|
||||
private val mediaImplementation = MediaImplementation()
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
context = flutterPluginBinding.applicationContext
|
||||
@ -77,6 +80,7 @@ class MoxxyNativePlugin : FlutterPlugin, ActivityAware, MoxxyPickerApi, MoxxyNot
|
||||
MoxxyCryptographyApi.setUp(flutterPluginBinding.binaryMessenger, cryptographyImplementation)
|
||||
MoxxyContactsApi.setUp(flutterPluginBinding.binaryMessenger, contactsImplementation)
|
||||
MoxxyPlatformApi.setUp(flutterPluginBinding.binaryMessenger, platformImplementation)
|
||||
MoxxyMediaApi.setUp(flutterPluginBinding.binaryMessenger, mediaImplementation)
|
||||
|
||||
// Register the picker handler
|
||||
pickerListener = PickerResultListener(context!!)
|
||||
|
@ -8,8 +8,6 @@ import io.flutter.plugin.common.BasicMessageChannel
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MessageCodec
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
private fun wrapResult(result: Any?): List<Any?> {
|
||||
return listOf(result)
|
||||
@ -20,13 +18,13 @@ private fun wrapError(exception: Throwable): List<Any?> {
|
||||
return listOf(
|
||||
exception.code,
|
||||
exception.message,
|
||||
exception.details
|
||||
exception.details,
|
||||
)
|
||||
} else {
|
||||
return listOf(
|
||||
exception.javaClass.simpleName,
|
||||
exception.toString(),
|
||||
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
|
||||
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -40,14 +38,15 @@ private fun wrapError(exception: Throwable): List<Any?> {
|
||||
class FlutterError(
|
||||
val code: String,
|
||||
override val message: String? = null,
|
||||
val details: Any? = null
|
||||
val details: Any? = null,
|
||||
) : Throwable()
|
||||
|
||||
/** The type of icon to use when no avatar path is provided. */
|
||||
enum class FallbackIconType(val raw: Int) {
|
||||
NONE(0),
|
||||
PERSON(1),
|
||||
NOTES(2);
|
||||
NOTES(2),
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun ofRaw(raw: Int): FallbackIconType? {
|
||||
@ -55,6 +54,7 @@ enum class FallbackIconType(val raw: Int) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface MoxxyContactsApi {
|
||||
fun recordSentMessage(name: String, jid: String, avatarPath: String?, fallbackIcon: FallbackIconType)
|
||||
@ -64,6 +64,7 @@ interface MoxxyContactsApi {
|
||||
val codec: MessageCodec<Any?> by lazy {
|
||||
StandardMessageCodec()
|
||||
}
|
||||
|
||||
/** Sets up an instance of `MoxxyContactsApi` to handle messages through the `binaryMessenger`. */
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: MoxxyContactsApi?) {
|
||||
|
@ -17,7 +17,7 @@ class ContactsImplementation(private val context: Context) : MoxxyContactsApi {
|
||||
name: String,
|
||||
jid: String,
|
||||
avatarPath: String?,
|
||||
fallbackIcon: FallbackIconType
|
||||
fallbackIcon: FallbackIconType,
|
||||
) {
|
||||
val pkgName = context.packageName
|
||||
val intent = Intent(context, Class.forName("$pkgName.MainActivity")).apply {
|
||||
|
@ -0,0 +1,79 @@
|
||||
// Autogenerated from Pigeon (v11.0.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
package org.moxxy.moxxy_native.media
|
||||
|
||||
import android.util.Log
|
||||
import io.flutter.plugin.common.BasicMessageChannel
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MessageCodec
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
|
||||
private fun wrapResult(result: Any?): List<Any?> {
|
||||
return listOf(result)
|
||||
}
|
||||
|
||||
private fun wrapError(exception: Throwable): List<Any?> {
|
||||
if (exception is FlutterError) {
|
||||
return listOf(
|
||||
exception.code,
|
||||
exception.message,
|
||||
exception.details,
|
||||
)
|
||||
} else {
|
||||
return listOf(
|
||||
exception.javaClass.simpleName,
|
||||
exception.toString(),
|
||||
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for passing custom error details to Flutter via a thrown PlatformException.
|
||||
* @property code The error code.
|
||||
* @property message The error message.
|
||||
* @property details The error details. Must be a datatype supported by the api codec.
|
||||
*/
|
||||
class FlutterError(
|
||||
val code: String,
|
||||
override val message: String? = null,
|
||||
val details: Any? = null,
|
||||
) : Throwable()
|
||||
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface MoxxyMediaApi {
|
||||
fun generateVideoThumbnail(src: String, dest: String, maxWidth: Long): Boolean
|
||||
|
||||
companion object {
|
||||
/** The codec used by MoxxyMediaApi. */
|
||||
val codec: MessageCodec<Any?> by lazy {
|
||||
StandardMessageCodec()
|
||||
}
|
||||
|
||||
/** Sets up an instance of `MoxxyMediaApi` to handle messages through the `binaryMessenger`. */
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: MoxxyMediaApi?) {
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.moxxy_native.MoxxyMediaApi.generateVideoThumbnail", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val srcArg = args[0] as String
|
||||
val destArg = args[1] as String
|
||||
val maxWidthArg = args[2].let { if (it is Int) it.toLong() else it as Long }
|
||||
var wrapped: List<Any?>
|
||||
try {
|
||||
wrapped = listOf<Any?>(api.generateVideoThumbnail(srcArg, destArg, maxWidthArg))
|
||||
} catch (exception: Throwable) {
|
||||
wrapped = wrapError(exception)
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package org.moxxy.moxxy_native.media
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.media.MediaMetadataRetriever
|
||||
import android.util.Log
|
||||
import org.moxxy.moxxy_native.TAG
|
||||
import java.io.FileOutputStream
|
||||
|
||||
class MediaImplementation : MoxxyMediaApi {
|
||||
override fun generateVideoThumbnail(src: String, dest: String, maxWidth: Long): Boolean {
|
||||
try {
|
||||
// Get a frame as a thumbnail
|
||||
val mmr = MediaMetadataRetriever().apply {
|
||||
setDataSource(src)
|
||||
}
|
||||
val unscaledThumbnail = mmr.getFrameAtTime(0) ?: return false
|
||||
|
||||
// Scale down the thumbnail while keeping the aspect ratio
|
||||
val scalingFactor = maxWidth.toDouble() / unscaledThumbnail.width
|
||||
Log.d(TAG, "Scaling to $maxWidth from ${unscaledThumbnail.width} with scalingFactor $scalingFactor")
|
||||
val thumbnail = Bitmap.createScaledBitmap(
|
||||
unscaledThumbnail,
|
||||
(unscaledThumbnail.width * scalingFactor).toInt(),
|
||||
(unscaledThumbnail.height * scalingFactor).toInt(),
|
||||
false,
|
||||
)
|
||||
|
||||
// Write it to the destination file
|
||||
val fileOutputStream = FileOutputStream(dest)
|
||||
thumbnail.compress(Bitmap.CompressFormat.JPEG, 75, fileOutputStream)
|
||||
|
||||
// Clean up
|
||||
fileOutputStream.apply {
|
||||
flush()
|
||||
close()
|
||||
}
|
||||
|
||||
// Success
|
||||
return true
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Failed to create thumbnail for $src: ${ex.message}")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
@ -8,8 +8,6 @@ import io.flutter.plugin.common.BasicMessageChannel
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MessageCodec
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
private fun wrapResult(result: Any?): List<Any?> {
|
||||
return listOf(result)
|
||||
@ -20,13 +18,13 @@ private fun wrapError(exception: Throwable): List<Any?> {
|
||||
return listOf(
|
||||
exception.code,
|
||||
exception.message,
|
||||
exception.details
|
||||
exception.details,
|
||||
)
|
||||
} else {
|
||||
return listOf(
|
||||
exception.javaClass.simpleName,
|
||||
exception.toString(),
|
||||
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
|
||||
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -40,8 +38,9 @@ private fun wrapError(exception: Throwable): List<Any?> {
|
||||
class FlutterError(
|
||||
val code: String,
|
||||
override val message: String? = null,
|
||||
val details: Any? = null
|
||||
val details: Any? = null,
|
||||
) : Throwable()
|
||||
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface MoxxyPlatformApi {
|
||||
fun getPersistentDataPath(): String
|
||||
@ -54,6 +53,7 @@ interface MoxxyPlatformApi {
|
||||
val codec: MessageCodec<Any?> by lazy {
|
||||
StandardMessageCodec()
|
||||
}
|
||||
|
||||
/** Sets up an instance of `MoxxyPlatformApi` to handle messages through the `binaryMessenger`. */
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: MoxxyPlatformApi?) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
export 'pigeon/contacts.g.dart';
|
||||
export 'pigeon/cryptography.g.dart';
|
||||
export 'pigeon/media.g.dart';
|
||||
export 'pigeon/notifications.g.dart';
|
||||
export 'pigeon/picker.g.dart';
|
||||
export 'pigeon/platform.g.dart';
|
||||
|
47
lib/pigeon/media.g.dart
Normal file
47
lib/pigeon/media.g.dart
Normal file
@ -0,0 +1,47 @@
|
||||
// Autogenerated from Pigeon (v11.0.1), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
||||
|
||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class MoxxyMediaApi {
|
||||
/// Constructor for [MoxxyMediaApi]. The [binaryMessenger] named argument is
|
||||
/// available for dependency injection. If it is left null, the default
|
||||
/// BinaryMessenger will be used which routes to the host platform.
|
||||
MoxxyMediaApi({BinaryMessenger? binaryMessenger})
|
||||
: _binaryMessenger = binaryMessenger;
|
||||
final BinaryMessenger? _binaryMessenger;
|
||||
|
||||
static const MessageCodec<Object?> codec = StandardMessageCodec();
|
||||
|
||||
Future<bool> generateVideoThumbnail(String arg_src, String arg_dest, int arg_maxWidth) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.moxxy_native.MoxxyMediaApi.generateVideoThumbnail', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_src, arg_dest, arg_maxWidth]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as bool?)!;
|
||||
}
|
||||
}
|
||||
}
|
16
pigeon/media.dart
Normal file
16
pigeon/media.dart
Normal file
@ -0,0 +1,16 @@
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
@ConfigurePigeon(
|
||||
PigeonOptions(
|
||||
dartOut: 'lib/pigeon/media.g.dart',
|
||||
kotlinOut: 'android/src/main/kotlin/org/moxxy/moxxy_native/media/MediaApi.kt',
|
||||
kotlinOptions: KotlinOptions(
|
||||
package: 'org.moxxy.moxxy_native.media',
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
@HostApi()
|
||||
abstract class MoxxyMediaApi {
|
||||
bool generateVideoThumbnail(String src, String dest, int maxWidth);
|
||||
}
|
Loading…
Reference in New Issue
Block a user