Skip to content

Commit 50805ff

Browse files
committed
Add Voice note Speed
1 parent b2e86ba commit 50805ff

File tree

9 files changed

+195
-3
lines changed

9 files changed

+195
-3
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package com.wmods.wppenhacer.preference;
2+
3+
import android.content.Context;
4+
import android.content.res.TypedArray;
5+
import android.util.AttributeSet;
6+
import android.widget.SeekBar;
7+
import android.widget.TextView;
8+
9+
import androidx.preference.Preference;
10+
import androidx.preference.PreferenceViewHolder;
11+
12+
import com.wmods.wppenhacer.R;
13+
14+
public class FloatSeekBarPreference extends Preference implements SeekBar.OnSeekBarChangeListener {
15+
16+
private float minValue;
17+
private float maxValue;
18+
private float valueSpacing;
19+
private String format;
20+
21+
private SeekBar seekbar;
22+
private TextView textView;
23+
24+
private float defaultValue = 0F;
25+
private float newValue = 0F;
26+
27+
public FloatSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
28+
super(context, attrs, defStyleAttr, defStyleRes);
29+
init(context, attrs, defStyleAttr, defStyleRes);
30+
}
31+
32+
public FloatSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
33+
this(context, attrs, defStyleAttr, 0);
34+
}
35+
36+
public FloatSeekBarPreference(Context context, AttributeSet attrs) {
37+
this(context, attrs, androidx.preference.R.attr.seekBarPreferenceStyle);
38+
}
39+
40+
public FloatSeekBarPreference(Context context) {
41+
this(context, null);
42+
}
43+
44+
@Override
45+
protected Object onGetDefaultValue(TypedArray ta, int index) {
46+
defaultValue = ta.getFloat(index, 0F);
47+
return defaultValue;
48+
}
49+
50+
@Override
51+
protected void onSetInitialValue(Object defaultValue) {
52+
newValue = getPersistedFloat((defaultValue instanceof Float) ? (Float) defaultValue : this.defaultValue);
53+
}
54+
55+
@Override
56+
public void onBindViewHolder(PreferenceViewHolder holder) {
57+
super.onBindViewHolder(holder);
58+
59+
holder.itemView.setClickable(false);
60+
seekbar = (SeekBar) holder.findViewById(R.id.seekbar);
61+
textView = (TextView) holder.findViewById(R.id.seekbar_value);
62+
63+
seekbar.setOnSeekBarChangeListener(this);
64+
seekbar.setMax((int) ((maxValue - minValue) / valueSpacing));
65+
seekbar.setProgress((int) ((newValue - minValue) / valueSpacing));
66+
seekbar.setEnabled(isEnabled());
67+
68+
textView.setText(String.format(format, newValue));
69+
}
70+
71+
@Override
72+
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
73+
if (!fromUser) {
74+
return;
75+
}
76+
float v = minValue + progress * valueSpacing;
77+
textView.setText(String.format(format, v));
78+
}
79+
80+
@Override
81+
public void onStartTrackingTouch(SeekBar seekBar) {
82+
// Not used
83+
}
84+
85+
@Override
86+
public void onStopTrackingTouch(SeekBar seekBar) {
87+
float v = minValue + seekBar.getProgress() * valueSpacing;
88+
persistFloat(v);
89+
}
90+
91+
private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
92+
setWidgetLayoutResource(R.layout.pref_float_seekbar);
93+
94+
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FloatSeekBarPreference, defStyleAttr, defStyleRes);
95+
minValue = ta.getFloat(R.styleable.FloatSeekBarPreference_minValue, 0F);
96+
maxValue = ta.getFloat(R.styleable.FloatSeekBarPreference_maxValue, 1F);
97+
valueSpacing = ta.getFloat(R.styleable.FloatSeekBarPreference_valueSpacing, .1F);
98+
format = ta.getString(R.styleable.FloatSeekBarPreference_format);
99+
if (format == null) {
100+
format = "%3.1f";
101+
}
102+
ta.recycle();
103+
}
104+
105+
public float getValue() {
106+
return (seekbar != null) ? (seekbar.getProgress() * valueSpacing) + minValue : 0F;
107+
}
108+
109+
public void setValue(float value) {
110+
newValue = value;
111+
persistFloat(value);
112+
notifyChanged();
113+
}
114+
}

app/src/main/java/com/wmods/wppenhacer/ui/fragments/HomeFragment.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ private void importConfigs(Context context) {
164164
prefs.edit().putInt(keyName, (int) value).apply();
165165
} else if (value instanceof Long) {
166166
prefs.edit().putLong(keyName, (long) value).apply();
167+
} else if (value instanceof Float) {
168+
prefs.edit().putFloat(keyName, (float) value).apply();
167169
}
168170
}
169171
}

app/src/main/java/com/wmods/wppenhacer/xposed/core/Unobfuscator.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,4 +1580,11 @@ public static Method loadShowDialogStatusMethod(ClassLoader classLoader) throws
15801580
});
15811581
}
15821582

1583+
public static Method loadPlaybackSpeed(ClassLoader classLoader) throws Exception {
1584+
return UnobfuscatorCache.getInstance().getMethod(classLoader, () -> {
1585+
var method = findFirstMethodUsingStrings(classLoader, StringMatchType.Contains, "heroaudioplayer/setPlaybackSpeed");
1586+
if (method == null) throw new RuntimeException("PlaybackSpeed method not found");
1587+
return method;
1588+
});
1589+
}
15831590
}

app/src/main/java/com/wmods/wppenhacer/xposed/core/Utils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,13 @@ public static XC_MethodHook getDebugMethodHook(boolean printMethods, boolean pri
110110
@Override
111111
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
112112
XposedBridge.log("\n\n-----------------HOOKED DEBUG START-----------------------------");
113-
XposedBridge.log("DEBUG CLASS: " + param.method.getDeclaringClass().getName() + ": " + param.thisObject);
113+
XposedBridge.log("DEBUG CLASS: " + param.method.getDeclaringClass().getName() + "->" + param.method.getName() + ": " + param.thisObject);
114114

115115
if (printArgs) {
116116
for (var i = 0; i < param.args.length; i++) {
117117
XposedBridge.log("ARG[" + i + "]: " + (param.args[i] == null ? null : param.args[i].getClass().getName()) + " -> VALUE: " + param.args[i]);
118118
}
119+
XposedBridge.log("Return value: " + (param.getResult() == null ? null : param.getResult().getClass().getName()) + " -> VALUE: " + param.getResult());
119120
}
120121
if (printFields) {
121122
debugFields(param.thisObject);

app/src/main/java/com/wmods/wppenhacer/xposed/features/general/Others.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,38 @@ public void doHook() throws Exception {
176176
sendAudioType(audio_type);
177177
}
178178
copieStatusToClipboard();
179+
customPlayBackSpeed();
179180

181+
}
180182

183+
private void customPlayBackSpeed() throws Exception {
184+
var voicenote_speed = prefs.getFloat("voicenote_speed", 2.0f);
185+
var playBackSpeed = Unobfuscator.loadPlaybackSpeed(classLoader);
186+
XposedBridge.hookMethod(playBackSpeed, new XC_MethodHook() {
187+
@Override
188+
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
189+
super.beforeHookedMethod(param);
190+
if ((float) param.args[1] == 2.0f) {
191+
param.args[1] = voicenote_speed;
192+
}
193+
}
194+
});
195+
var voicenoteClass = classLoader.loadClass("com.whatsapp.search.views.itemviews.VoiceNoteProfileAvatarView");
196+
var method = ReflectionUtils.findAllMethodUsingFilter(voicenoteClass, method1 -> method1.getParameterCount() == 4 && method1.getParameterTypes()[0] == int.class && method1.getReturnType().equals(void.class));
197+
XposedBridge.hookMethod(method[method.length - 1], new XC_MethodHook() {
198+
@SuppressLint("SetTextI18n")
199+
@Override
200+
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
201+
super.afterHookedMethod(param);
202+
if ((int) param.args[0] == 3) {
203+
var view = (View) param.thisObject;
204+
var playback = (TextView) view.findViewById(Utils.getID("fast_playback_overlay", "id"));
205+
if (playback != null) {
206+
playback.setText(voicenote_speed + "x");
207+
}
208+
}
209+
}
210+
});
181211
}
182212

183213
private void copieStatusToClipboard() throws Exception {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="fill_parent"
4+
android:layout_height="wrap_content"
5+
android:gravity="center_vertical">
6+
7+
<androidx.appcompat.widget.AppCompatSeekBar
8+
android:id="@+id/seekbar"
9+
android:layout_width="0dp"
10+
android:layout_height="wrap_content"
11+
android:layout_weight="80" />
12+
13+
<TextView
14+
android:id="@+id/seekbar_value"
15+
android:layout_width="0dp"
16+
android:layout_height="wrap_content"
17+
android:layout_weight="20" />
18+
19+
</LinearLayout>

app/src/main/res/values/attrs.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@
1919
-->
2020

2121
<resources>
22+
23+
<declare-styleable name="FloatSeekBarPreference">
24+
<attr name="minValue" format="float" />
25+
<attr name="maxValue" format="float" />
26+
<attr name="valueSpacing" format="float" />
27+
<attr name="format" format="float" />
28+
</declare-styleable>
29+
30+
2231
<attr name="colorNormal" format="color" />
2332
<attr name="colorInstall" format="color" />
2433

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,7 @@
259259
<string name="toast_on_viewed_message_sum">Shows a toast if someone views your message</string>
260260
<string name="textonahora_sum">Show text next to any timestamp in the WhatsApp app</string>
261261
<string name="delete_for_me">Delete(for me)</string>
262+
<string name="send_audio_as_voice_audio_note">Send audio as voice/audio Note</string>
263+
<string name="send_audio_as_voice_audio_note_sum">Always sends audio media/forward as a voice note or audio note</string>
264+
<string name="voice_note_speed">Voice Note Speed</string>
262265
</resources>

app/src/main/res/xml/fragment_media.xml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,16 @@
7474
android:defaultValue="0"
7575
android:entries="@array/audio_type_buttons"
7676
android:entryValues="@array/audio_type_values"
77-
android:summary="Always sends audio media/forward as a voice note or audio note"
77+
android:summary="@string/send_audio_as_voice_audio_note_sum"
7878
app:key="audio_type"
79-
app:title="Send audio as voice/audio Note" />
79+
app:title="@string/send_audio_as_voice_audio_note" />
80+
81+
<com.wmods.wppenhacer.preference.FloatSeekBarPreference
82+
android:defaultValue="2"
83+
app:key="voicenote_speed"
84+
app:maxValue="5"
85+
app:minValue="0.1"
86+
app:title="@string/voice_note_speed" />
8087

8188
</PreferenceCategory>
8289

0 commit comments

Comments
 (0)