refactor: remove deprecated transcript api
Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>
This commit is contained in:
@@ -1056,14 +1056,6 @@
|
||||
"preferred_transcription_lang": {
|
||||
"name": "Preferred Transcription Language",
|
||||
"description": "The preferred language for the voice note transcript (e.g. EN, ES, FR)"
|
||||
},
|
||||
"enhanced_transcript": {
|
||||
"name": "Enhanced Transcript",
|
||||
"description": "Improves the voice note transcript using DeepL.\nBefore using this feature, please ensure that you have read their privacy policy."
|
||||
},
|
||||
"enhanced_transcript_in_notifications": {
|
||||
"name": "Enhanced Transcript in Notifications",
|
||||
"description": "Transcribes voice notes in notifications using DeepL. This requires the Chat Preview feature to be enabled in Better Notifications"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -20,8 +20,6 @@ class Experimental : ConfigContainer() {
|
||||
class BetterTranscriptConfig: ConfigContainer(hasGlobalState = true) {
|
||||
val forceTranscription = boolean("force_transcription") { requireRestart() }
|
||||
val preferredTranscriptionLang = string("preferred_transcription_lang") { requireRestart() }
|
||||
val enhancedTranscript = boolean("enhanced_transcript") { requireRestart(); addNotices(FeatureNotice.UNSTABLE) }
|
||||
val enhancedTranscriptInNotifications = boolean("enhanced_transcript_in_notifications") { requireRestart(); addNotices(FeatureNotice.UNSTABLE) }
|
||||
}
|
||||
|
||||
class ComposerHooksConfig: ConfigContainer(hasGlobalState = true) {
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package me.rhunk.snapenhance.common.util
|
||||
|
||||
import com.google.gson.JsonParser
|
||||
import me.rhunk.snapenhance.common.Constants
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
|
||||
|
||||
class TranscriptApi(
|
||||
private val okHttpClient: OkHttpClient = OkHttpClient.Builder().addInterceptor {
|
||||
it.proceed(it.request().newBuilder().header("User-Agent", Constants.USER_AGENT).build())
|
||||
}.build()
|
||||
) {
|
||||
private fun genDlClearance() = okHttpClient.newCall(
|
||||
Request("https://clearance.deepl.com/token".toHttpUrl())
|
||||
).execute().use { response ->
|
||||
val cookie = response.headers.firstOrNull { it.first.lowercase() == "set-cookie" && it.second.contains("dl_clearance", ignoreCase = true) }
|
||||
cookie?.second?.substringBefore(";")?.substringAfter("dl_clearance=")
|
||||
}
|
||||
|
||||
fun transcribe(
|
||||
body: RequestBody,
|
||||
lang: String? = null,
|
||||
): String? {
|
||||
val clearance = genDlClearance() ?: return null
|
||||
val url = "https://voice-pro.www.deepl.com/sync/transcribe".toHttpUrl().newBuilder()
|
||||
.apply {
|
||||
lang?.let { addQueryParameter("lang", it) }
|
||||
}
|
||||
.build()
|
||||
val request = Request(url, headers = Headers.headersOf(
|
||||
"Cookie", "dl_clearance=$clearance",
|
||||
"Content-Type", "audio/webm"
|
||||
), method = "POST", body = body)
|
||||
return okHttpClient.newCall(request).execute().use { response ->
|
||||
if (!response.isSuccessful) return@use null
|
||||
val jsonObject = JsonParser.parseString(response.body.string()).asJsonObject
|
||||
jsonObject.getAsJsonArray("segments").fold("") { text, segment ->
|
||||
text + segment.asJsonObject.getAsJsonPrimitive("text").asString
|
||||
}.trim()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,15 @@
|
||||
package me.rhunk.snapenhance.core.features.impl.experiments
|
||||
|
||||
import me.rhunk.snapenhance.common.data.ContentType
|
||||
import me.rhunk.snapenhance.common.util.TranscriptApi
|
||||
import me.rhunk.snapenhance.common.util.protobuf.ProtoEditor
|
||||
import me.rhunk.snapenhance.core.event.events.impl.BuildMessageEvent
|
||||
import me.rhunk.snapenhance.core.features.Feature
|
||||
import me.rhunk.snapenhance.core.util.dataBuilder
|
||||
import me.rhunk.snapenhance.core.util.hook.HookStage
|
||||
import me.rhunk.snapenhance.core.util.hook.hook
|
||||
import me.rhunk.snapenhance.core.util.ktx.getObjectFieldOrNull
|
||||
import me.rhunk.snapenhance.core.util.ktx.setObjectField
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import java.lang.reflect.Method
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
class BetterTranscript: Feature("Better Transcript") {
|
||||
val transcriptApi by lazy { TranscriptApi() }
|
||||
|
||||
override fun init() {
|
||||
if (context.config.experimental.betterTranscript.globalState != true) return
|
||||
|
||||
@@ -40,33 +33,6 @@ class BetterTranscript: Feature("Better Transcript") {
|
||||
}
|
||||
|
||||
findClass("com.snapchat.client.voiceml.IVoiceMLSDK\$CppProxy").hook("asrTranscribe", HookStage.BEFORE) { param ->
|
||||
if (config.enhancedTranscript.get()) {
|
||||
val buffer = param.arg<ByteBuffer>(2).let {
|
||||
it.rewind()
|
||||
ByteArray(it.remaining()).also { it1 -> it.get(it1); it.rewind() }
|
||||
}
|
||||
val result = runCatching {
|
||||
transcriptApi.transcribe(
|
||||
buffer.toRequestBody(),
|
||||
lang = config.preferredTranscriptionLang.getNullable()?.takeIf {
|
||||
it.isNotBlank()
|
||||
}?.uppercase()
|
||||
)
|
||||
}.onFailure {
|
||||
context.log.error("Failed to transcribe audio", it)
|
||||
context.shortToast("Failed to transcribe audio! Check logcat for more details.")
|
||||
}.getOrNull()
|
||||
|
||||
param.setResult(
|
||||
(param.method() as Method).returnType.dataBuilder {
|
||||
set("mError", result == null)
|
||||
set("mNlpResponses", ArrayList<Any>())
|
||||
set("mWordInfo", ArrayList<Any>())
|
||||
set("mTranscription", result)
|
||||
}
|
||||
)
|
||||
return@hook
|
||||
}
|
||||
preferredTranscriptionLang?.lowercase()?.let {
|
||||
val asrConfig = param.arg<Any>(1)
|
||||
asrConfig.getObjectFieldOrNull("mBaseConfig")?.apply {
|
||||
|
||||
@@ -24,9 +24,7 @@ import me.rhunk.snapenhance.core.event.events.impl.SnapWidgetBroadcastReceiveEve
|
||||
import me.rhunk.snapenhance.core.features.Feature
|
||||
import me.rhunk.snapenhance.core.features.impl.FriendMutationObserver
|
||||
import me.rhunk.snapenhance.core.features.impl.downloader.MediaDownloader
|
||||
import me.rhunk.snapenhance.core.features.impl.downloader.decoder.AttachmentType
|
||||
import me.rhunk.snapenhance.core.features.impl.downloader.decoder.MessageDecoder
|
||||
import me.rhunk.snapenhance.core.features.impl.experiments.BetterTranscript
|
||||
import me.rhunk.snapenhance.core.features.impl.spying.StealthMode
|
||||
import me.rhunk.snapenhance.core.util.hook.HookStage
|
||||
import me.rhunk.snapenhance.core.util.hook.findRestrictedConstructor
|
||||
@@ -36,7 +34,6 @@ import me.rhunk.snapenhance.core.util.ktx.setObjectField
|
||||
import me.rhunk.snapenhance.core.util.media.PreviewUtils
|
||||
import me.rhunk.snapenhance.core.wrapper.impl.Message
|
||||
import me.rhunk.snapenhance.core.wrapper.impl.SnapUUID
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
class Notifications : Feature("Notifications") {
|
||||
@@ -390,28 +387,6 @@ class Notifications : Feature("Notifications") {
|
||||
}"
|
||||
}
|
||||
|
||||
if (contentType == ContentType.NOTE && context.config.experimental.betterTranscript.takeIf { it.globalState == true }?.enhancedTranscriptInNotifications?.get() == true) {
|
||||
val transcriptApi = context.feature(BetterTranscript::class).transcriptApi
|
||||
MessageDecoder.decode(message.messageContent!!).firstOrNull { it.type == AttachmentType.NOTE }?.also { media ->
|
||||
runCatching {
|
||||
media.openStream { mediaStream, length ->
|
||||
if (mediaStream == null || length > 25 * 1024 * 1024) {
|
||||
context.log.error("Failed to open media stream or media is too large")
|
||||
return@openStream
|
||||
}
|
||||
val text = transcriptApi.transcribe(
|
||||
mediaStream.readBytes().toRequestBody(),
|
||||
lang = context.config.experimental.betterTranscript.preferredTranscriptionLang.getNullable()?.takeIf { it.isNotBlank() }
|
||||
)?.takeIf { it.isNotBlank() } ?: return@openStream
|
||||
serializedMessage = "\uD83C\uDFA4 $text"
|
||||
isChatMessage = true
|
||||
}
|
||||
}.onFailure {
|
||||
context.log.error("Failed to transcribe message", it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isChatMessage || config.stackedMediaMessages.get()) {
|
||||
setNotificationText(serializedMessage)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user