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
Release files for mumu-python-api 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mumu_python_api-1.0.1.tar.gz | 34.1 kB | Details |
Release files / mumu_python_api-1.0.1.tar.gz
| Download URL | mumu_python_api-1.0.1.tar.gz |
|---|---|
| Size | 34.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
742f8d5b99a7f71235dcbf58671f76a1052cb7cf5a7721e89298ac1dac4e3978
|
|
BLAKE2b-256 checksum How to use checksums |
5534d5111a0f6e293d58f31a7566c7e614476ae470f674e565fa07288b82db8b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.0
|