Python API for controlling MuMu emulator through MuMuManager.exe
Project description
Mumu模拟器Python API
- Mumu模拟器Python API
项目介绍
该项目是基于MuMu提供的MuMuManager.exe实现的Python API,可以通过Python代码控制MuMu模拟器的大量操作。
该项目要求你已经安装了MuMu模拟器,且Mumu模拟器版本>=4.0.0以上。
如何使用?
将本项目安装到您的Python环境中
导入模块
from mumu.mumu import Mumu
设置MuMuManager路径
如果你的Mumu模拟器不是使用默认路径安装,则需要在创建Mumu对象时传入MuMuManager的路径。
默认路径C:\Program Files\Netease\MuMu Player 12\shell\MuMuManager.exe
from mumu.mumu import Mumu
Mumu(r'your_path').select(1)
模拟器索引说明
在Mumu模拟器种,操作模拟器通过索引,索引可以在创建时指定,也可以创建时自动分配,如果你不知道你的模拟器索引是多少,可以打开“Mumu多开器”,找到你的模拟器,最前面那个数字就是你的模拟器索引。
选择模拟器
如果指定的操作需要操作模拟器,可以通过select方法选择模拟器
from mumu.mumu import Mumu
mumu = Mumu().select(1)
对于选择多个模拟器时可以这样,一下4种方式都是等价的,均可以选择1、2、3号模拟器
from mumu.mumu import Mumu
# 第一种
mumu = Mumu().select([1, 2, 3])
# 第二种
mumu = Mumu().select(1, 2, 3)
# 第三种
mumu = Mumu().select((1, 2, 3))
# 也可以混合使用
mumu = Mumu().select([1, 2], 3)
如果希望选择所有模拟器,可以使用以下两种方法
from mumu.mumu import Mumu
# 第一种
mumu = Mumu().select() # 当select什么都不传时,默认选择所有模拟器
# 第二种:通过all方法选择所有模拟器
mumu = Mumu().all()
举个例子
我希望开启索引为1的模拟器的root权限,然后启动它。
from mumu.mumu import Mumu
# 选择索引为1的模拟器
mumu = Mumu().select(1)
# 开启Root权限
mumu.permission.root.enable()
# 启动模拟器
mumu.power.start()
注意
带*的类是本项目提供的超类,并不是MuMu模拟器的API原生提供。
API类
本项目提供了多个操作类,可以通过这些类实现对模拟器的控制。
驱动类(driver)
说明:具官方文档,目前仅支持网络桥接驱动。
网络桥接驱动(bride)
安装桥接驱动(install)
说明:安装桥接驱动需要管理员权限
Mumu().driver.bridge.install()
卸载桥接驱动(uninstall)
说明:卸载桥接驱动需要管理员权限
Mumu().driver.bridge.uninstall()
权限类(permission)
* ROOT权限(root)
开启ROOT权限(enable)
说明:开启ROOT权限需要在模拟器关机状态下进行
Mumu().select('your_index').permission.root.enable()
关闭ROOT权限(disable)
说明:关闭ROOT权限需要在模拟器关机状态下进行
Mumu().select('your_index').permission.root.disable()
电源类(power)
启动模拟器(start)
Mumu().select('your_index').power.start()
启动完成后打开指定包名的应用
Mumu().select('your_index').power.start('com.tencent.mobileqq')
关闭模拟器(shutdown|stop)
Mumu().select('your_index').power.shutdown()
# or
Mumu().select('your_index').power.stop()
重启模拟器(restart|reboot)
Mumu().select('your_index').power.restart()
# or
Mumu().select('your_index').power.reboot()
窗口类(window)
显示窗口(show)
Mumu().select('your_index').window.show()
隐藏窗口(hidden)
Mumu().select('your_index').window.hidden()
调整窗口大小或位置(layout)
该方法可以接受4个参数,分别是x坐标、y坐标、宽度、高度
Mumu().select('your_index').window.layout(0, 0, 800, 600)
如果只希望调整窗口的大小
Mumu().select('your_index').window.layout(None, None, 1080, 1920)
也可以只调整一个参数
Mumu().select('your_index').window.layout(300, None, None, None)
# or
Mumu().select('your_index').window.layout(None, None, 1080, None)
应用类(app)
安装一个应用(install)
该方法接受一个参数,即apk文件的路径,当apk路径无法访问时,会抛出FileNotFoundError异常
Mumu().select('your_index').app.install(r'C:\test.apk')
卸载一个应用(uninstall)
该方法接受一个参数,即应用的包名
Mumu().select('your_index').app.uninstall('com.miHoYo.Yuanshen')
启动模拟器里的应用(launch)
该方法接受一个参数,即应用的包名
# 启动原神
Mumu().select('your_index').app.launch('com.miHoYo.Yuanshen')
关闭模拟器里的应用(close)
该方法接受一个参数,即应用的包名
# 关闭原神
Mumu().select('your_index').app.close('com.miHoYo.Yuanshen')
* 判断应用是否存在(exists)
该方法接受一个参数,即应用的包名
# 判断原神是否存在
if (Mumu().select('your_index').app.exists('com.miHoYo.Yuanshen')):
print('原神已安装')
else:
print('原神未安装')
* 判断应用是否不存在(doesntExists)
该方法接受一个参数,即应用的包名
# 判断原神是否不存在
if (Mumu().select('your_index').app.doesntExists('com.miHoYo.Yuanshen')):
print('原神未安装')
else:
print('原神已安装')
获取已经安装的应用列表(get_installed)
# 获取已经安装的应用列表
Mumu().select(1).app.get_installed()
返回一个列表,当没有安装任何应用时,返回一个空列表
[
{
'package': 'com.miHoYo.Yuanshen', # 包名
'app_name': '原神', # 应用名称
'version': '4.1.8' # 版本号
},
]
* 获取应用状态(state)
该方法接受一个参数,即应用的包名,返回一个字符串,running表示应用正在运行,stopped表示应用未运行,not_installed表示应用未安装
# 获取原神的状态
Mumu().select('your_index').app.state('com.miHoYo.Yuanshen')
核心类(core)
创建模拟器(create)
该方法接受一个参数,即模拟器的名称,返回一个list包含所创建的模拟器索引
举例:创建一个模拟器
Mumu().core.create()
举例:创建5个模拟器
Mumu().core.create(5)
举例:创建一个索引为10的模拟器
Mumu().select(10).core.create()
从索引3开始创建5个模拟器
Mumu().select(3).core.create(5)
从索引 3,20 开始,分别创建10次模拟器,索引依次递增(即创建3-12,20-29索引的模拟器)
Mumu().select(3, 20).core.create(10)
克隆模拟器(clone)
该方法接受一个参数,即为克隆的数量,但是调用该方法前需要先选择一个模拟器,返回一个list包含所创建的模拟器索引
举例:克隆索引为2的模拟器
Mumu().select(2).core.clone()
举例:复制索引为 2,4,6 的模拟器
Mumu().select(2, 4, 6).core.clone()
举例:复制索引为2的模拟器,复制10次
Mumu().select(2).core.clone(10)
举例:复制所有模拟器
Mumu().all().core.clone()
删除模拟器(delete)
该方法不需要传入参数,但是调用该方法前需要先选择一个模拟器,返回bool值,表示是否删除成功
举例:删除索引为2的模拟器
if Mumu().select(2).core.delete():
print('删除成功')
举例:删除索引为2,4,6的模拟器
Mumu().select(2, 4, 6).core.delete()
举例:删除所有模拟器(危险操作)
Mumu().all().core.delete()
重命名模拟器(rename)
该方法接受一个参数,即为新的模拟器名称,但是调用该方法前需要先选择一个模拟器,返回bool值,表示是否重命名成功。
举例:重命名索引为2的模拟器为“测试”
if Mumu().select(2).core.rename('测试'):
print('重命名成功')
举例:重命名索引为2,4,6的模拟器为“测试”
Mumu().select(2, 4, 6).core.rename('测试')
举例:重命名所有的模拟器为“测试”
Mumu().all().core.rename('测试')
备份模拟器(export)
该方法接受三个参数,调用该方法前需要先选择一个模拟器,返回bool值,表示是否备份成功。
| 参数 | 说明 |
|---|---|
| dir | 备份的路径 |
| name | 备份的名称 |
| zip | 是否使用zip压缩 |
举例:备份索引为2的模拟器到C盘目录 backup 下,名称为 test.mumudata,以非压缩的格式
if Mumu().select(2).core.export(r'C:\backup', 'test'):
print('备份成功')
举例:备份索引为2,4,6的模拟器到C盘目录 backup 下,文件名基于 test 自动加后缀,以非压缩的格式
Mumu().select(2, 4, 6).core.export(r'C:\backup', 'test')
举例:备份所有的模拟器到C盘目录 backup 下,文件名基于 test 自动加后缀,以压缩的格式
Mumu().all().core.export(r'C:\backup', 'test', True)
导入模拟器(import_)
该方法接受一个参数,即为备份文件的路径,如果传入一个列表,则表示导入多个,调用该方法前需要先选择一个模拟器,返回bool值,表示是否导入成功。
举例:导入C盘下的 test.mumudata 并创建模拟器
if Mumu().select(2).core.import_(r'C:\test.mumudata'):
print('导入成功')
举例:导入C盘下的 test.mumudata 并创建模拟器,导入10次
Mumu().select(2).core.import_(r'C:\test.mumudata', 10)
举例:导入C盘下的 test.mumudata 和D盘下的 test2.mumudata 并创建模拟器,分别导入10次
Mumu().select(2).core.import_([r'C:\test.mumudata', r'D:\test2.mumudata'], 10)
限制CPU使用率(limit_cpu)
该方法接受一个参数,即为CPU使用率,调用该方法前需要先选择一个模拟器,返回bool值,表示是否设置成功。
举例:在索引为2的模拟器中限制CPU为50%
Mumu().select(2).core.limit_cpu(50)
举例:在索引为2,4,6的模拟器中限制CPU为50%
Mumu().select(2, 4, 6).core.limit_cpu(50)
举例:在所有模拟器中限制CPU为50%
Mumu().all().core.limit_cpu(50)
安卓事件类(androidEvent)
该类提供了安卓事件操作,可以通过该类实现对模拟器的操作。
调用类的所有方法前需要先选择一个模拟器,返回bool值,表示是否操作成功。 方法未特殊说明时,均无需传入参数。
屏幕旋转(rotate)
Mumu().select(1).androidEvent.rotate()
返回主页(go_home)
Mumu().select(1).androidEvent.go_home()
返回(back)
Mumu().select(1).androidEvent.go_back()
窗口置顶(top_most)
Mumu().select(1).androidEvent.top_most()
窗口全屏(fullscreen)
Mumu().select(1).androidEvent.fullscreen()
摇一摇(shake)
Mumu().select(1).androidEvent.shake()
截图(screenshot)
Mumu().select(1).androidEvent.screenshot()
音量增加(volume_up)
Mumu().select(1).androidEvent.volume_up()
音量减少(volume_down)
Mumu().select(1).androidEvent.volume_down()
音量静音(volume_mute)
Mumu().select(1).androidEvent.volume_mute()
任务键(go_task)
Mumu().select(1).androidEvent.go_task()
修改虚拟定位(location)
该方法接受两个参数,分别是经度和纬度
举例:在索引为2的模拟器中修改虚拟定位为经度114.1,纬度-23
Mumu().select(2).androidEvent.location(114.1, -23)
举例: 在索引为2,4,6的模拟器中修改虚拟定位为经度114.1,纬度-23
Mumu().select(2, 4, 6).androidEvent.location(114.1, -23)
举例:在所有模拟器中修改虚拟定位为经度114.1,纬度-23
Mumu().all().androidEvent.location(114.1, -23)
修改重力感应(gyro)
该方法接受三个参数,分别是x轴、y轴、z轴
举例:在索引为2的模拟器中修改重力感应X=40,Y=20,Z=30
Mumu().select(2).androidEvent.gyro(40, 20, 30)
举例:在索引为2,4,6的模拟器中修改重力感应X=40,Y=20,Z=30
Mumu().select(2, 4, 6).androidEvent.gyro(40, 20, 30)
举例:在所有模拟器中修改重力感应X=40,Y=20,Z=30
Mumu().all().androidEvent.gyro(40, 20, 30)
快捷方式类(shortcut)
创建桌面快捷方式(create)
该方法接受三个参数,分别是快捷方式名称、快捷方式图标路径、应用包名
举例:在桌面创建索引为2的模拟器的快捷方式 test,图标用 C 盘的 test.ico,自动启动原神
Mumu().select(2).shortcut.create('test', r'C:\test.ico', 'com.miHoYo.Yuanshen')
举例:在桌面创建索引为2,4,6的模拟器的快捷方式 test,图标用 C 盘的 test.ico,自动启动原神
Mumu().select(2, 4, 6).shortcut.create('test', r'C:\test.ico', 'com.miHoYo.Yuanshen')
举例:在所有模拟器中创建快捷方式 test,图标用 C 盘的 test.ico,自动启动原神
Mumu().all().shortcut.create('test', r'C:\test.ico', 'com.miHoYo.Yuanshen')
删除桌面快捷方式(delete)
该方法无需传入参数,调用该方法前需要先选择一个模拟器,返回bool值,表示是否删除成功。
举例:删除索引为2的模拟器的快捷方式
Mumu().select(2).shortcut.delete()
举例:删除索引为2,4,6的模拟器的快捷方式
Mumu().select(2, 4, 6).shortcut.delete()
举例:删除所有模拟器的快捷方式
Mumu().all().shortcut.delete()
机型类(simulation)
该类提供了模拟器机型操作。这玩意非常的鸡肋!!
修改MAC地址(mac_address)
该方法接受一个参数,即为新的MAC地址,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
Mumu().select(1).simulation.mac_address('00:11:22:33:44:55')
举例:为索引为1的模拟器随机生成一个MAC地址,两种方式均可
from mumu.constant import MacAddress
# 第一种:传入一个MAC地址
Mumu().select(1).simulation.mac_address(MacAddress.random())
# 第二种:当不传入参数时,表示随机生成一个MAC地址
Mumu().select(1).simulation.mac_address()
修改IMEI(imei)
安卓12不允许应用获取IMEI
该方法接受一个参数,即为新的IMEI,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
Mumu().select(1).simulation.imei('123456789012345')
举例:为索引为1的模拟器随机生成一个IMEI,两种方式均可
from mumu.constant import IMEI
# 第一种:传入一个IMEI
Mumu().select(1).simulation.imei(IMEI.random())
# 第二种:当不传入参数时,表示随机生成一个IMEI
Mumu().select(1).simulation.imei()
修改IMSI(imsi)
安卓12不允许应用获取IMSI
该方法接受一个参数,即为新的IMSI,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
Mumu().select(1).simulation.imsi('460000000000000')
举例:为索引为1的模拟器随机生成一个IMSI,两种方式均可
from mumu.constant import IMSI
# 第一种:传入一个IMSI
Mumu().select(1).simulation.imsi(IMSI.random())
# 第二种:当不传入参数时,表示随机生成一个IMSI
Mumu().select(1).simulation.imsi()
修改Android ID(android_id)
该方法接受一个参数,即为新的Android ID,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
Mumu().select(1).simulation.android_id('1234567890123456')
举例:为索引为1的模拟器随机生成一个Android ID,两种方式均可
from mumu.constant import AndroidID
# 第一种:传入一个Android ID
Mumu().select(1).simulation.android_id(AndroidID.random())
# 第二种:当不传入参数时,表示随机生成一个Android ID
Mumu().select(1).simulation.android_id()
设置模拟器设备型号(model)
该方法接受一个参数,即为新的设备型号,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
Mumu().select(1).simulation.model('MI 10')
设置模拟器主板品牌(brand)
该方法接受一个参数,即为新的主板型号,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
Mumu().select(1).simulation.brand('Xiaomi')
设置模拟器硬件制造商(solution)
该方法接受一个参数,即为新的硬件型号,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
Mumu().select(1).simulation.solution('qcom')
设置模拟器手机号码(phone_number)
安卓12不允许应用获取手机号码
该方法接受一个参数,即为新的手机号码,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
Mumu().select(1).simulation.phone_number('18888888888')
举例:随机设置一个手机号码,两种方式均可
from mumu.constant import PhoneNumber
# 第一种:传入一个手机号码
Mumu().select(1).simulation.phone_number(PhoneNumber.random())
# 第二种:当不传入参数时,表示随机生成一个手机号码
Mumu().select(1).simulation.phone_number()
设置模拟器GPU型号(gpu_model)
该方法提供4个参数,选填一个即可。
举例:设置索引为1的模拟器的GPU型号为GeForce RTX 3090
Mumu().select(1).simulation.gpu_model('GeForce RTX 3090')
举例:设置索引为1的模拟器的GPU型号为高配
Mumu().select(1).simulation.gpu_model(top_model=True)
举例:设置索引为1的模拟器的GPU型号为低配
Mumu().select(1).simulation.gpu_model(low_model=True)
举例:设置索引为1的模拟器的GPU型号为中配
Memu().select(1).simulation.gpu_model(middle_model=True)
配置类(setting)
该类提供了模拟器配置文件操作。
在配置类中,不选择任何模拟器即操作全局配置(默认值)
获取模拟器配置所有配置项(all)
该方法提供一个参数all_writable,当传入True时,表示获取所有可写的配置项,当传入False时,表示获取所有配置项,返回一个字典,表示所有配置项的键值对。
举例:获取所有配置项
Mumu().select(1).setting.all()
举例:获取所有可写的配置项
Mumu().select(1).setting.all(True)
获取一个或多个配置项(get)
该方法接受一个或多个参数,表示要获取的配置项,当获取单个配置项时,返回一个字符串,当获取多个配置项时,返回一个字典,表示所有配置项的键值对。
举例:获取指定一个或多个配置(返回字符串)
value = Mumu().select(1).setting.get('window_size_fixed')
举例:获取多个配置项(返回字典)
dict_val = Mumu().select(1).setting.get('window_size_fixed', 'window_save_rect')
修改一个或多个配置(set)
该方法接受一个或多个参数,表示要设置的配置项,返回一个bool值,表示是否设置成功。
当传入参数的值为None时,表示还原默认值。
如果遇到需要写的配置键包含.或者-时,将.替换为两个_,-替换为三个_。
举例:修改索引为2的模拟器的配置 window_size_fixed 的值为 true
Mumu().select(2).setting.set(window_size_fixed=True)
举例:修改索引为2的模拟器的配置 window_size_fixed 的值为 false,配置 window_save_rect 的值为 true
Mumu().select(2).setting.set(window_size_fixed=False, window_save_rect=True)
修改索引为2的模拟器的还原配置 window_size_fixed 的值(将使用默认值)
Mumu().select(2).setting.set(window_size_fixed=None)
根据JSON文件内容修改配置(set_by_json)
该方法接受一个参数,即为JSON文件的路径,返回一个bool值,表示是否设置成功。
举例:
一个 utf8 格式 test.json 文件在C盘下,文件内容如下:
{
"window_save_rect": "true",
"window_size_fixed": "false"
}
修改索引为2的模拟器的配置,通过JSON文件方式修改。
Mumu().select(2).setting.set_by_json(r'C:\test.json')
*判断某个配置是否等于某个值(equal)
该方法接受两个参数,分别是配置项和值,返回一个bool值,表示是否相等。
举例:判断索引为2的模拟器的配置 window_size_fixed 是否等于 true
if Mumu().select(2).setting.equal('window_size_fixed', True):
print('相等')
else:
print('不相等')
*判断某个配置是否不等于某个值(not_equal)
该方法接受两个参数,分别是配置项和值,返回一个bool值,表示是否不相等。
举例:判断索引为2的模拟器的配置 window_size_fixed 是否不等于 true
if Mumu().select(2).setting.not_equal('window_size_fixed', True):
print('不相等')
else:
print('相等')
*判断某个配置等于某个值时,修改为另一个值(equal_then_set)
该方法接受三个参数,分别是配置项、值和新值,返回一个bool值,表示是否修改成功。
举例:判断索引为2的模拟器的配置 window_size_fixed 是否等于 true,如果相等则修改为 false
Mumu().select(2).setting.equal_then_set('window_size_fixed', True, False)
*判断某个配置不等于某个值时,修改为另一个值(not_equal_then_set)
该方法接受三个参数,分别是配置项、值和新值,返回一个bool值,表示是否修改成功。
当不传入新值时,将自动设置值
举例:判断索引为2的模拟器的配置 window_size_fixed 是否不等于 true,如果不相等则修改为 true
Mumu().select(2).setting.not_equal_then_set('window_size_fixed', True, True)
# or
Mumu().select(2).setting.not_equal_then_set('window_size_fixed', True)
*屏幕类(screen)
该类提供了模拟器屏幕操作。
调整模拟器分辨率(resolution)
该方法接受两个参数,分别是宽度和高度,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
举例:修改索引为2的模拟器的分辨率为 800x600
Mumu().select(2).screen.resolution(800, 600)
设置为手机分辨率(resolution_mobile)
该方法不需要传入参数,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
该方法调整的分辨率为 1080x1920 DPI 为 480
举例:设置索引为2的模拟器的分辨率为手机分辨率
Mumu().select(2).screen.resolution_mobile()
设置为平板分辨率(resolution_tablet)
该方法不需要传入参数,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
该方法调整的分辨率为 1920x1080 DPI 为 280
举例:设置索引为2的模拟器的分辨率为平板分辨率
Mumu().select(2).screen.resolution_tablet()
设置为超宽屏分辨率(resolution_ultrawide)
该方法不需要传入参数,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
该方法调整的分辨率为 3200x1440 DPI 为 400
举例:设置索引为2的模拟器的分辨率为超宽屏分辨率
Mumu().select(2).screen.resolution_ultrawide()
调整模拟器DPI(dpi)
该方法接受一个参数,即为新的DPI,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
举例:修改索引为2的模拟器的DPI为 240
Mumu().select(2).screen.dpi(240)
调整模拟器亮度(brightness)
该方法接受一个参数,即为新的亮度,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
参数范围为0-100
举例:修改索引为2的模拟器的亮度为 50
Mumu().select(2).screen.brightness(50)
调整模拟器最大帧率(max_frame_rate)
该方法接受一个参数,即为新的最大帧率,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
参数范围为1-240
举例:修改索引为2的模拟器的最大帧率为 60
Mumu().select(2).screen.max_frame_rate(60)
# or
Mumu().select(2).screen.max_frame_rate() # 缺省值为60
设置动态调整帧率(dynamic_adjust_frame_rate)
该方法接受两个参数,分别是enable和dynamic_low_frame_rate_limit,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
| 参数 | 类型 | 说明 |
|---|---|---|
| enable | bool | 是否启用动态调整帧率 |
| dynamic_low_frame_rate_limit | int | 模拟器不是操作主窗口时,降低至的帧率,默认:15 |
举例:启用索引为2的模拟器的动态调整帧率,降低至15帧
Mumu().select(2).screen.dynamic_adjust_frame_rate(True, 15)
举例:禁用索引为2的模拟器的动态调整帧率
Mumu().select(2).screen.dynamic_adjust_frame_rate(False)
设置垂直同步(vertical_sync)
该方法接受一个参数,即为enable,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
举例:启用索引为2的模拟器的垂直同步
Mumu().select(2).screen.vertical_sync(True)
举例:禁用索引为2的模拟器的垂直同步
Mumu().select(2).screen.vertical_sync(False)
显示帧率(show_frame_rate)
该方法接受一个参数,即为enable,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
举例:启用索引为2的模拟器的显示帧率
Mumu().select(2).screen.show_frame_rate(True)
举例:禁用索引为2的模拟器的显示帧率
Mumu().select(2).screen.show_frame_rate(False)
设置窗口自动旋转(window_auto_rotate)
该方法接受一个参数,即为enable,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
设置后,模拟器窗口会根据运行的应用自动旋转
举例:启用索引为2的模拟器的窗口自动旋转
Mumu().select(2).screen.window_auto_rotate(True)
举例:禁用索引为2的模拟器的窗口自动旋转
Mumu().select(2).screen.window_auto_rotate(False)
性能类(performance)
该类提供了模拟器性能操作。
该类的所有操作需要重启模拟器后生效。
设置CPU和内存(set)
该方法接受两个参数,分别是CPU个数和内存大小,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
CPU个数范围为1-16
内存大小范围为1-16,单位为GB,不支持小数
举例:设置索引为2的模拟器的CPU为4核,内存为4GB
Mumu().select(2).performance.set(4, 4)
设置CPU个数(cpu)
该方法接受一个参数,即为CPU个数,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
CPU个数范围为1-16
举例:设置索引为2的模拟器的CPU为4核
Mumu().select(2).performance.cpu(4)
设置内存大小(memory)
该方法接受一个参数,即为内存大小,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
内存大小范围为1-16,单位为GB,不支持小数
举例:设置索引为2的模拟器的内存为4GB
Mumu().select(2).performance.memory(4)
设置强制使用独立显卡(force_discrete_graphics)
该方法接受一个参数,即为enable,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
举例:启用索引为2的模拟器的强制使用独立显卡
Mumu().select(2).performance.force_discrete_graphics(True)
举例:禁用索引为2的模拟器的强制使用独立显卡
Mumu().select(2).performance.force_discrete_graphics(False)
显存使用策略(renderer_strategy)
该方法接受三个参数,选择一个即可。
举例:设置索引为2的模拟器的显存使用策略为自动
Mumu().select(2).performance.renderer_strategy(auto=True)
# or
Mumu().select(2).performance.renderer_strategy()
举例:设置索引为2的模拟器的显存使用策略为资源占用更小
Mumu().select(2).performance.renderer_strategy(perf=True)
举例:设置索引为2的模拟器的显存使用策略为画面表现更好
Mumu().select(2).performance.renderer_strategy(dis=True)
设置磁盘类型(disk_readonly)
该方法接受一个参数,即为enable,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
enable缺省值为True,开启时,磁盘类型为(只读系统盘,官方推荐),关闭时,磁盘类型为(可写系统盘)
本方法提供一个助手方法disk_writable,用于设置磁盘类型为可写系统盘。
举例:设置索引为2的模拟器的磁盘类型为只读系统盘。
Mumu().select(2).performance.disk_readonly(True)
# or
Mumu().select(2).performance.disk_readonly()
举例:设置索引为2的模拟器的磁盘类型为可写系统盘
Mumu().select(2).performance.disk_readonly(False)
# or
Mumu().select(2).performance.disk_writable()
*网络类(network)
该类提供了模拟器网络操作。
获取所有可被桥接的网卡(get_bridge_card)
该方法返回一个列表,表示所有可被桥接的网卡。
举例:获取所有可被桥接的网卡
Mumu().select(1).network.get_bridge_card()
示例返回:
['Realtek Gaming GbE Family Controller', 'Sangfor SSL VPN CS Support System VNIC', 'Microsoft KM-TEST 环回适配器',
'Intel(R) Wi-Fi 6E AX211 160MHz']
设置网络桥接模式(bridge)
该方法接受两个参数,分别代表是否启用和网卡名称,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
该方法需要安装“桥接驱动”才能使用。
举例:启用索引为2的模拟器的网络桥接模式,网卡名称为Realtek Gaming GbE Family Controller
Mumu().select(2).network.bridge(True, 'Realtek Gaming GbE Family Controller')
举例:禁用索引为2的模拟器的网络桥接模式
Mumu().select(2).network.bridge(False)
设置网络为NAT模式(nat)
该方法无需传入参数,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
举例:设置索引为2的模拟器的网络为NAT模式
Mumu().select(2).network.nat()
设置桥接模式IP设置方式为DHCP(bridge_dhcp)
该方法无需传入参数,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
举例:设置索引为2的模拟器的桥接模式IP设置方式为DHCP
Mumu().select(2).network.bridge_dhcp()
设置桥接模式IP设置方式为静态(bridge_static)
该方法接受5个参数,分别是IP地址、子网掩码、网关、DNS1、DNS2,调用该方法前需要先选择一个模拟器,返回bool值,表示是否修改成功。
当不填写DNS时,默认DNS1为8.8.8.8,DNS2为114.114.114.114
举例:设置索引为2的模拟器的桥接模式IP设置方式为静态,IP地址为192.168.10.10,子网掩码为255.255.255.0
,网关为192.168.10.1
Mumu().select(2).network.bridge_static('192.168.10.10', '255.255.255.0', '192.168.10.1')
ADB类(adb)
该类提供了ADB操作。
获取模拟器的ADB连接信息(get_connect_info)
该无需传入参数,调用该方法前需要先选择一个模拟器,当选择一个模拟器时返回一个元组,包含IP和端口,当选择多个模拟器时返回一个字典,键为索引,值为IP和端口。
如果选择的模拟器无法获取到ADB连接信息,将返回None,None
举例:获取索引为2的模拟器的ADB连接信息
adb_ipaddr, adb_port = Mumu().select(2).adb.get_connect_info()
举例:获取索引为2,4,6的模拟器的ADB连接信息
adb_info = Mumu().select(2, 4, 6).adb.get_connect_info()
返回示例
{'2': ('172.30.20.123', 16416), '4': (None, None), '6': (None, None)}
点击屏幕(click)
该方法接受两个参数,分别是X坐标和Y坐标,调用该方法前需要先选择一个模拟器,返回bool值,表示是否点击成功。
举例:点击索引为2的模拟器的坐标为(100, 100)的位置
Mumu().select(2).adb.click(100, 100)
举例:点击索引为2,4,6的模拟器的坐标为(100, 100)的位置
Mumu().select(2, 4, 6).adb.click(100, 100)
滑动屏幕(swipe)
该方法提供5个参数,分别是起始X坐标、起始Y坐标、结束X坐标、结束Y坐标和滑动时间,调用该方法前需要先选择一个模拟器,返回bool值,表示是否滑动成功。
举例:滑动索引为2的模拟器的坐标为(100, 100)到(200, 200)的位置,时间为500ms
Mumu().select(2).adb.swipe(100, 100, 200, 200, 500)
# or
Mumu().select(2).adb.swipe(100, 100, 200, 200) # 缺省值为500ms
举例:滑动索引为2,4,6的模拟器的坐标为(100, 100)到(200, 200)的位置,时间为500ms
Mumu().select(2, 4, 6).adb.swipe(100, 100, 200, 200, 500)
文本输入(input_text)
该方法接受一个参数,即为要输入的文本,调用该方法前需要先选择一个模拟器,返回bool值,表示是否输入成功。
举例:在索引为2的模拟器中输入文本Hello World
Mumu().select(2).adb.input_text('Hello World')
举例:在索引为2,4,6的模拟器中输入文本Hello World
Mumu().select(2, 4, 6).adb.input_text('Hello World')
模拟按键(key_event)
该方法接受一个参数,即为要模拟的按键,调用该方法前需要先选择一个模拟器,返回bool值,表示是否模拟成功。
举例:在索引为2的模拟器中模拟按键HOME
Mumu().select(2).adb.key_event(3)
举例:通过本项目提供的按键常量模拟按键HOME
from mumu.constant import AndroidKey
Mumu().select(2).adb.key_event(AndroidKey.KEYCODE_HOME)
举例:在索引为2,4,6的模拟器中模拟音量+
from mumu.constant import AndroidKey
Mumu().select(2, 4, 6).adb.key_event(AndroidKey.KEYCODE_VOLUME_UP)
上传文件(push)
该方法接受两个参数,分别是本地文件路径和模拟器文件路径,调用该方法前需要先选择一个模拟器,返回bool值,表示是否上传成功。
当上传失败时,会触发一个warning警告。
举例:上传索引为2的模拟器的本地文件C:\test.txt到模拟器的/sdcard/test.txt
Mumu().select(2).adb.push(r'C:\test.txt', '/sdcard/test.txt')
举例:上传索引为2,4,6的模拟器的本地文件C:\test.txt到模拟器的/sdcard/test.txt
Mumu().select(2, 4, 6).adb.push(r'C:\test.txt', '/sdcard/test.txt')
上传文件到Download目录(push_download)
该方法提供两个参数,分别是本地文件路径和模拟器文件名,调用该方法前需要先选择一个模拟器,返回bool值,表示是否上传成功。
当模拟器文件名为None时,将自动使用本地文件名。
举例:上传索引为2的模拟器的本地文件C:\test.txt到模拟器的Download目录
Mumu().select(2).adb.push_download(r'C:\test.txt')
举例:上传索引为2,4,6的模拟器的本地文件C:\test.txt到模拟器的Download目录,重命名为:test1.txt
Mumu().select(2, 4, 6).adb.push_download(r'C:\test.txt', 'test1.txt')
下载文件(pull)
该方法提供两个参数,分别是模拟器文件路径和本地文件路径,调用该方法前需要先选择一个模拟器,返回bool值,表示是否下载成功。
当下载失败时,会触发一个warning警告。
举例:下载索引为2的模拟器的模拟器文件/sdcard/test.txt到本地的C:\test.txt
Mumu().select(2).adb.pull('/sdcard/test.txt', r'C:\test.txt')
清理应用数据(clear)
该方法接受一个参数,即为应用包名,调用该方法前需要先选择一个模拟器,返回bool值,表示是否清理成功。
如果包名错误会抛出异常
举例:清理索引为2的模拟器的应用数据
Mumu().select(2).adb.clear('com.miHoYo.Yuanshen')
GUI自动化类(auto)
本类提供了模拟器的GUI自动化操作,例如:通过图片定位、坐标定位、文字定位实现自动化操作。
先决条件:需要安装opencv-python库,可以通过pip install opencv-python安装。
如果希望使用本项目自带的投屏功能,需要安装scrcpy,可以通过pip install scrcpy-client安装。
处理模拟器实时帧(create_handle)
该方法接受一个参数handle,传入一个方法,用于处理模拟器的帧。
该方法基于scrcpy实现,如果您的应用对该软件有限制,请勿使用。
使用该方法,会自动创建2个子线程,一个用于接收模拟器的帧,一个用于处理帧。
handle方法包含两个参数frame和mumu,分别表示帧和当前模拟器对象。
frame为numpy数组,可以直接使用opencv的方法处理。
mumu为当前模拟器对象,仅选中了当前模拟器。
举例:处理索引为2的模拟器的帧
def handle(frame, mumu):
# do something
print('接收到模拟器:', mumu.core.utils.get_vm_id(), '的帧')
Mumu().select(2).auto.create_handle(handle)
举例:处理索引为2,4,6的模拟器的帧
def handle(frame, mumu):
# do something
print('接收到模拟器:', mumu.core.utils.get_vm_id(), '的帧')
Mumu().select(2, 4, 6).auto.create_handle(handle)
保存模拟器实时帧(save)
该方法接受两个参数,分别为frame和path,用于保存模拟器的帧。
举例:保存帧到C:\test.png
def handle(frame, mumu):
mumu.auto.save(frame, r'C:\test.png')
Mumu().select(2).auto.create_handle(handle)
举例:保存索引为3的模拟器的帧到C:\test.png
def handle(frame, mumu):
if mumu.core.utils.get_vm_id() == '3':
mumu.auto.save(frame, r'C:\test.png')
Mumu().select(2, 3).auto.create_handle(handle)
在帧中查找第一个图片(locateOnScreen)
该方法接受4个参数,分别为haystack、needle、confidence和grayscale,用于在帧中查找图片。
confidence为相似度,范围为0-1,缺省值为0.8
grayscale为是否使用灰度查找,缺省值为`False
举例:在帧中查找图片C:\test.png
def handle(frame, mumu):
# do something
print('接收到模拟器:', mumu.core.utils.get_vm_id(), '的帧')
pos = mumu.auto.locateOnScreen(frame, r'C:\test.png')
if pos:
print('找到图片:', pos)
else:
print('未找到图片')
在帧中查找第一张图片的中心点(locateCenterOnScreen)
该方法接受4个参数,分别为haystack、needle、confidence和grayscale,用于在帧中查找图片。
confidence为相似度,范围为0-1,缺省值为0.8
grayscale为是否使用灰度查找,缺省值为`False
def handle(frame, mumu):
# do something
print('接收到模拟器:', mumu.core.utils.get_vm_id(), '的帧')
pos = mumu.auto.locateCenterOnScreen(frame, r'C:\test.png')
if pos:
print('找到图片中心点:', pos)
else:
print('未找到图片')
在帧中查找所有图片(locateAllOnScreen)
该方法接受4个参数,分别为haystack、needle、confidence和grayscale,用于在帧中查找图片。
confidence为相似度,范围为0-1,缺省值为0.8
grayscale为是否使用灰度查找,缺省值为`False
def handle(frame, mumu):
# do something
print('接收到模拟器:', mumu.core.utils.get_vm_id(), '的帧')
pos = mumu.auto.locateAllOnScreen(frame, r'C:\test.png')
if pos:
print('找到图片:', pos)
else:
print('未找到图片')
获取Box的中心点(center)
该方法接受一个参数,即为box,用于获取Box的中心点,返回x和y
box为一个元组,包含4个元素,分别为左上角x、左上角y、右下角x、右下角y
def handle(frame, mumu):
# do something
print('接收到模拟器:', mumu.core.utils.get_vm_id(), '的帧')
pos = mumu.auto.locateOnScreen(frame, r'C:\test.png')
if pos:
print('找到图片:', pos)
x, y = mumu.auto.center(pos)
print('中心点:', x, y)
else:
print('未找到图片')
实战举例
监听模拟器3的帧,当帧中出现test.png时,返回找到了,并返回当前时间和模拟器ID,然后返回到桌面。
def handle(frame, mumu: Mumu):
if mumu.auto.locateOnScreen(frame, './test.png', confidence=0.75, grayscale=True):
print("找到了", time.time(), '在模拟器', mumu.core.utils.get_vm_id())
mumu.androidEvent.go_home()
Mumu().select(3).auto.create_handle(handle)
支持本项目
作者:wlkjyy
Mail:wlkjyy@vip.qq.com
WeCHAT:laravel_debug
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mumu_python_api_wlkjyy-1.1.0.tar.gz.
File metadata
- Download URL: mumu_python_api_wlkjyy-1.1.0.tar.gz
- Upload date:
- Size: 62.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d42b4a612684afcdd9143f2e894dceb27edcca067db7935ad0cdd6081fc3dfe
|
|
| MD5 |
e08d42c9d0f4b96ca0944557fc244d4d
|
|
| BLAKE2b-256 |
8cb39d183b4474bd6baaa0b01f00be2695ef49936af7fc8b2c6b8132499a4ce4
|
File details
Details for the file mumu_python_api_wlkjyy-1.1.0-py3-none-any.whl.
File metadata
- Download URL: mumu_python_api_wlkjyy-1.1.0-py3-none-any.whl
- Upload date:
- Size: 41.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
20a453b688aedc13f4a895071c92d4f88e34537e308b989a22ecd866884ac10e
|
|
| MD5 |
532f6b20c2ec2922c6148eaaa384f781
|
|
| BLAKE2b-256 |
e1b1e886d31c9c9098843eb4c9909b0076f0cf177c5bbe330f026f49e3ab3d88
|