StarRailCopilot/module/device/method/scrcpy/options.py

133 lines
4.7 KiB
Python

import typing as t
import module.device.method.scrcpy.const as const
class ScrcpyOptions:
frame_rate = 10
@classmethod
def codec_options(cls) -> str:
"""
Custom codec options passing through scrcpy.
https://developer.android.com/reference/android/media/MediaFormat
Returns:
key_profile=1,key_level=4096,...
"""
options = dict(
# H.264 profile and level
# https://developer.android.com/reference/android/media/MediaCodecInfo.CodecProfileLevel
# Baseline, which only has I/P frames
key_profile=1,
# Level 4.1, for 1280x720@30fps
key_level=4096,
# Max quality
key_quality=100,
# https://developer.android.com/reference/android/media/MediaCodecInfo.EncoderCapabilities
# Constant quality
key_bitrate_mode=0,
# A zero value means a stream containing all key frames is requested.
key_i_frame_interval=0,
# https://developer.android.com/reference/android/media/MediaCodecInfo.CodecCapabilities
# COLOR_Format24bitBGR888
key_color_format=12,
# The same as output frame rate to lower CPU consumption
key_capture_rate=cls.frame_rate,
# 20Mbps, the maximum output bitrate of scrcpy
key_bit_rate=20000000,
)
return ','.join([f'{k}={v}' for k, v in options.items()])
@classmethod
def arguments(cls) -> t.List[str]:
"""
https://github.com/Genymobile/scrcpy/blob/master/server/src/main/java/com/genymobile/scrcpy/Server.java
https://github.com/Genymobile/scrcpy/blob/master/server/src/main/java/com/genymobile/scrcpy/Options.java
Returns:
['log_level=info', 'max_size=1280', ...]
"""
options = [
'log_level=info',
'max_size=1280',
# 20Mbps, the maximum output bitrate of scrcpy
# If a higher value is set, scrcpy fallback to 8Mbps default.
'bit_rate=20000000',
# Screenshot time cost <= 300ms is enough for human speed.
f'max_fps={cls.frame_rate}',
# No orientation lock
f'lock_video_orientation={const.LOCK_SCREEN_ORIENTATION_UNLOCKED}',
# Always true
'tunnel_forward=true',
# Always true for controlling via scrcpy
'control=true',
# Default to 0
'display_id=0',
# Useless, always false
'show_touches=false',
# Not determined, leave it as default
'stay_awake=false',
# Encoder name
# Should in [
# "OMX.google.h264.encoder",
# "OMX.qcom.video.encoder.avc",
# "c2.qti.avc.encoder",
# "c2.android.avc.encoder",
# ]
# Empty value, let scrcpy to decide
# 'encoder_name=',
# Codec options
f'codec_options={cls.codec_options()}',
# Useless, always false
'power_off_on_close=false',
'clipboard_autosync=false',
'downsize_on_error=false',
]
return options
@classmethod
def command_v125(cls, jar_path='/data/local/tmp/scrcpy-server.jar') -> t.List[str]:
"""
Generate the commands to run scrcpy.
"""
commands = [
f'CLASSPATH={jar_path}',
'app_process',
'/',
'com.genymobile.scrcpy.Server',
'1.25',
]
commands += cls.arguments()
return commands
@classmethod
def command_v120(cls, jar_path='/data/local/tmp/scrcpy-server.jar') -> t.List[str]:
commands = [
f"CLASSPATH={jar_path}",
"app_process",
"/",
"com.genymobile.scrcpy.Server",
"1.20", # Scrcpy server version
"info", # Log level: info, verbose...
f"1280", # Max screen width (long side)
f"20000000", # Bitrate of video
f"{cls.frame_rate}", # Max frame per second
f"{const.LOCK_SCREEN_ORIENTATION_UNLOCKED}", # Lock screen orientation: LOCK_SCREEN_ORIENTATION
"true", # Tunnel forward
"-", # Crop screen
"false", # Send frame rate to client
"true", # Control enabled
"0", # Display id
"false", # Show touches
"false", # Stay awake
cls.codec_options(), # Codec (video encoding) options
"-", # Encoder name
"false", # Power off screen after server closed
]
return commands
if __name__ == '__main__':
print(' '.join(ScrcpyOptions.command_v120()))