Skip to content

Commit

Permalink
Merge pull request #187 from rodit/high-quality
Browse files Browse the repository at this point in the history
High quality
  • Loading branch information
rodit authored Jun 5, 2022
2 parents ae0a00c + 41cc04a commit c12b55b
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 17 deletions.
Binary file modified app/libs/snapmod.jar
Binary file not shown.
37 changes: 37 additions & 0 deletions app/src/main/java/xyz/rodit/snapmod/SettingsActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package xyz.rodit.snapmod
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.ImageFormat
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.net.Uri
import android.os.Bundle
import android.text.InputType
Expand All @@ -14,6 +17,7 @@ import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.appcompat.app.AlertDialog
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceManager
import xyz.rodit.xposed.SettingsActivity
Expand Down Expand Up @@ -76,6 +80,8 @@ class SettingsActivity : SettingsActivity(R.xml.root_preferences) {
setNumericInput(fragment, "location_share_lat")
setNumericInput(fragment, "location_share_long")
setNumericInput(fragment, "audio_playback_speed")
setNumericInput(fragment, "custom_video_fps")
setNumericInput(fragment, "custom_video_bitrate")

(fragment.findPreference<Preference>("hidden_friends") as EditTextPreference?)?.apply {
setOnBindEditTextListener {
Expand All @@ -85,6 +91,30 @@ class SettingsActivity : SettingsActivity(R.xml.root_preferences) {
it.setSelection(it.text.length)
}
}

val camera = getSystemService(CAMERA_SERVICE) as CameraManager
val characteristics = camera.getCameraCharacteristics(camera.cameraIdList[0])
val config = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
config?.let { c ->
val sizes = c.getOutputSizes(ImageFormat.JPEG)
val strings = sizes.map { s -> "${s.width}x${s.height}" }.toTypedArray()
sequenceOf(
"custom_image_resolution",
"custom_video_resolution"
).map { fragment.findPreference<ListPreference>(it) }
.filterNotNull()
.forEach {
it.entries = strings + "Default"
it.entryValues = strings + "0"
}
}

fragment.findPreference<Preference>("camera_readme")?.apply {
onPreferenceClickListener = Preference.OnPreferenceClickListener {
showCameraReadme()
true
}
}
}

private fun setNumericInput(fragment: SettingsFragment, name: String) {
Expand All @@ -102,6 +132,13 @@ class SettingsActivity : SettingsActivity(R.xml.root_preferences) {
.show()
}

private fun showCameraReadme() {
AlertDialog.Builder(this)
.setTitle(R.string.camera_title)
.setMessage(R.string.camera_dialog_description)
.show()
}

private fun getInstallationSummary(detailed: Boolean): Spannable {
val builder = SpannableStringBuilder()
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class FeatureManager(context: FeatureContext) : Contextual(context) {
// Tweaks
add(::BypassVideoLength)
add(::BypassVideoLengthGlobal)
add(::CameraResolution)
add(::ConfigurationTweaks)
add(::ConfigurationTweaks)
add(::DisableBitmojis)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ class AdditionalFriendInfo(context: FeatureContext) : Feature(context) {
override fun performHooks() {
// Show more info in friend profile footer.
FriendProfileTransformer.apply.after(context, "more_profile_info") {
if (!FriendProfilePageData.isInstance(it.args[0]) || it.result !is List<*>) return@after
val transformer = FriendProfileTransformer.wrap(it.thisObject)
if (!FriendProfilePageData.isInstance(transformer.data) || it.result !is List<*>) return@after

val viewModelList = it.result as List<*>
if (viewModelList.isEmpty()) return@after

val viewModel = viewModelList[0]!!
if (!FooterInfoItem.isInstance(viewModel)) return@after

val data = FriendProfilePageData.wrap(it.args[0])
val data = FriendProfilePageData.wrap(transformer.data)
val friendDate = Date(max(data.addedTimestamp, data.reverseAddedTimestamp))
val birthday = if (data.birthday.isNull) CalendarDate(13, -1) else data.birthday

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package xyz.rodit.snapmod.features.tweaks

import xyz.rodit.snapmod.features.Feature
import xyz.rodit.snapmod.features.FeatureContext
import xyz.rodit.snapmod.mappings.MediaQualityLevel
import xyz.rodit.snapmod.mappings.RecordingCodecConfiguration
import xyz.rodit.snapmod.mappings.ScCameraSettings
import xyz.rodit.snapmod.mappings.TranscodingRequest
import xyz.rodit.snapmod.util.after
import xyz.rodit.snapmod.util.getNonDefault
import xyz.rodit.snapmod.util.getResolution

class CameraResolution(context: FeatureContext) : Feature(context) {

override fun performHooks() {
// Override preview and picture resolution
ScCameraSettings.constructors.after {
val settings = ScCameraSettings.wrap(it.thisObject)
context.config.getResolution("custom_video_resolution")?.let { r ->
val previewResolution = settings.previewResolution
if (previewResolution.isNotNull) {
previewResolution.width = r.width
previewResolution.height = r.height
}
}

context.config.getResolution("custom_image_resolution")?.let { r ->
val pictureResolution = settings.pictureResolution
if (pictureResolution.isNotNull) {
pictureResolution.width = r.width
pictureResolution.height = r.height
}
}
}

// Override actual recording resolution
RecordingCodecConfiguration.constructors.after {
val config = RecordingCodecConfiguration.wrap(it.thisObject)
context.config.getResolution("custom_video_resolution")?.let { r ->
val res = config.resolution
res.width = r.width
res.height = r.height
}

context.config.getNonDefault("custom_video_bitrate")?.let { bitrate ->
config.bitrate = bitrate
}
}

// Override save/send quality level
TranscodingRequest.constructors.after(context, "force_source_encoding") {
TranscodingRequest.wrap(it.thisObject).qualityLevel = MediaQualityLevel.LEVEL_MAX()
}
}
}
11 changes: 11 additions & 0 deletions app/src/main/java/xyz/rodit/snapmod/logging/XLogUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package xyz.rodit.snapmod.logging

import android.util.Log
import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.XposedHelpers
import java.util.*

private val logMap = WeakHashMap<Any, XLog>()
Expand Down Expand Up @@ -44,4 +46,13 @@ fun XLog.dumpMethodCall(param: XC_MethodHook.MethodHookParam) {
"Arguments:\n" +
param.args.mapIndexed { i, o -> "$i: $o" }.joinToString("\n")
)
}

fun XLog.dumpConstruction(className: String, classLoader: ClassLoader) {
val cls = XposedHelpers.findClass(className, classLoader)
XposedBridge.hookAllConstructors(cls, object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam) {
debug("${param.thisObject}")
}
})
}
20 changes: 19 additions & 1 deletion app/src/main/java/xyz/rodit/snapmod/util/ConfigExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,22 @@ fun ConfigurationClient.getList(key: String): List<String> {
.split(',')
.filter(String::isNotBlank)
.map(String::trim)
}
}

fun ConfigurationClient.getNonDefault(key: String, default: Int = 0): Int? {
val value = this.getInt(key, default)
return if (value == default) null else value
}

fun ConfigurationClient.getResolution(key: String): Resolution? {
val parts = this.getString(key, "0").split('x')
if (parts.size != 2) return null
return try {
val dimens = parts.map { it.toInt() }
Resolution(dimens[0], dimens[1])
} catch (ex: Exception) {
null
}
}

data class Resolution(val width: Int, val height: Int)
8 changes: 8 additions & 0 deletions app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@
<item>NOTE</item>
</string-array>

<string-array name="default_resolutions">
<item>Default</item>
</string-array>

<string-array name="default_resolutions_values">
<item>0</item>
</string-array>

<string-array name="sc_scope">
<item>com.snapchat.android</item>
</string-array>
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<string name="title_activity_settings">Settings</string>
<string name="privacy_header">Privacy</string>
<string name="tweaks_header">Tweaks</string>
<string name="camera_header">🧪 Camera</string>
<string name="snaps_header">Snaps</string>
<string name="downloads_header">Downloads</string>
<string name="notifications_header">Notifications</string>
Expand Down Expand Up @@ -158,6 +159,23 @@

<string name="enable_new_chat_menu_title">Enable New Chat Menu</string>
<string name="enable_new_chat_menu_description">Enables the new chat context menu (recommended).</string>

<string name="enable_story_list_title">Enable Story List</string>
<string name="enable_story_list_description">Replaces the default story carousel with a list.</string>

<string name="camera_title">Notice</string>
<string name="camera_description">Tap to read.</string>
<string name="camera_dialog_description">Note, increasing video resolution, FPS and bitrate all have an effect on the media size. This means high quality videos will take up a lot of storage space and will take a long time to upload and download for the recipient.</string>

<string name="custom_image_resolution_title">Image Resolution</string>
<string name="custom_video_resolution_title">Video Resolution</string>

<string name="custom_video_fps_title">Video FPS</string>
<string name="custom_video_fps_default">Set to 0 for default FPS.</string>

<string name="custom_video_bitrate_title">Video Bitrate (bps)</string>
<string name="custom_video_bitrate_default">Set to 0 for default bitrate. Higher bitrate leads to higher quality but also larger file sizes. For example, 4k videos typically have a bitrate of 60000000 to 100000000 bps.</string>

<string name="force_source_encoding_title">Force Source Encoding</string>
<string name="force_source_encoding_description">Forces Snapchat to use the source resolution and bitrate when saving/sending videos and images. This must be enabled for custom video/image resolution to be noticeable.</string>
</resources>
46 changes: 46 additions & 0 deletions app/src/main/res/xml/root_preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,52 @@
app:iconSpaceReserved="false" />
</PreferenceCategory>

<PreferenceCategory app:title="@string/camera_header"
app:iconSpaceReserved="false">

<Preference
app:key="camera_readme"
app:title="@string/camera_title"
app:summary="@string/camera_description"
app:iconSpaceReserved="false" />

<ListPreference
app:key="custom_image_resolution"
app:title="@string/custom_image_resolution_title"
app:entries="@array/default_resolutions"
app:entryValues="@array/default_resolutions_values"
app:defaultValue="0"
app:iconSpaceReserved="false" />

<ListPreference
app:key="custom_video_resolution"
app:title="@string/custom_video_resolution_title"
app:entries="@array/default_resolutions"
app:entryValues="@array/default_resolutions_values"
app:defaultValue="0"
app:iconSpaceReserved="false" />

<EditTextPreference
app:key="custom_video_fps"
app:title="@string/custom_video_fps_title"
app:dialogMessage="@string/custom_video_fps_default"
app:defaultValue="0"
app:iconSpaceReserved="false" />

<EditTextPreference
app:key="custom_video_bitrate"
app:title="@string/custom_video_bitrate_title"
app:dialogMessage="@string/custom_video_bitrate_default"
app:defaultValue="0"
app:iconSpaceReserved="false" />

<SwitchPreferenceCompat
app:key="force_source_encoding"
app:title="@string/force_source_encoding_title"
app:summary="@string/force_source_encoding_description"
app:iconSpaceReserved="false" />
</PreferenceCategory>

<PreferenceCategory app:title="@string/snaps_header"
app:iconSpaceReserved="false">

Expand Down
Loading

0 comments on commit c12b55b

Please sign in to comment.