feat(YouTube - Overlay buttons): Improve the translation workflow of subtitles after Yandex transcription
This commit is contained in:
parent
77c52ee38c
commit
88e54e64db
3 changed files with 87 additions and 2 deletions
|
|
@ -374,8 +374,10 @@ public final class GeminiManager {
|
|||
}
|
||||
|
||||
// Call Gemini for translation
|
||||
String cleanedJson = YandexVotUtils.stripTokensFromYandexJson(rawIntermediateJson);
|
||||
|
||||
GeminiUtils.translateYandexJson(
|
||||
rawIntermediateJson,
|
||||
cleanedJson,
|
||||
targetLangName,
|
||||
apiKey,
|
||||
new GeminiUtils.Callback() {
|
||||
|
|
|
|||
|
|
@ -236,7 +236,19 @@ public class GeminiUtils {
|
|||
.getJSONArray("parts")
|
||||
.getJSONObject(0)
|
||||
.getString("text");
|
||||
final String finalResult = resultText.trim();
|
||||
|
||||
final String finalResult = sanitizeJsonOutput(resultText);
|
||||
Logger.printDebug(() -> "Gemini RAW result (Sanitized): " + finalResult.substring(0, Math.min(finalResult.length(), 300)) + "...");
|
||||
|
||||
if (videoUrl == null) {
|
||||
boolean looksLikeJson = finalResult.startsWith("[") || finalResult.startsWith("{");
|
||||
if (!looksLikeJson) {
|
||||
Logger.printInfo(() -> "Gemini JSON translation result doesn't look like valid JSON!");
|
||||
Logger.printInfo(() -> "Start of content: " + finalResult.substring(0, Math.min(finalResult.length(), 50)));
|
||||
mainThreadHandler.post(() -> callback.onFailure("Translation result format error. Expected JSON."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.printDebug(() -> "Gemini RAW result received: " + finalResult.substring(0, Math.min(finalResult.length(), 300)) + "...");
|
||||
|
||||
|
|
@ -498,6 +510,22 @@ public class GeminiUtils {
|
|||
return "English";
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans the Gemini response to remove potential Markdown formatting.
|
||||
*/
|
||||
private static String sanitizeJsonOutput(String text) {
|
||||
if (text == null) return "";
|
||||
text = text.trim();
|
||||
|
||||
if (text.startsWith("```")) {
|
||||
text = text.replaceFirst("^```[a-zA-Z]*\\s*", "");
|
||||
}
|
||||
if (text.endsWith("```")) {
|
||||
text = text.replaceAll("\\s*```$", "");
|
||||
}
|
||||
return text.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface for Gemini API operations (summary, transcription).
|
||||
* Defines methods to handle successful results or failures.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import app.revanced.extension.shared.utils.Logger;
|
||||
import okhttp3.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
|
@ -973,6 +974,60 @@ public class YandexVotUtils {
|
|||
return serverMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to strip the "tokens" array from Yandex JSON.
|
||||
* This drastically reduces the size of the JSON sent to Gemini,
|
||||
* preventing output truncation and saving tokens.
|
||||
*
|
||||
* @param jsonContent The raw JSON from Yandex.
|
||||
* @return The JSON string with 'tokens' arrays removed from each subtitle entry.
|
||||
*/
|
||||
public static String stripTokensFromYandexJson(String jsonContent) {
|
||||
if (TextUtils.isEmpty(jsonContent)) return jsonContent;
|
||||
try {
|
||||
// Handle case where JSON is just an array (non-standard Yandex output)
|
||||
if (jsonContent.trim().startsWith("[")) {
|
||||
JSONArray root = new JSONArray(jsonContent);
|
||||
for (int i = 0; i < root.length(); i++) {
|
||||
JSONObject item = root.getJSONObject(i);
|
||||
if (item.has("tokens")) item.remove("tokens");
|
||||
}
|
||||
return root.toString();
|
||||
} else {
|
||||
// Handle standard object with "subtitles" array (standard Yandex output)
|
||||
JSONObject root = getJsonObject(jsonContent);
|
||||
return root.toString();
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Logger.printException(() -> "Failed to strip tokens from JSON", e);
|
||||
return jsonContent; // Return original if modification fails
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the provided JSON string into a JSONObject and removes the verbose "tokens"
|
||||
* arrays from within the "subtitles" list. It also updates metadata flags to reflect
|
||||
* the removal of tokens.
|
||||
*
|
||||
* @param jsonContent The raw JSON string containing the subtitle object.
|
||||
* @return The modified {@link JSONObject} with tokens removed.
|
||||
* @throws JSONException If the string cannot be parsed or the structure is invalid.
|
||||
*/
|
||||
@NotNull
|
||||
private static JSONObject getJsonObject(String jsonContent) throws JSONException {
|
||||
JSONObject root = new JSONObject(jsonContent);
|
||||
if (root.has("subtitles")) {
|
||||
JSONArray subs = root.getJSONArray("subtitles");
|
||||
for (int i = 0; i < subs.length(); i++) {
|
||||
JSONObject item = subs.getJSONObject(i);
|
||||
if (item.has("tokens")) item.remove("tokens");
|
||||
}
|
||||
}
|
||||
// Also remove top-level containsTokens flag if present
|
||||
if (root.has("containsTokens")) root.put("containsTokens", false);
|
||||
return root;
|
||||
}
|
||||
|
||||
// endregion Utils
|
||||
|
||||
// region Interfaces and Inner Classes
|
||||
|
|
|
|||
Loading…
Reference in a new issue