mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2026-01-08 12:52:11 +00:00
Compare commits
203 Commits
beewarewin
...
pysideP
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab3c55e7b7 | ||
|
|
082934d918 | ||
|
|
28d59f8be9 | ||
|
|
1103a06897 | ||
|
|
63499732eb | ||
|
|
be40f8f920 | ||
|
|
190ef70fc4 | ||
|
|
a74fd4b4de | ||
|
|
2ebdf6be24 | ||
|
|
9ca0788eb2 | ||
|
|
fba83ef968 | ||
|
|
68e019412d | ||
|
|
9734bf493a | ||
|
|
bde2b4e378 | ||
|
|
dc1efc9e84 | ||
|
|
b04c01772f | ||
|
|
88d36f94f0 | ||
|
|
8eda5c4736 | ||
|
|
37ccbe3dae | ||
|
|
be43e4a92a | ||
|
|
5929ae417d | ||
|
|
517c7db112 | ||
|
|
3ae456c4d1 | ||
|
|
b0af5f4950 | ||
|
|
1ccaa8e9aa | ||
|
|
75fabf9c37 | ||
|
|
95e34f5c7b | ||
|
|
5bb0227a7a | ||
|
|
9c9ebe0a08 | ||
|
|
0b3a19faad | ||
|
|
6cde168bf3 | ||
|
|
451d1d8e80 | ||
|
|
085ab3f4c0 | ||
|
|
a16109f29a | ||
|
|
813186bef9 | ||
|
|
3921190832 | ||
|
|
c32b94592a | ||
|
|
77b7344277 | ||
|
|
0a17f8b8f8 | ||
|
|
f8d707ac11 | ||
|
|
ad7e047abc | ||
|
|
5ea47c54cb | ||
|
|
b20f350da4 | ||
|
|
5aaae83020 | ||
|
|
85e6340570 | ||
|
|
662c6506d8 | ||
|
|
ad2fcd6f14 | ||
|
|
5dde31d081 | ||
|
|
2e11a9949b | ||
|
|
3b53846ade | ||
|
|
96af5183ac | ||
|
|
59fd2645e4 | ||
|
|
33ce7ed8c8 | ||
|
|
14f7d6fd7e | ||
|
|
fb2fd13b21 | ||
|
|
5025cba356 | ||
|
|
abb53a7499 | ||
|
|
73854be7be | ||
|
|
6f6a77d0b4 | ||
|
|
e0a3399fed | ||
|
|
2afd6beb3f | ||
|
|
9517c49ec5 | ||
|
|
887452184b | ||
|
|
d36134e525 | ||
|
|
453ca745af | ||
|
|
7d814bcda2 | ||
|
|
55b933ac85 | ||
|
|
56fb029e75 | ||
|
|
c5a7dfb608 | ||
|
|
0a640267ff | ||
|
|
a6d7022f87 | ||
|
|
dcc62ca66d | ||
|
|
992572cbf1 | ||
|
|
ce1099a246 | ||
|
|
2340741bb9 | ||
|
|
3f0f714a7c | ||
|
|
65c23ca427 | ||
|
|
3b6cb3865f | ||
|
|
cae0b7f23d | ||
|
|
e1d4cd9933 | ||
|
|
3499c05eb4 | ||
|
|
259fb04980 | ||
|
|
8ce7a9fa83 | ||
|
|
affb5b5404 | ||
|
|
1805ab53c0 | ||
|
|
eda3a957cf | ||
|
|
4788d8949b | ||
|
|
8f6cc04780 | ||
|
|
6cb5c9ba89 | ||
|
|
ae83f9c21e | ||
|
|
dd34ac9998 | ||
|
|
2da06136c5 | ||
|
|
e9f4230a2d | ||
|
|
1b7ab73c02 | ||
|
|
2624c081bb | ||
|
|
87cc189da8 | ||
|
|
668bf480b2 | ||
|
|
4cc3f2678f | ||
|
|
701e9d5129 | ||
|
|
8dd2694e82 | ||
|
|
ac962f0ab7 | ||
|
|
b800384547 | ||
|
|
5da1041664 | ||
|
|
966ce515c3 | ||
|
|
349c255f5f | ||
|
|
cbb77086d0 | ||
|
|
280e50f4cb | ||
|
|
a2a37be8ef | ||
|
|
7acd6b7e38 | ||
|
|
4c95f76cf9 | ||
|
|
8a1a159eb8 | ||
|
|
cb43caef26 | ||
|
|
200167ef84 | ||
|
|
7e0a127406 | ||
|
|
5e70dd73a1 | ||
|
|
7229b12e99 | ||
|
|
074124bc3d | ||
|
|
91446bfd81 | ||
|
|
5011efcdee | ||
|
|
3b4af19379 | ||
|
|
d3d89d2567 | ||
|
|
441d1e9982 | ||
|
|
77e738cb7e | ||
|
|
46b6884e64 | ||
|
|
d0a63d0f8e | ||
|
|
887394570b | ||
|
|
c62806d470 | ||
|
|
d21c26d632 | ||
|
|
26ec42a71d | ||
|
|
245e2fa1ec | ||
|
|
e70fc806be | ||
|
|
72a3715722 | ||
|
|
fd3d27d596 | ||
|
|
3d283bfded | ||
|
|
7d9b63b9fe | ||
|
|
82850a3d74 | ||
|
|
629cfa402b | ||
|
|
0818957f51 | ||
|
|
954a30f722 | ||
|
|
96e6bc2f7a | ||
|
|
ca0e56e771 | ||
|
|
8fe71dbe0d | ||
|
|
97f334789e | ||
|
|
d2a6ce2529 | ||
|
|
066e0b0cac | ||
|
|
052142ac08 | ||
|
|
59c481f6da | ||
|
|
53c17f0328 | ||
|
|
ed28fc4866 | ||
|
|
320114533d | ||
|
|
aa210ac678 | ||
|
|
c4dd7b1ce8 | ||
|
|
99509be48c | ||
|
|
073ae827ab | ||
|
|
58b312554d | ||
|
|
55eeddb108 | ||
|
|
9d4a75cd41 | ||
|
|
882ce96b90 | ||
|
|
9093a66639 | ||
|
|
b48a66115a | ||
|
|
db20a87ae9 | ||
|
|
69eebd25a9 | ||
|
|
89ef3bcb55 | ||
|
|
f08a2ff9be | ||
|
|
9f8694ef14 | ||
|
|
81272a1166 | ||
|
|
a83052bd5d | ||
|
|
2fcfdca0a0 | ||
|
|
bcaeb129a5 | ||
|
|
36b639f029 | ||
|
|
4b241dfc0b | ||
|
|
255cc84ef3 | ||
|
|
c04b622297 | ||
|
|
b6a63a794e | ||
|
|
7c0dd218b2 | ||
|
|
19bbb92cff | ||
|
|
26ee16f071 | ||
|
|
05eb0c05ec | ||
|
|
5d2e0582c3 | ||
|
|
d3e0f78d2c | ||
|
|
79a2dfb5b1 | ||
|
|
bf3367c7e4 | ||
|
|
c91f5cf2f9 | ||
|
|
d8ea747ef1 | ||
|
|
39148a6c76 | ||
|
|
0e3eb394ab | ||
|
|
f0dedabe1a | ||
|
|
dda78ab35f | ||
|
|
5b6ff5ee68 | ||
|
|
fcb1a25227 | ||
|
|
81eb8e5376 | ||
|
|
7e13b22d46 | ||
|
|
07e153f215 | ||
|
|
908f622433 | ||
|
|
5f7ca0859f | ||
|
|
32ae868c34 | ||
|
|
ce441e4905 | ||
|
|
3dc099af7e | ||
|
|
cf7e51595e | ||
|
|
737b2d5f07 | ||
|
|
143de0bb37 | ||
|
|
17f9fa7ffc | ||
|
|
1bc1c6485b |
172
.gitignore
vendored
172
.gitignore
vendored
@@ -1,38 +1,20 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
# sth. can't open
|
||||
/msctPkgver/secrets/*.py
|
||||
/msctPkgver/secrets/*.c
|
||||
|
||||
|
||||
# mystuff
|
||||
/.vscode
|
||||
*.mid
|
||||
*.midi
|
||||
|
||||
# Byte-compiled / optimized
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.pyc
|
||||
*$py.class
|
||||
|
||||
# OSX useful to ignore
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
@@ -44,23 +26,123 @@ lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# IntelliJ Idea family of suites
|
||||
.idea
|
||||
*.iml
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
## mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Briefcase build directories
|
||||
iOS/
|
||||
macOS/
|
||||
windows/
|
||||
android/
|
||||
linux/
|
||||
django/
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# Pycharm
|
||||
/.idea
|
||||
|
||||
88
1.py
Normal file
88
1.py
Normal file
@@ -0,0 +1,88 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file '1.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.4.1
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QMainWindow, QMenuBar, QSizePolicy,
|
||||
QStatusBar, QTabWidget, QToolButton, QVBoxLayout,
|
||||
QWidget)
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
if not MainWindow.objectName():
|
||||
MainWindow.setObjectName(u"MainWindow")
|
||||
MainWindow.resize(800, 600)
|
||||
self.centralwidget = QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.verticalLayoutWidget_2 = QWidget(self.centralwidget)
|
||||
self.verticalLayoutWidget_2.setObjectName(u"verticalLayoutWidget_2")
|
||||
self.verticalLayoutWidget_2.setGeometry(QRect(0, 0, 861, 681))
|
||||
self.verticalLayout_2 = QVBoxLayout(self.verticalLayoutWidget_2)
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.tabWidget = QTabWidget(self.verticalLayoutWidget_2)
|
||||
self.tabWidget.setObjectName(u"tabWidget")
|
||||
self.tab = QWidget()
|
||||
self.tab.setObjectName(u"tab")
|
||||
self.toolButton_2 = QToolButton(self.tab)
|
||||
self.toolButton_2.setObjectName(u"toolButton_2")
|
||||
self.toolButton_2.setGeometry(QRect(30, 10, 24, 22))
|
||||
self.tabWidget.addTab(self.tab, "")
|
||||
self.tab_2 = QWidget()
|
||||
self.tab_2.setObjectName(u"tab_2")
|
||||
self.tabWidget.addTab(self.tab_2, "")
|
||||
|
||||
self.verticalLayout_2.addWidget(self.tabWidget)
|
||||
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QMenuBar(MainWindow)
|
||||
self.menubar.setObjectName(u"menubar")
|
||||
self.menubar.setGeometry(QRect(0, 0, 800, 26))
|
||||
MainWindow.setMenuBar(self.menubar)
|
||||
self.statusbar = QStatusBar(MainWindow)
|
||||
self.statusbar.setObjectName(u"statusbar")
|
||||
MainWindow.setStatusBar(self.statusbar)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
self.toolButton_2.clicked.connect(self.toolButton_2.click)
|
||||
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow)
|
||||
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
|
||||
self.toolButton_2.setText(QCoreApplication.translate("MainWindow", u"...", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),
|
||||
QCoreApplication.translate("MainWindow", u"Tab 1", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),
|
||||
QCoreApplication.translate("MainWindow", u"Tab 2", None))
|
||||
# retranslateUi
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
from PySide6 import QtWidgets
|
||||
|
||||
app = QtWidgets.QApplication(sys.argv) # 创建一个QApplication,也就是你要开发的软件app
|
||||
MainWindow = QtWidgets.QMainWindow() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
# MainWindow = QtWidgets.QWidget() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
ui = Ui_MainWindow() # ui是你创建的ui类的实例化对象
|
||||
ui.setupUi(MainWindow) # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
|
||||
MainWindow.show() # 执行QMainWindow的show()方法,显示这个QMainWindow
|
||||
sys.exit(app.exec_()) # 使用exit()或者点击关闭按钮退出QApplication
|
||||
91
1.ui
Normal file
91
1.ui
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QWidget" name="verticalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>861</width>
|
||||
<height>681</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Tab 1</string>
|
||||
</attribute>
|
||||
<widget class="QToolButton" name="toolButton_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>10</y>
|
||||
<width>24</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Tab 2</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>toolButton_2</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>toolButton_2</receiver>
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>44</x>
|
||||
<y>76</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>46</x>
|
||||
<y>71</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1,201 +1,219 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
**注意,以下条款或版权声明应当且必须是高于此项目中任何其他声明的**
|
||||
|
||||
1. 音·创的全部开发者享有其完整版权,其开发者可以在任一时刻终止以后音·创源代码开放,若经由其开发者授予特殊权利,则授权对象可以将源代码进行特定的被特殊授权的操作
|
||||
2. 音·创或(及)其代码允许在 Apache2.0 协议的条款与说明下进行非商业使用
|
||||
3. 除部分代码特殊声明外,音·创允许对其或(及)其代码进行商业化使用,但是需要经过音·创主要开发者(诸葛亮与八卦阵、金羿)的一致授权,同时,授权对象在商业化授权的使用过程中必须依照 Apache2.0 协议的条款与说明
|
||||
4. 若存在对于音·创包含的部分代码的特殊开源声明,则此部分代码依照其特定的开源方式授权,但若此部分代码经由此部分代码的主要开发者一致特殊授权后商用,则授权对象在商用时依照此部分的开发者所准许的方式(或条款)进行商用,或默认依照 Apache2.0 协议进行商业化使用
|
||||
5. Apache2.0 协议的英文原文副本可见下文
|
||||
|
||||
> The English Translation of the TERMS AND CONDITIONS above is listed below
|
||||
>
|
||||
> This translated version is for reference only and has no legal effect.
|
||||
>
|
||||
> The version with legal effect is the Chinese version above.
|
||||
|
||||
**Note, The TERMS AND CONDITIONS below should and must be above all others in this project**
|
||||
|
||||
1. *Musicreater* is fully copyrighted by all its developers, the developers have the right to make *Musicreater* close sourced at any time. Operations are permitted under specific terms instructed by its developer(s).
|
||||
2. Non-commercial use of *Musicreater* and(or) its source code is permitted under Apache License 2.0.
|
||||
3. Commercial use of *Musicreater* is permitted under Apache License 2.0 with the unanimous permission of the steering developers of *Musicreater* (*bgArray*诸葛亮与八卦阵 and *Eilles*金羿).
|
||||
4. *Musicreater* is open sourced under priority given:
|
||||
1. License granted by the core developer(s) of a section after negotiation.
|
||||
2. Explicitly stated license.
|
||||
3. Apache 2.0 License.
|
||||
5. A copy of the original Apache Lisence 2.0 can be found below.
|
||||
|
||||
|
||||
```text
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
Copyright 2022 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
```
|
||||
532
PySide6-Pkg.ui
Normal file
532
PySide6-Pkg.ui
Normal file
@@ -0,0 +1,532 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>951</width>
|
||||
<height>611</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabO">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Tab 1</string>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>881</width>
|
||||
<height>591</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidget"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Tab 2</string>
|
||||
</attribute>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>71</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>30</y>
|
||||
<width>281</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>271</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>280</x>
|
||||
<y>30</y>
|
||||
<width>281</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>271</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget_3" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>160</y>
|
||||
<width>781</width>
|
||||
<height>191</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>781</width>
|
||||
<height>191</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>默认保存路径:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>速度倍率</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="horizontalSlider">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>音量倍率</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="horizontalSlider_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>最大指令生成高度</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_16">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>选择器模式</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_3"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>计分板名称</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>玩家选择器</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>bdx作者名称</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_2">
|
||||
<property name="text">
|
||||
<string>是否启用进度条</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string>是否自定义进度条</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>自定义进度条内容:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit_3">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_18"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择命令格式版本</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>选择转换算法版本</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_4"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_26">
|
||||
<property name="text">
|
||||
<string>选择导出模式</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_5"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>页</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>页</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu">
|
||||
<property name="title">
|
||||
<string>文件</string>
|
||||
</property>
|
||||
<addaction name="action"/>
|
||||
<addaction name="action_Input"/>
|
||||
</widget>
|
||||
<addaction name="menu"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<action name="action">
|
||||
<property name="icon">
|
||||
<iconset theme="document-open">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>打开 Open</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Input">
|
||||
<property name="text">
|
||||
<string>导入 Input</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
100
README.md
100
README.md
@@ -1,49 +1,79 @@
|
||||
# 音·创 Musicreater
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
### 介绍
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
<h2 align="center">库版 Package Version</h2>
|
||||
|
||||
欢迎加群:861684859
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
### 软件架构
|
||||
<p align="center">
|
||||
<img src="https://forthebadge.com/images/badges/built-with-love.svg">
|
||||
<p>
|
||||
|
||||
软件采用Python作为第一语言,目前还没有使用其他语言辅助。使用BeeWare作为图形库兼容安卓。
|
||||
[![][Bilibili: 凌云金羿]](https://space.bilibili.com/397369002/)
|
||||
[![][Bilibili: 诸葛亮与八卦阵]](https://space.bilibili.com/604072474)
|
||||
[![CodeStyle: black]](https://github.com/psf/black)
|
||||
[![][python]](https://www.python.org/)
|
||||
[![][license]](LICENSE)
|
||||
[![][release]](../../releases)
|
||||
|
||||
尽量全平台支持
|
||||
简体中文🇨🇳 | [English🇬🇧](README_EN.md)
|
||||
|
||||
## **嘿伙计,你是不是来错地儿了,这里还在开发,注意选对版本!**
|
||||
|
||||
## 介绍🚀
|
||||
|
||||
音·创 Musicreater 是一款免费开源的 **《我的世界:基岩版》** 音乐制作软件
|
||||
|
||||
音·创 库版 (Musicreater Package Version) 是一款免费开源的针对 **《我的世界:基岩版》** 的midi音乐转换库
|
||||
|
||||
欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
|
||||
|
||||
**此分支为音·创的包版本,即便于其他软件使用的可被import版本**
|
||||
|
||||
### **看这看这!看这看这!看这看这!教程:[教程链接](./docs/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)**
|
||||
|
||||
## 软件作者✒
|
||||
|
||||
金羿 Eilles:我的世界基岩版指令师,个人开发者,B站不知名UP主,江西在校高中生。
|
||||
|
||||
诸葛亮与八卦阵 bgArray:我的世界基岩版玩家,喜欢编程和音乐,深圳初二学生。
|
||||
|
||||
|
||||
### 安装教程
|
||||
|
||||
#### Windows
|
||||
## 致谢🙏
|
||||
|
||||
即将到来。
|
||||
- 感谢 **昀梦**\<QQ1515399885\> 找出指令生成错误bug并指正
|
||||
- 感谢由 **Charlie_Ping “查理平”** 带来的bdx文件转换参考,
|
||||
以及mid转我的世界乐器参考表格
|
||||
- 感谢由 **CMA_2401PT** 为我们的软件开发进行指导
|
||||
- 感谢由 **Dislink Sforza “断联·斯福尔扎”**\<QQ1600515314\>带来的midi音色解析以及转换指令的算法,我们将其改编并应用;同时,感谢他的[网页版转换器](https://dislink.github.io/midi2bdx/)给我们的开发与更新带来巨大的压力和动力,让我们在原本一骑绝尘的摸鱼道路上转向开发
|
||||
- 感谢 **Touch “偷吃”**\<QQ1793537164\>提供的测试支持,并对程序的改进提供了丰富的意见;同时也感谢他的不断尝试新的内容,使我们的排错更进一步
|
||||
- 感谢 **Mono**\<QQ738893087\>反馈安装时的问题
|
||||
- 感谢 **Ammelia** 敦促我们进行新的功能开发,并为新功能提出了非常优秀的大量建议
|
||||
|
||||
#### Linux
|
||||
> 感谢广大群友为此程序提供的测试等支持
|
||||
>
|
||||
> 若您对我们有所贡献但您的名字没有显示在此列表中,请联系我!
|
||||
|
||||
即将到来。
|
||||
## 联系我们📞
|
||||
|
||||
#### Android
|
||||
|
||||
即将到来。
|
||||
|
||||
### 使用说明
|
||||
|
||||
1. 直接运行就好
|
||||
2. 有不懂的问题来群里问
|
||||
3. 请理解英文表述
|
||||
|
||||
### 致谢
|
||||
|
||||
1. 感谢由 [Fuckcraft](https://github.com/fuckcraft) “鸣凤鸽子”等 带来的我的世界websocket服务器功能
|
||||
2. 感谢 昀梦<QQ1515399885> 找出指令生成错误bug并指正
|
||||
3. 感谢由 Charlie_Ping “查理平” 带来的bdx转换功能
|
||||
4. 感谢由 CMA_2401PT 提供的 BDXWorkShop作为.bdx结构的操作指导
|
||||
5. 感谢广大群友为此程序提供的测试等支持
|
||||
6. 若您为我找出了错误但您的名字没有显示在此列表中,请联系我!
|
||||
|
||||
|
||||
### 作者<金羿>联系方式
|
||||
### 作者\<*金羿*\>(Eilles)联系方式
|
||||
|
||||
1. QQ 2647547478
|
||||
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com
|
||||
3. 微信 WYI_DoctorYI
|
||||
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. 微信 WYI_DoctorYI
|
||||
4. Telegram [@EillesWan](https://t.me/EillesWan)
|
||||
|
||||
### 作者\<*诸葛亮与八卦阵*\>(bgArray)联系方式
|
||||
|
||||
1. QQ 4740437765
|
||||
|
||||
|
||||
|
||||
[Bilibili: 凌云金羿]: https://img.shields.io/badge/Bilibili-%E5%87%8C%E4%BA%91%E9%87%91%E7%BE%BF-00A1E7?style=for-the-badge
|
||||
[Bilibili: 诸葛亮与八卦阵]: https://img.shields.io/badge/Bilibili-%E8%AF%B8%E8%91%9B%E4%BA%AE%E4%B8%8E%E5%85%AB%E5%8D%A6%E9%98%B5-00A1E7?style=for-the-badge
|
||||
[CodeStyle: black]: https://img.shields.io/badge/code%20style-black-121110.svg?style=for-the-badge
|
||||
[python]: https://img.shields.io/badge/python-3.6-AB70FF?style=for-the-badge
|
||||
[release]: https://img.shields.io/github/v/release/EillesWan/Musicreater?style=for-the-badge
|
||||
[license]: https://img.shields.io/badge/Licence-Apache-228B22?style=for-the-badge
|
||||
|
||||
12
README.rst
12
README.rst
@@ -1,12 +0,0 @@
|
||||
Musicreater
|
||||
===========
|
||||
|
||||
**This cross-platform app was generated by** `Briefcase`_ **- part of**
|
||||
`The BeeWare Project`_. **If you want to see more tools like Briefcase, please
|
||||
consider** `becoming a financial member of BeeWare`_.
|
||||
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
|
||||
.. _`Briefcase`: https://github.com/beeware/briefcase
|
||||
.. _`The BeeWare Project`: https://beeware.org/
|
||||
.. _`becoming a financial member of BeeWare`: https://beeware.org/contributing/membership
|
||||
74
README_EN.md
Normal file
74
README_EN.md
Normal file
@@ -0,0 +1,74 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://forthebadge.com/images/badges/built-with-love.svg">
|
||||
<p>
|
||||
|
||||
[![][Bilibili: Eilles]](https://space.bilibili.com/397369002/)
|
||||
[![][Bilibili: bgArray]](https://space.bilibili.com/604072474)
|
||||
[![CodeStyle: black]](https://github.com/psf/black)
|
||||
![][python]
|
||||
[![][license]](LICENSE)
|
||||
[![][release]](../../releases)
|
||||
|
||||
[简体中文🇨🇳](README.md) | English🇬🇧
|
||||
|
||||
|
||||
**Notice that the language support of *README* may be a little SLOW.**
|
||||
|
||||
## Introduction🚀
|
||||
|
||||
Musicreater(音·创) is a free open source software which is used for making and also creating music in **Minecraft: Bedrock Edition**.
|
||||
|
||||
Musicreater pkgver(Package Version 音·创 库版) is a free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
|
||||
|
||||
Welcome to join our QQ group: [861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
|
||||
|
||||
### **SEEEEEEEEE Tutorials [HERE](./docs/Use%20of%20Funtions.md)**
|
||||
|
||||
### Authors✒
|
||||
|
||||
Eilles (金羿):A high school student, individual developer, unfamous BilibiliUPer, which knows a little about commands in *Minecraft: Bedrock Edition*
|
||||
|
||||
bgArray "诸葛亮与八卦阵": Fix bugs, improve code aesthetics, add new functions, change data format, etc.
|
||||
|
||||
|
||||
## Thanks🙏
|
||||
|
||||
- Thank *昀梦*\<QQ1515399885\> for finding and correcting the bugs in the commands that *Musicreater* Created.
|
||||
- Thank *Charlie_Ping “查理平”* for bdx convert function, and
|
||||
the data label that's used to convert the mid's instruments into minecraft's instruments.
|
||||
- Thank *CMA_2401PT* for BDXWorkShop as the .bdx structure's operation guide.
|
||||
- Thank *Dislink Sforza* \<QQ1600515314\> for the algorithm brought to us, his midi analysis algorithm became one of us's best ones
|
||||
- Thank *Arthur Morgan*\<QQ312280061\> for his/her biggest support for the debugging of Musicreater
|
||||
- Thank *Touch “偷吃”*\<QQ1793537164\> for support of debugging and testing program and algorithm, as well his/her suggestions to the improvement of our project
|
||||
- Thank *Mono*\<QQ738893087\> for reporting problems while installing
|
||||
- Thanks for a lot of groupmates who support me and help me to test the program.
|
||||
- If you have give me some help but u haven't been in the list, please contact me.
|
||||
|
||||
## Contact Information📞
|
||||
|
||||
### Author *Eilles*(金羿)
|
||||
|
||||
1. QQ 2647547478
|
||||
2. E-mail EillesWan2006@163.com
|
||||
W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. WeChat WYI_DoctorYI
|
||||
4. Telegram [@EillesWan](https://t.me/EillesWan)
|
||||
|
||||
### Author *bgArray*(诸葛亮与八卦阵)
|
||||
|
||||
1. QQ 4740437765
|
||||
|
||||
|
||||
|
||||
[Bilibili: Eilles]: https://img.shields.io/badge/Bilibili-%E5%87%8C%E4%BA%91%E9%87%91%E7%BE%BF-00A1E7?style=for-the-badge
|
||||
[Bilibili: bgArray]: https://img.shields.io/badge/Bilibili-%E8%AF%B8%E8%91%9B%E4%BA%AE%E4%B8%8E%E5%85%AB%E5%8D%A6%E9%98%B5-00A1E7?style=for-the-badge
|
||||
[CodeStyle: black]: https://img.shields.io/badge/code%20style-black-121110.svg?style=for-the-badge
|
||||
[python]: https://img.shields.io/badge/python-3.6-AB70FF?style=for-the-badge
|
||||
[release]: https://img.shields.io/github/v/release/EillesWan/Musicreater?style=for-the-badge
|
||||
[license]: https://img.shields.io/badge/Licence-Apache-228B22?style=for-the-badge
|
||||
52
README_en.md
52
README_en.md
@@ -1,52 +0,0 @@
|
||||
# Musicreater
|
||||
|
||||
### Introduction
|
||||
Musicreater(音·创) is an Eilles(*W-YI*)'s app that is used for creating musics in **Minecraft: Bedrock Edition**.
|
||||
|
||||
Welcome to join our QQ group: 861684859
|
||||
|
||||
### Framework
|
||||
|
||||
Use *Python* to develop, use *BeeWare* as a Windows Library.
|
||||
|
||||
We are trying to support every platform.
|
||||
|
||||
|
||||
### Tutorials
|
||||
|
||||
#### Windows
|
||||
|
||||
Please wait for a while...
|
||||
Comming soon
|
||||
|
||||
#### Linux
|
||||
|
||||
Please wait for a while...
|
||||
Comming soon
|
||||
|
||||
#### Android
|
||||
|
||||
Please wait for a while...
|
||||
Comming soon
|
||||
|
||||
### Instructions
|
||||
|
||||
1. Just make u understand the Chinese
|
||||
2. If u dont understand, u can come to the QQ group or email me to ask questions
|
||||
3. The English Edition is comming soon.
|
||||
|
||||
### Thanks
|
||||
|
||||
1. Thank [Fuckcraft](https://github.com/fuckcraft) “鸣凤鸽子”and so on for the function of Creating the Websocket Server for Minecraft: Bedrock Edition.
|
||||
2. Thank 昀梦<QQ1515399885> for finding and correcting the bugs in the commands that *Musicreater* Created.
|
||||
3. Thank Charlie_Ping “查理平” for bdx convert funtion.
|
||||
4. Thank CMA_2401PT for BDXWorkShop as the .bdx structure's operation guide.
|
||||
5. Thanks for a lot of groupmates who support me and help me to test the program.
|
||||
6. If u have give me some help but u haven't been in the list, please contact me.
|
||||
|
||||
|
||||
### Contact *Eilles(W-YI)*(金羿)
|
||||
|
||||
1. QQ 2647547478
|
||||
2. E-mail EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. WeChat WYI_DoctorYI
|
||||
@@ -1 +0,0 @@
|
||||
briefcase dev
|
||||
@@ -1,60 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os,shutil
|
||||
from sys import platform
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print("更新执行位置...")
|
||||
if platform == 'win32':
|
||||
try:
|
||||
os.chdir(__file__[:len(__file__)-__file__[len(__file__)::-1].index('\\')]+'src\\')
|
||||
print("更新执行位置,当前文件位置"+__file__)
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
os.chdir(__file__[:len(__file__)-__file__[len(__file__)::-1].index('/')]+'src/')
|
||||
except:
|
||||
pass
|
||||
print("其他平台:"+platform+"更新执行位置,当前文件位置"+__file__)
|
||||
print('完成!')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
import toga,amulet
|
||||
except:
|
||||
print("You'd better install the libraries of this app\nNow, we're helping you with this.")
|
||||
from src.musicreater.msctspt.bugReporter import version
|
||||
version.installLibraries(version)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if platform == 'win32':
|
||||
os.system("python ./Musicreater.py")
|
||||
elif platform == 'linux':
|
||||
os.system("python3 ./Musicreater.py")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
if os.path.exists("./log/"):
|
||||
shutil.rmtree("./log/")
|
||||
if os.path.exists("./logs/"):
|
||||
shutil.rmtree("./logs/")
|
||||
if os.path.exists("./cache/"):
|
||||
shutil.rmtree("./cache/")
|
||||
except:
|
||||
print("无法清除日志及临时文件")
|
||||
151
demo_convert.py
Normal file
151
demo_convert.py
Normal file
@@ -0,0 +1,151 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 MIDI转换展示程序
|
||||
Musicreater Package Version : Demo for Midi Conversion
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ./Lisence.md
|
||||
Terms & Conditions: ./Lisence.md
|
||||
"""
|
||||
|
||||
from msctPkgver.main import *
|
||||
import os
|
||||
|
||||
convertion = midiConvert()
|
||||
|
||||
while True:
|
||||
midipath = input('请输入midi文件路径:')
|
||||
if os.path.exists(midipath):
|
||||
break
|
||||
else:
|
||||
print('文件不存在,请重新输入')
|
||||
|
||||
outpath = input('请输入输出路径:')
|
||||
|
||||
if not os.path.exists(outpath):
|
||||
os.makedirs(outpath)
|
||||
|
||||
while True:
|
||||
try:
|
||||
outFormat = int(input('请输入输出格式(0:mcpack|1:BDX结构):'))
|
||||
if outFormat == 0:
|
||||
isAutoReset = input('是否自动重置计分板(1|0):')
|
||||
if isAutoReset != '':
|
||||
isAutoReset = bool(int(isAutoReset))
|
||||
while True:
|
||||
isProgress = input('*进度条[本Demo不支持自定义]:')
|
||||
if isProgress != '':
|
||||
if isProgress in ('1', 'True'):
|
||||
isProgress = True
|
||||
elif isProgress in ('0', 'False'):
|
||||
isProgress = False
|
||||
else:
|
||||
isProgress = isProgress
|
||||
else:
|
||||
continue
|
||||
break
|
||||
sbname = input('请输入计分板名称:')
|
||||
volume = input('请输入音量(0-1):')
|
||||
if volume != '':
|
||||
volume = float(volume)
|
||||
speed = input('请输入速度倍率:')
|
||||
if speed != '':
|
||||
speed = float(speed)
|
||||
elif outFormat == 1:
|
||||
author = input('请输入作者:')
|
||||
while True:
|
||||
isProgress = input('*进度条[本Demo不支持自定义]:')
|
||||
if isProgress != '':
|
||||
if isProgress in ('1', 'True'):
|
||||
isProgress = True
|
||||
elif isProgress in ('0', 'False'):
|
||||
isProgress = False
|
||||
else:
|
||||
isProgress = isProgress
|
||||
else:
|
||||
continue
|
||||
break
|
||||
maxHeight = input('请输入指令结构最大生成高度:')
|
||||
if maxHeight != '':
|
||||
maxHeight = int(maxHeight)
|
||||
sbname = input('请输入计分板名称:')
|
||||
volume = input('请输入音量(0-1):')
|
||||
if volume != '':
|
||||
volume = float(volume)
|
||||
speed = input('请输入速度倍率:')
|
||||
if speed != '':
|
||||
speed = float(speed)
|
||||
isAutoReset = input('是否自动重置计分板(1|0):')
|
||||
if isAutoReset != '':
|
||||
isAutoReset = bool(int(isAutoReset))
|
||||
break
|
||||
except BaseException:
|
||||
print('输入错误,请重新输入')
|
||||
|
||||
|
||||
|
||||
|
||||
m = 1
|
||||
'''采用的算法编号'''
|
||||
|
||||
|
||||
if os.path.isdir(midipath):
|
||||
for i in os.listdir(midipath):
|
||||
if i.lower().endswith('.mid'):
|
||||
print(f'正在操作{i}')
|
||||
convertion.convert(midipath + '/' + i, outpath + '/' + i[:-4])
|
||||
if outFormat == 0:
|
||||
print(convertion.tomcpack(
|
||||
m,
|
||||
isAutoReset
|
||||
if isAutoReset != ''
|
||||
else bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
isProgress,
|
||||
sbname if sbname != '' else input('请输入计分板名称:'),
|
||||
volume if volume != '' else float(input('请输入音量(0-1):')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
))
|
||||
elif outFormat == 1:
|
||||
print(convertion.toBDXfile(
|
||||
m,
|
||||
author if author != '' else input('请输入作者:'),
|
||||
isProgress,
|
||||
maxHeight if maxHeight != '' else int(input('请输入指令结构最大生成高度:')),
|
||||
sbname if sbname != '' else input('请输入计分板名称:'),
|
||||
volume if volume != '' else float(input('请输入音量(0-1):')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
isAutoReset
|
||||
if isAutoReset != ''
|
||||
else bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
))
|
||||
else:
|
||||
convertion.convert(midipath, outpath)
|
||||
if outFormat == 0:
|
||||
print(convertion.tomcpack(
|
||||
m,
|
||||
isAutoReset if isAutoReset != '' else bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
isProgress,
|
||||
sbname if sbname != '' else input('请输入计分板名称:'),
|
||||
volume if volume != '' else float(input('请输入音量(0-1):')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
))
|
||||
elif outFormat == 1:
|
||||
print(convertion.toBDXfile(
|
||||
m,
|
||||
author if author != '' else input('请输入作者:'),
|
||||
isProgress,
|
||||
maxHeight if maxHeight != '' else int(input('请输入指令结构最大生成高度:')),
|
||||
sbname if sbname != '' else input('请输入计分板名称:'),
|
||||
volume if volume != '' else float(input('请输入音量(0-1):')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
isAutoReset if isAutoReset != '' else bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
))
|
||||
101
demo_convert_bdx_byDelay.py
Normal file
101
demo_convert_bdx_byDelay.py
Normal file
@@ -0,0 +1,101 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# THIS PROGRAM IS ONLY A TEST EXAMPLE
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 MIDI转换展示程序
|
||||
Musicreater Package Version : Demo for Midi Conversion
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ./Lisence.md
|
||||
Terms & Conditions: ./Lisence.md
|
||||
"""
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
convertion = midiConvert()
|
||||
|
||||
while True:
|
||||
midipath = input('请输入midi文件路径:')
|
||||
if os.path.exists(midipath):
|
||||
break
|
||||
else:
|
||||
print('文件不存在,请重新输入')
|
||||
|
||||
outpath = input('请输入输出路径:')
|
||||
|
||||
if not os.path.exists(outpath):
|
||||
os.makedirs(outpath)
|
||||
|
||||
while True:
|
||||
try:
|
||||
authorname = input('请输入作者:')
|
||||
while True:
|
||||
isProgress = input('*进度条[本Demo不支持自定义]:')
|
||||
if isProgress != '':
|
||||
if isProgress in ('1', 'True'):
|
||||
isProgress = True
|
||||
elif isProgress in ('0', 'False'):
|
||||
isProgress = False
|
||||
else:
|
||||
isProgress = isProgress
|
||||
else:
|
||||
continue
|
||||
break
|
||||
|
||||
volume = input('请输入音量(0-1):')
|
||||
if volume != '':
|
||||
volume = float(volume)
|
||||
speed = input('请输入速度倍率:')
|
||||
if speed != '':
|
||||
speed = float(speed)
|
||||
player = input('请输入玩家选择器:')
|
||||
heightmax = input('请输入指令结构最大生成高度:')
|
||||
if heightmax != '':
|
||||
heightmax = int(heightmax)
|
||||
break
|
||||
|
||||
except BaseException:
|
||||
print('输入错误,请重新输入')
|
||||
|
||||
|
||||
def operation(
|
||||
i,
|
||||
):
|
||||
print(f'正在操作{i}')
|
||||
convertion.convert(midipath + '/' + i, outpath)
|
||||
convertion.toBDXfile_withDelay(
|
||||
1,
|
||||
authorname if authorname != '' else input('请输入作者:'),
|
||||
isProgress,
|
||||
heightmax if heightmax != '' else int(input('请输入指令结构最大生成高度:')),
|
||||
volume if volume != '' else float(input('请输入音量(0-1]:')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
player if player != '' else input('请输入玩家选择器:'),
|
||||
)
|
||||
|
||||
|
||||
if os.path.isdir(midipath):
|
||||
import threading
|
||||
|
||||
for i in os.listdir(midipath):
|
||||
if i.lower().endswith('.mid'):
|
||||
threading.Thread(target=operation, args=(i,)).start()
|
||||
else:
|
||||
convertion.convert(midipath, outpath)
|
||||
convertion.toBDXfile_withDelay(
|
||||
1,
|
||||
authorname if authorname != '' else input('请输入作者:'),
|
||||
isProgress,
|
||||
heightmax if heightmax != '' else int(input('请输入指令结构最大生成高度:')),
|
||||
volume if volume != '' else float(input('请输入音量(0-1]:')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
player if player != '' else input('请输入玩家选择器:'),
|
||||
)
|
||||
262
docs/Use of Funtions.md
Normal file
262
docs/Use of Funtions.md
Normal file
@@ -0,0 +1,262 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
|
||||
# Instructions for Using Demo(s)
|
||||
|
||||
*This is a tutorial for using the demo(s) of this library, not the Development Guide. If you want to see so, please read Below*
|
||||
|
||||
## Under Windows
|
||||
|
||||
0. Install Python 3.6+
|
||||
|
||||
First of all, you need to install the runtime environment of this library, *Python*. And a Installation Pack maybe the best choice:
|
||||
|
||||
> [Downloading Python 64-bit](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
|
||||
> [Downloading Python 32-bit](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
|
||||
|
||||
While installing, it's better to check `Add Python 3.X to PATH`(just as the screenshot showed below), otherwise it needs to be set manually which may cause some time wasting
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1662736520757331846/e38efb81_9911226.png>
|
||||
|
||||
If you are new to Python or not very familiar to Computer Programming, and having the disk space in your PC's System Partition (usually C:) of 150 MB, you can directly choose *Install Now*.
|
||||
|
||||
However, if you want to do it like a pro, choosing *Customize Installation*, it's a necessary to be sure to check `pip` and `py launcher` will be installed on your computer(see screenshot below). The two options is required for the next step of installing the requirements.
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1662736621235871190/2ac3d98f_9911226.png>
|
||||
|
||||
After the installation, you can enter in your terminal(CMD/PowerShell/Bash/etc): "python" to ensure whether the installation was successful. If it was, your terminal will show things like below:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659972669907359295/cmd.png>
|
||||
|
||||
|
||||
1. Installing Requirements
|
||||
|
||||
It's better to open your terminal(CMD/PowerShell/Bash/etc) under Administrator Mode.
|
||||
|
||||
For example, if you want to use CMD in Administrator Mode, you can search `cmd` in the *Start Menu*, right click it and *Run as Administrator*
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662736878650993886/62487dd8_9911226.png">
|
||||
|
||||
Okay, after that, please enter in your terminal:
|
||||
|
||||
`pip install mido`
|
||||
|
||||
`pip install brotli`
|
||||
|
||||
If successful you will see something like below:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
|
||||
|
||||
2. Download This Package and Demo(s)
|
||||
|
||||
- If you using Git, you can use the following commands to clone this lib:
|
||||
|
||||
`git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
|
||||
|
||||
- If Git is not installed, you can download the zip package from the code page(from [GitHub](https://github.com/EillesWan/Musicreater.git) or [Gitee](https://gitee.com/EillesWan/Musicreater.git)). Or you are a Chinese fan having a QQ account, you can [Join the QQ Group 861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr) and get it from our GroupFiles.
|
||||
|
||||
<img src=" https://foruda.gitee.com/images/1659972440341216712/下载.png" >
|
||||
|
||||
|
||||
2. Start Using Demo(s)
|
||||
|
||||
Open your terminal in the directory of this, taking CMD, for example, just enter the directory and enter `cmd` in the path box:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974437388532868/输入.png>
|
||||
<img src=https://foruda.gitee.com/images/1659974754378201859/输入c.png>
|
||||
|
||||
And enter one of the commands below by choosing what you need:
|
||||
|
||||
`python demo_convert.py`
|
||||
|
||||
`python demo_convert_bdx_byDelay.py`
|
||||
|
||||
|
||||
### Addition for Error(s) Using or Installing
|
||||
|
||||
1. Environment Error of Microsoft Visual C++ Redistributable
|
||||
|
||||
If you meet this condition as the screenshot shows:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659972789779764953/bug.jpeg>
|
||||
|
||||
Your MSVC Environment may be not installed, and you can download and install
|
||||
> [Here of 64-Bit VCREDIST](https://aka.ms/vs/17/release/vc_redist.x64.exe)
|
||||
> [Here of 32-Bit VCREDIST](https://aka.ms/vs/17/release/vc_redist.x86.exe)
|
||||
|
||||
Thank our groupmate *Mono* again for helping finding this problem.
|
||||
|
||||
|
||||
|
||||
## Under Linux OS
|
||||
|
||||
|
||||
### Install Runtime Environment
|
||||
|
||||
0. Install and Verify Python Runtime
|
||||
|
||||
Common Linux Releases do include a Python Runtime Environment, what we should do only is to check it is a satisfied version to our program. If the version ≥Python3.6, theoretically our program can be run.
|
||||
|
||||
We can type:
|
||||
|
||||
```bash
|
||||
python -V
|
||||
```
|
||||
|
||||
To check the Python version, as the follows
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665120915821957090/429561fd_9911226.png>
|
||||
|
||||
- Not Necessary
|
||||
|
||||
If you want to change a Python version just as what I want to do, it is such a great fantastic action! Let do as the follows:
|
||||
|
||||
- pacman Package Manager(In Arch Linux Mostly)
|
||||
|
||||
Let's write python3 into the ingore list of updating. Via `vim` to edit `/etc/pacman.conf`, add `python3` after `IgnorePkg`.
|
||||
|
||||
```bash
|
||||
sudo vim /etc/pacman.conf
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665124611490335193/5e99ca26_9911226.png>
|
||||
|
||||
Then we can search for python releases in [Arch Achieve](https://archive.archlinux.org/packages/).(*HERE, under Arch, Python refers to Python3 defaultly, while some other Linux releases using Python2 as default. So dose Arch Achieve.*)What I find here is [Python3.8.6](https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst), so let's download she via `pacman`:
|
||||
|
||||
```bash
|
||||
sudo pacman -U https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665126362769399903/ea4b9598_9911226.png>
|
||||
|
||||
Perfect!
|
||||
|
||||
1. Install and Verify pip Package Manager
|
||||
|
||||
Before installing, it is to be checked, wheather Python's pip is OK:
|
||||
|
||||
```bash
|
||||
python -m pip # To check is pip installed
|
||||
# If a long tip occured, it is OK
|
||||
|
||||
# If returned as this, then not.
|
||||
/usr/bin/python: No module named pip
|
||||
# We can install pip via:
|
||||
sudo pacman -S python-pip
|
||||
# Verfy, remember.
|
||||
python -m pip
|
||||
|
||||
|
||||
# If you did but failed, we should use other methods to install pip:
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
sudo python get-pip.py
|
||||
# Verfy, must.
|
||||
python -m pip
|
||||
```
|
||||
|
||||
Over after checking, lets install the dependences.
|
||||
|
||||
```bash
|
||||
pip install mido -i https://mirrors.aliyun.com/pypi/simple/
|
||||
pip install brotli -i https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
See the tips below as successfully installed:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
|
||||
### Download this sources pack and Using its demos.
|
||||
|
||||
1. 使用Git下载本库及其示例代码
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git MSCTpkgver
|
||||
```
|
||||
|
||||
当上述命令执行成功,你会在执行此命令的所在位置发现一个名为 `MSCTpkgver` 的文件夹,其中包含的正是我们心心念念下载的本程序和示例代码。
|
||||
而我们要运行的也正是示例代码,因此,赶快进入下载到的文件夹:
|
||||
|
||||
```bash
|
||||
cd MSCTpkgver
|
||||
```
|
||||
|
||||
1. 开始使用
|
||||
|
||||
在目录下打开终端,执行以下命令:(选择你需要的)
|
||||
|
||||
```bash
|
||||
python demo_convert.py
|
||||
python demo_convert_bdx_byDelay.py
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2. More Info for Parameters of Our Demo Program(s)
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974810147043475/运行.png>
|
||||
|
||||
|Input Prompt|English Translation|Description|
|
||||
|----------------|----------------|-------|
|
||||
|请输入MIDI文件路径|Midi File Path|Path of a .mid file or a directory. While directory entered, our demo will convert all midi(s) in the directory|
|
||||
|请输入输出路径|Output Path|Where files converted in|
|
||||
|是否重置计分板|Whether Reset Scoreboard Automatically|Can only be 1 or 0(Recommanded 1)|
|
||||
|*进度条[注]|Progressbar|Whether to enable Progressbar and customize progressbar style. Type 0 or False to disable, 1 or True to use default style, or type using format taught in follow the Instructions below to customize one you like|
|
||||
|请输入计分板名称|Scoreboard Name|*Only not byDelay* The name of scoreboard that player using|
|
||||
|请输入音量|Volume|Only decimal in [0,1],(Recommanded 1)|
|
||||
|请输入速度倍率|Speed Multiplying Factor|Maybe you want to play it faster(>1) or slower(>0 <1)?|
|
||||
|请输入玩家选择器|Player Selector|Full Selector including `@x`. E.g: Play for players tagged `Holo`, enter `@a[tag=Holo]` on this parameter|
|
||||
|
||||
|
||||
|
||||
|
||||
# Instructions for **Customize Progress Bar**
|
||||
|
||||
We have supported the function of making progress bar in *Minecraft*'s music player. And also the method of customize them. So the following instructions are about the parameters of the Progress Bar Customizition.
|
||||
|
||||
A Progress Bar, of course, is composed of **changeless** parts and **changable** parts. And the changable parts include texts or *images*(these images are made up of texts, or we can say, character paintings 😁). That is, for *Minecraft*, a changable image in a progress bar is just the "bar" part(which is like a stripe).
|
||||
|
||||
We use a string to describe the style of progress bar you need, and it includes many **identifier**s to replace the changable parts.
|
||||
|
||||
There are the identifiers:
|
||||
|
||||
| Identifier | Changable Part |
|
||||
|--------------|------------------------------------------------------|
|
||||
| `%%N` | Music name(file name which is imported into program) |
|
||||
| `%%s` | Value of scoreboard of now |
|
||||
| `%^s` | Max value of scoreboard |
|
||||
| `%%t` | Current playback time |
|
||||
| `%^t` | Total music time |
|
||||
| `%%%` | Current playback progress |
|
||||
| `_` | To be replaced by the *Bar* part of the progress bar |
|
||||
|
||||
The `_` is a placeholder to identifying the *bar* part, yeah, just the changable image.
|
||||
|
||||
This is an example of **style description string**, and this is also the default style of *Musicreater*'s progress bar.
|
||||
|
||||
`▶ %%N [ %%s/%^s %%% __________ %%t|%^t]`
|
||||
|
||||
This is a progress bar with only one line, but it is possible if you want to give a multiline parameter into the style description string.
|
||||
|
||||
But the string above is only for style identification, but we also need to identifying the changable image's image(just what the bar's look).
|
||||
|
||||
A "bar", simply, included 2 parts: *Have Been Played* & *Not Been Played*. So we use a tuple to pass the parameter. It's under a simple format: `(str: played, str: not)`. For example, the default parameter is below:
|
||||
|
||||
`('§e=§r', '§7=§r')`
|
||||
|
||||
So it's time to combine what I said in one parameter now!
|
||||
|
||||
This is a default definder parameter:
|
||||
|
||||
`('▶ %%N [ %%s/%^s %%% __________ %%t|%^t]',('§e=§r', '§7=§r'))`
|
||||
|
||||
*Tip: To avoid errors, please not to use the identifiers as the other part of your style.*
|
||||
167
docs/download&atart/Android.md
Normal file
167
docs/download&atart/Android.md
Normal file
@@ -0,0 +1,167 @@
|
||||
## 使用前的准备工作
|
||||
|
||||
### 安装终端工具
|
||||
|
||||
这里我们选用 **Termux** 作为我们的终端工具来安装,这是一个强大的终端模拟器,旨在安卓环境下模拟Linux的软件包环境。
|
||||
|
||||
1. 下载
|
||||
|
||||
下载可以通过 [GitHub源](https://github.com/termux/termux-app/releases) 或者 [F-Droid源](https://f-droid.org/en/packages/com.termux/) ,个人建议选择 F-Droid 源,因为在国内可以访问得到,而 GitHub 源就看运气。
|
||||
|
||||
2. 安装
|
||||
|
||||
下载*APK*包后直接安装,安装后打开可以看到一个类似这样的界面:
|
||||
|
||||
<img height="512" src="https://foruda.gitee.com/images/1665933025120627254/a0479618_9911226.jpeg">
|
||||
|
||||
3. 完成
|
||||
|
||||
恭喜你,你已经获得了一个极客般流畅地操作你手机的终端工具。
|
||||
|
||||
### 安装运行环境
|
||||
|
||||
1. 换源
|
||||
|
||||
接下来,我们就要来准备安装一下 **Python** 运行环境了,这是运行 **Python** 源代码必要的。
|
||||
|
||||
首先,我估计你等不了多久,急得要死,所以我们要让下载速度稍微快一点,先来换个源。在 **Termux** 中,输入以下指令:
|
||||
|
||||
```bash
|
||||
echo "deb https://mirror.mwt.me/termux/main stable main" > /data/data/com.termux/files/usr/etc/apt/sources.list
|
||||
```
|
||||
|
||||
*感谢 天如<QQ 3291691454>为我们带来的简单换源方法。*
|
||||
|
||||
- *非必要步骤*:手动编辑换源
|
||||
|
||||
如果你闲着没事,非要要手动编辑个文档来换源,那用啥?用普通的编辑器肯定可以,于是我们就让他更普通一点,用**nano**吧!
|
||||
|
||||
在 **Termux** 中,输入以下指令:
|
||||
|
||||
```bash
|
||||
export EDITOR=nano
|
||||
apt edit-sources
|
||||
```
|
||||
|
||||
那么请把看到的如左下图的界面变为右下图吧:
|
||||
|
||||
<table><tr>
|
||||
<td><img src="https://foruda.gitee.com/images/1665933104313107707/41108f03_9911226.jpeg"> </td>
|
||||
<td><img src="https://foruda.gitee.com/images/1665933122534781330/3887a901_9911226.jpeg"></td>
|
||||
</tr></table>
|
||||
|
||||
- 图片中的文件,最后应该加入的两行为:
|
||||
|
||||
```bash
|
||||
deb https://mirrors.ustc.edu.cn/termux/apt/termux-main/ stable main
|
||||
deb https://mirrors.tuna.tsinghua.edu.cn/termux/apt/termux-main/ stable main
|
||||
```
|
||||
|
||||
然后键入 `Ctrl`+`S`,再键入 `Ctrl`+`X`,退出`nano`。
|
||||
|
||||
在换源之后,你可能会见到类似的提示:
|
||||
|
||||
```bash
|
||||
Your '/data/data/com.termux/files/usr/etc/apt/sources.list' file changed. Please run 'apt-get update'.
|
||||
```
|
||||
|
||||
那就遵循它的指引,输入:
|
||||
|
||||
```bash
|
||||
apt-get update
|
||||
```
|
||||
|
||||
Alright.
|
||||
|
||||
2. 安装 **Python**
|
||||
|
||||
```bash
|
||||
apt-get install python3
|
||||
```
|
||||
|
||||
如果遇到提示问是否继续,那就输入`Y`表示是,如左下图,安装成功后,图若右下。
|
||||
|
||||
<table><tr>
|
||||
<td><img src="https://foruda.gitee.com/images/1665933181440420034/7f0fb5fd_9911226.jpeg"></td>
|
||||
<td><img src="https://foruda.gitee.com/images/1665933238339972260/a9f06f4f_9911226.jpeg"></td>
|
||||
</tr></table>
|
||||
|
||||
接下来,我们来试一试 **Python** 是不是安装成了吧,输入
|
||||
|
||||
```bash
|
||||
python3 -V
|
||||
```
|
||||
|
||||
如果输出了形如 `Python 3.X.X` 的提示,则完成。
|
||||
|
||||
3. 安装依赖库
|
||||
|
||||
```bash
|
||||
# 首先换源
|
||||
pip config set global.index-url http://mirrors.aliyun.com/pypi/simple/
|
||||
# 然后安装
|
||||
pip install mido
|
||||
pip install brotli
|
||||
```
|
||||
|
||||
- 如果出现以下情况,真是死了鬼的,我们要来再搞个设置:
|
||||
|
||||
<img height="512" src="https://foruda.gitee.com/images/1665933289612919459/b87b7804_9911226.jpeg">
|
||||
|
||||
我们来修改收信任的源设置:
|
||||
|
||||
```bash
|
||||
pip config set global.trusted-host mirrors.aliyun.com/
|
||||
```
|
||||
|
||||
之后再来安装即可
|
||||
|
||||
```bash
|
||||
pip install mido
|
||||
pip install brotli
|
||||
```
|
||||
|
||||
安装成功后您可能会见到类似下图的提示:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
### 安装下载工具
|
||||
|
||||
既然已经有了运行环境,那么我们就需要下载下我们的**音·创库版示例代码**工具,我非常推崇**Git**这种方便快捷好用还能下载仓库的代码管理器,这个世界上你也找不到第二个,所以我们来安装一下:
|
||||
|
||||
```bash
|
||||
pkg install git
|
||||
```
|
||||
|
||||
安装完成后记得测试一下:
|
||||
|
||||
<img height="512" src="https://foruda.gitee.com/images/1665933331269483373/9374c85d_9911226.jpeg">
|
||||
|
||||
## 本代码库的下载与演示程序的使用
|
||||
|
||||
1. 使用Git下载本库及其示例代码
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git MSCTpkgver
|
||||
```
|
||||
|
||||
当上述命令执行成功,你会在执行此命令的所在位置发现一个名为 `MSCTpkgver` 的文件夹,其中包含的正是我们心心念念下载的本程序和示例代码。
|
||||
而我们要运行的也正是示例代码,因此,赶快进入下载到的文件夹:
|
||||
|
||||
```bash
|
||||
cd MSCTpkgver
|
||||
```
|
||||
|
||||
1. 开始使用演示程序
|
||||
|
||||
依照你的需要,执行以下命令之一:
|
||||
|
||||
```bash
|
||||
python demo_convert.py #计分板播放器,支持mcpack与BDX
|
||||
python demo_convert_bdx_byDelay.py #延迟播放器,仅支持BDX
|
||||
```
|
||||
|
||||
运行成功了,哦耶!
|
||||
|
||||
<img height="512" src="https://foruda.gitee.com/images/1665933366784631363/db9f80f6_9911226.jpeg">
|
||||
|
||||
104
docs/download&atart/Linux.md
Normal file
104
docs/download&atart/Linux.md
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
## 运行环境安装
|
||||
|
||||
### 检验Python运行环境
|
||||
|
||||
0. 一般的Linux发行版都有安装Python环境,我们只需要保证其版本即可,理论上 ≥Python3.6 都可以运行我们的库
|
||||
|
||||
我们可以使用
|
||||
|
||||
```bash
|
||||
python -V
|
||||
```
|
||||
|
||||
来查看 Python 版本,如下
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665120915821957090/429561fd_9911226.png>
|
||||
|
||||
1. *非必要环节*:回退版本
|
||||
|
||||
如果你跟作者一样,觉得 Python 3.10+ 太难用很烦人的话,那真是皆大欢喜,让我们一起来回退版本吧!
|
||||
|
||||
- pacman 包管理器(多用于Arch Linux上)
|
||||
|
||||
1. 让我们先来把 python3 加入忽略升级的列表中,使用`vim`修改`/etc/pacman.conf`,在`IgnorePkg`后加上`python3`
|
||||
|
||||
```bash
|
||||
sudo vim /etc/pacman.conf
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665124611490335193/5e99ca26_9911226.png>
|
||||
|
||||
2. 然后我们开始从[Arch Achieve](https://archive.archlinux.org/packages/)上找Python的版本列表。(*这里说明一下,在Arch中,Python默认指的是Python3,而与其他某些Linux发行版中Python默认指代Python2不同,所以在Arch Achieve中也是如此。*)我这里找到的是[Python3.8.6](https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst),于是我们用`pacman`把她下载下来并安装:
|
||||
|
||||
```bash
|
||||
sudo pacman -U https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665126362769399903/ea4b9598_9911226.png>
|
||||
|
||||
3. 完美!
|
||||
|
||||
- 其他包管理器
|
||||
|
||||
暂无
|
||||
|
||||
### 检查并安装pip包管理器依赖
|
||||
|
||||
1. 我们在安装依赖库之前,应该确认一下,Python自带的包管理器pip是否安装到位:
|
||||
|
||||
```bash
|
||||
python -m pip # 确认pip是否安装
|
||||
# 当这个命令输入后有长段提示出现则为已经安装
|
||||
|
||||
# 如果返回如下,那么则pip尚未安装
|
||||
/usr/bin/python: No module named pip
|
||||
# 可以使用如下命令来安装pip
|
||||
sudo pacman -S python-pip
|
||||
# 安装完成后记得验证
|
||||
python -m pip
|
||||
|
||||
|
||||
# 如果还是失败,那么就需要用其他工具安装pip:
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
sudo python get-pip.py
|
||||
# 安装完成后一定要验证!!!
|
||||
python -m pip
|
||||
```
|
||||
|
||||
2. 确认完成之后,我们来安装一下依赖库:
|
||||
|
||||
```bash
|
||||
pip install mido -i https://mirrors.aliyun.com/pypi/simple/
|
||||
pip install brotli -i https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
3. 安装成功后可能会见到类似下图的提示:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
|
||||
## 本代码库的下载与使用
|
||||
|
||||
1. 使用Git下载本库及其示例代码
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git MSCTpkgver
|
||||
```
|
||||
|
||||
当上述命令执行成功,你会在执行此命令的所在位置发现一个名为 `MSCTpkgver` 的文件夹,其中包含的正是我们心心念念下载的本程序和示例代码。
|
||||
而我们要运行的也正是示例代码,因此,赶快进入下载到的文件夹:
|
||||
|
||||
```bash
|
||||
cd MSCTpkgver
|
||||
```
|
||||
|
||||
1. 开始使用
|
||||
|
||||
在目录下打开终端,执行以下命令:(选择你需要的)
|
||||
|
||||
```bash
|
||||
python demo_convert.py #计分板播放器,支持mcpack与BDX
|
||||
python demo_convert_bdx_byDelay.py #延迟播放器,仅支持BDX
|
||||
```
|
||||
|
||||
89
docs/download&atart/Windows.md
Normal file
89
docs/download&atart/Windows.md
Normal file
@@ -0,0 +1,89 @@
|
||||
## 一、运行环境安装
|
||||
|
||||
### (一)安装 Python3.6+
|
||||
|
||||
1. 首先需要下载Python的安装包,最好是 *Python3.8*,因为作者就用的是这个版本
|
||||
|
||||
> [下载64位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
|
||||
> [下载32位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
|
||||
|
||||
2. 在安装时,最好需要勾选 `Add Python 3.X to PATH`,如下图所示,当然,如果您对自己非常自信,您也可以手动设置此项目:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1662736520757331846/e38efb81_9911226.png>
|
||||
|
||||
- 若您对Python一知半解或者不怎么了解、并对自己的系统盘(通常是C盘)有大约150*兆字节*(MB)的信心的话,您可以在安装时直接选择*快速安装*(Install Now)
|
||||
|
||||
3. 若您选择了*自定义安装*(Customize Installation),请务必勾选 `pip` 和 `py launcher` 便于后续安装依赖,如下图:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1662736621235871190/2ac3d98f_9911226.png>
|
||||
|
||||
4. 安装结束之后可以在*终端*(命令行/PowerShell/Bash/etc)中输入:python 试试是否安装成功,成功安装之后,在终端中输入python会显示诸如如下图片的提示:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659972669907359295/cmd.png>
|
||||
|
||||
|
||||
### (二)安装依赖
|
||||
|
||||
1. 请以管理员模式打开您的*终端*(命令行/PowerShell/Bash/etc)
|
||||
|
||||
例如,命令行,可以如此打开:在*视窗开始菜单*(Windows开始)中搜索 `cmd`, 并以管理员身份运行
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662736878650993886/62487dd8_9911226.png">
|
||||
|
||||
2. 打开了终端之后,请在终端中输入以下指令
|
||||
|
||||
```bash
|
||||
pip install mido -i https://mirrors.aliyun.com/pypi/simple/
|
||||
pip install brotli -i https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
3. 安装成功后您可能会见到类似下图的提示:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
## 二、本工具的下载与使用
|
||||
|
||||
0. 下载本代码库以及演示程序
|
||||
|
||||
- 若您使用git,请直接克隆本仓库:
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git
|
||||
```
|
||||
|
||||
- 若您不使用git,可以在[*码云*(Gitee)](https://gitee.com/EillesWan/Musicreater.git)或[*GitHub*](https://github.com/EillesWan/Musicreater.git)下载zip包,或者[加入QQ群聊861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr),在群文件中获取。
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1669540786443169766/fabf0acd_9911226.png" >
|
||||
|
||||
值得注意的是,这张图上有1、2两个数字,虽然是手写的,但确实是数字,表示着要进行的步骤。希望眼尖得能找出我的口头禅的你们能够发现这两个用鼠标手写的数字并在安装时认真地执行。我认为这并不算十分的难,移动鼠标并单击大约消耗不了多少卡路里,不过我没有进行精确的计算,我也不是十分的清楚这个活动对于一个常人来讲有多难,但我怀疑它不难。
|
||||
|
||||
|
||||
1. 开始使用
|
||||
|
||||
在目录下打开终端。
|
||||
|
||||
例如:打开命令行:请进入到目录下,在文件资源管理器的地址框内输入`cmd`:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974437388532868/输入.png>
|
||||
<img src=https://foruda.gitee.com/images/1659974754378201859/输入c.png>
|
||||
|
||||
执行以下命令:(选择你需要的)
|
||||
|
||||
```bash
|
||||
python demo_convert.py #计分板播放器,支持mcpack与BDX
|
||||
python demo_convert_bdx_byDelay.py #延迟播放器,仅支持BDX
|
||||
```
|
||||
|
||||
## 三、安装时错误的补充说明
|
||||
|
||||
1. Microsoft Visual C++ Redistributable 环境出错
|
||||
|
||||
如果你遇到了类似以下这种情况:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659972789779764953/bug.jpeg>
|
||||
|
||||
请下载最新的VCREDIST安装包,可以参照[这个网页](https://docs.microsoft.com/zh-CN/cpp/windows/latest-supported-vc-redist)的说明,也可以在这直接选择你需要的安装包下载:
|
||||
> [下载64位VCREDIST安装包](https://aka.ms/vs/17/release/vc_redist.x64.exe)
|
||||
> [下载32位VCREDIST安装包](https://aka.ms/vs/17/release/vc_redist.x86.exe)
|
||||
|
||||
感谢群友Mono帮我们发现这个问题。
|
||||
105
docs/功能使用说明.md
Normal file
105
docs/功能使用说明.md
Normal file
@@ -0,0 +1,105 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<h2 align="center">库版 Package Version</h2>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
# 演示程序使用教程
|
||||
|
||||
*由于先前的 **读我文件**(README.md) 过于冗杂,现另辟蹊径来给大家全方位的教程。*
|
||||
|
||||
*这是演示程序(demo)的使用教程,将在这里提供演示程序的相应的使用教程*
|
||||
|
||||
## 下载与启动教程
|
||||
|
||||
### [视窗(Windows)操作系统](./download%26atart/Windows.md)
|
||||
### [里纽克斯(Linux)操作系统](./download%26atart/Linux.md)
|
||||
### [安卓(Android)与安卓衍生操作系统](./download%26atart/Android.md)
|
||||
|
||||
## 演示程序使用教程
|
||||
|
||||
1. 参数说明
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974810147043475/运行.png>
|
||||
|
||||
- midi路径:含有mid文件路径、文件名、后缀的完整文件路径,或者一个目录(demo可接受批量转换)。可以使用相对或绝对路径皆可
|
||||
|
||||
- 输出路径:输出文件夹的路径,不需要指示文件名
|
||||
|
||||
- 是否重置计分板:`1`或`0`(歌曲放完是否重置,推荐`1`)
|
||||
|
||||
- 进度条:是否启用进度条,以及自定义进度条样式。输入`0`或`False`表示不启用进度条,输入`1`或`True`表示使用默认进度条,其余的输入均表示使用输入的格式作为自定义的进度条样式
|
||||
|
||||
若不支持自定义,则仅能输入`0`或`1`表示“关闭”或“开启”
|
||||
|
||||
- 计分板名称:游戏内的计分板名称
|
||||
|
||||
- 音量:0-1之间的小数(含0,1)正常来说推荐`1`
|
||||
|
||||
- 速度倍率:小数数据,其值不可为0,一般写`1`
|
||||
|
||||
- 玩家选择器:包括 `@x` 在内的全部选择器,即若要选择全部标签为`Holo`的玩家,则需要如此输入:`@a[tag=Holo]`
|
||||
|
||||
- 没有报错且在输出路径下找到mcpack或bdx即为生成成功:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659973655881460036/输出.png>
|
||||
|
||||
|
||||
# 其他说明
|
||||
|
||||
## 对于 延迟播放器 的说明
|
||||
|
||||
问1:什么是延迟播放器?
|
||||
|
||||
答1:播放音乐,不同的音符之间存在间隔,可以用不同的方式实现音符间空白的时间。其一是计分板,通过给计分板加分,对应分数播放对应的音符就可以间隔到,还有就是命令方块自带的延迟,这样也可以实现音符间空白。延迟播放器即后者,但是因为只能对命令方块写入这样的延迟数据,所以仅可以使用包含NBT的结构导出或者直接输出至世界。
|
||||
|
||||
问2:可不可以不要积分板?
|
||||
|
||||
答2:详见问1,切换你所需要的播放器即可。
|
||||
|
||||
## 对于 进度条自定义 功能的说明
|
||||
|
||||
因为我们提供了可以自动转换进度条的功能,因此在这里给出进度条自定义参数的详细解释。
|
||||
|
||||
请注意,并非所有的演示样例程序都支持自定义进度条。
|
||||
|
||||
一个进度条,明显地,有**固定部分**和**可变部分**来构成。而可变部分又包括了文字和图形两种(当然,《我的世界》里头的进度条,可变的图形也就是那个“条”了)。这一点你需要了解,因为后文中包含了很多这方面的概念需要你了解。
|
||||
|
||||
进度条的自定义功能使用一个字符串来定义自己的样式,其中包含众多**标识符**来表示可变部分。
|
||||
|
||||
标识符如下(注意大小写):
|
||||
|
||||
| 标识符 | 指定的可变量 |
|
||||
|---------|----------------|
|
||||
| `%%N` | 乐曲名(即传入的文件名)|
|
||||
| `%%s` | 当前计分板值 |
|
||||
| `%^s` | 计分板最大值 |
|
||||
| `%%t` | 当前播放时间 |
|
||||
| `%^t` | 曲目总时长 |
|
||||
| `%%%` | 当前进度比率 |
|
||||
| `_` | 用以表示进度条占位|
|
||||
|
||||
表示进度条占位的 `_` 是用来标识你的进度条的。也就是可变部分的唯一的图形部分。
|
||||
|
||||
**样式定义字符串**的样例如下,这也是默认的进度条的样式:
|
||||
|
||||
`▶ %%N [ %%s/%^s %%% __________ %%t|%^t]`
|
||||
|
||||
这是单独一行的进度条,当然你也可以制作多行的,如果是一行的,输出时所使用的指令便是 `title`,而如果是多行的话,输出就会用 `titleraw` 作为进度条字幕。
|
||||
|
||||
哦对了,上面的只不过是样式定义,同时还需要定义的是可变图形的部分,也就是进度条上那个真正的“条”。
|
||||
|
||||
对于这个我们就采用了固定参数的方法,对于一个进度条,无非就是“已经播放过的”和“没播放过的”两种形态,所以,使用一个元组来传入这两个参数就是最简单的了。元组的格式也很简单:`(str: 播放过的部分长啥样, str: 没播放过的部分长啥样)` 。例如,我们默认的进度“条”的定义是这样的:
|
||||
|
||||
`('§e=§r', '§7=§r')`
|
||||
|
||||
综合起来,把这些参数传给函数需要一个参数整合,你猜用的啥?啊对对对,我用的还是元组!
|
||||
|
||||
我们的默认定义参数如下:
|
||||
|
||||
`(r'▶ %%N [ %%s/%^s %%% __________ %%t|%^t]',('§e=§r', '§7=§r'))`
|
||||
|
||||
*对了!为了避免生成错误,请尽量避免使用标识符作为定义样式字符串的其他部分*
|
||||
|
||||
180
docs/新手答疑指南.md
Normal file
180
docs/新手答疑指南.md
Normal file
@@ -0,0 +1,180 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<h2 align="center">库版 Package Version</h2>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
# 新手答疑指南
|
||||
|
||||
**考虑到某些用户电脑技术不是特别先进,且对这个项目充满了好奇心,但是又了解的不是很充分,
|
||||
为此,我特别在这里写一份文档,解答各位的好奇心。放心,本文件全程中文,英文版本随后更新!**
|
||||
|
||||
## 第一部分 关于音·创的作用
|
||||
|
||||
### 1.1 音·创简介
|
||||
|
||||
音·创 Musicreater 是一款免费开源的 **《我的世界:基岩版》** 音乐制作软件
|
||||
|
||||
音·创 库版 (Musicreater Package Version) 是一款免费开源的针对 **《我的世界:基岩版》** 的midi音乐转换库
|
||||
|
||||
音·创 采用的是**带有特殊条款的Apache2.0**开源协议,详情请见[这里](https://gitee.com/EillesWan/Musicreater/blob/master/LICENSE.md)。
|
||||
|
||||
音·创
|
||||
目前已经具备较为完善的**教程**,如果你还不知道音·创有教程,请点击
|
||||
[
|
||||
这里](https://gitee.com/EillesWan/Musicreater/blob/pkgver/docs/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)。
|
||||
|
||||
### 1.2 音·创到底目前有什么功能?
|
||||
* - [x] 支持导入.mid文件
|
||||
* - [x] 支持写入.mcpack文件
|
||||
* - [x] 支持写入.bdx文件
|
||||
|
||||
|
||||
* 不支持导入.mp3 .mp4 .wav等音频流文件
|
||||
|
||||
## 第二部分 关于格式的问题
|
||||
|
||||
### 2.1 关于.mid格式
|
||||
其实对于经常玩音乐电子制作的朋友们来说,mid格式并不陌生,这里我简单介绍一下。
|
||||
|
||||
> mid格式是由MIDI继承而来。MID文件并不是一段录制好的声音,而是记录声音的信息,然后再告诉声卡如何再现音乐的一组指令。
|
||||
> 这样一个MIDI文件每存1分钟的音乐只用大约5~10KB。今天,MID文件主要用于原始乐器作品、流行歌曲的业余表演、游戏音轨以及电子贺卡等。
|
||||
>
|
||||
> ——百度百科
|
||||
>
|
||||
> MIDI 音乐,保存在电脑上,就是 *.mid 类型的文件。和一般意义上的“音乐”不同,mid 类型的音乐通常并不是可直接发行供大众欣赏的音乐,
|
||||
> 它更像是一种音乐创作者使用的工程文件。它没有歌词,不含有人类语言。如果说五线谱是给人类阅读的乐谱,
|
||||
> MIDI音乐文件便是给计算机或其他电子设备使用的乐谱。对于“音乐”这个世界来说,它微不足道,却又是现代数字音乐的基石。虽不为大众所知,
|
||||
> 但在 MIDI 音乐爱好者眼中,它却是非常有意思的东西。有了 MIDI 音乐技术和一台电脑,基本就等于拥有了一个乐队,加上相关的音乐知识,
|
||||
> 就可以自己指挥这个“乐队”,创作音乐作品了!
|
||||
> 同时,MIDI 技术由于数据结构简单,又与音乐有关,也成为了部分技术极客的爱好。有人使用MIDI技术+Arduino开源硬件制作了架子鼓,
|
||||
> 有人通过分析大量MIDI乐曲结构,设计了人工智能作曲软件,还有更酷的人使用MIDI音乐制作了随节奏变幻的特斯拉线圈!
|
||||
> 在MIDI 音乐的世界里,汇聚了一批喜欢音乐又热爱技术的人。我们有理由相信,玩MIDI音乐的你,定是多才多艺的。
|
||||
>
|
||||
> ——midishow.com
|
||||
|
||||
**所以,mid文件的本质是电子乐谱,而不是记录声音波形文件的.mp3/.wav/.m4a等等文件!**
|
||||
|
||||
### 2.2 关于.mid格式的获取
|
||||
|
||||
通过刚刚的介绍,你可能已经发现,*.mid文件因为受众并不多而并没有被广泛熟知,因而你之前可能完全没见过这个文件,更何况要弄一首自己心仪的歌了。
|
||||
|
||||
这里介绍几个获取.mid格式的方法:
|
||||
|
||||
1. 最简单的方法就是成为一个作编曲的人,当然,很多人做不到这一点,但是有必要提到这一点,当你在下面的渠道中都无法获得想要的文件时,
|
||||
你应该考虑是不是需要自己创作内容,或者,请别人帮你创作内容。
|
||||
2. 当你没有这样的文件时,问问别人或者从群里下在公告的免费的也是个思路,不过这个办法通常使用次数有限。
|
||||
3. 自己找mid:现在,我将给你提供一个完整的找mid的方法,请认真学习:
|
||||
**1.** 首先你需要在www.midishow.com中注册一个账号,并不复杂,你可能只需要一个QQ号。
|
||||
**2.** 登录你的账号,主界面应该如下图所示:
|
||||
<img src="https://foruda.gitee.com/images/1672644995747340749/36c9c143_10062986.png">
|
||||
**3.** 在显眼的搜索框中,输入你想要的歌曲名称,接下来的教程,我以`夜空中最亮的星`这首歌及它的mid来演示下载流程。点击搜索框,完成这一步。
|
||||
<img src="https://foruda.gitee.com/images/1672645340943813483/44d0db69_10062986.png">
|
||||
**4.** 接下来看到搜索结果如下,你可以点进去一个听听,决定你是否要下载;也有可能你什么都没搜到,那你就得换首歌或者换个途径了。
|
||||
<img src="https://foruda.gitee.com/images/1672645574402099694/6b7e18e5_10062986.png">
|
||||
**5.** 点击播放按钮试听,网站上的效果可能一般,但是会听音乐的人应该很快就能决定你是否需要下载这个音乐。如果需要下载,你可以进行到下一步,
|
||||
如果不行,那你可以退回刚刚的页面换一个。
|
||||
<img src="https://foruda.gitee.com/images/1672645752246438160/47cead78_10062986.png">
|
||||
**6.** 翻到最下面,如图,你可以对这首歌进行打分,打分可以使积分+1,建议打5分;你可以对这首歌进行评论,一次有意义的评论可以+3分。
|
||||
下载一首歌需要-3积分,如果你先完成了这两项操作再下载,那你还会再赚1积分。所以推荐这样做!
|
||||
<img src="https://foruda.gitee.com/images/1672646433045265565/26ea29b2_10062986.png">
|
||||
**完成后会像这样:**
|
||||
<img src="https://foruda.gitee.com/images/1672646242419857480/5e8809b8_10062986.png">
|
||||
**7.** 接下来下载,往上翻网页,找到这个标识,然后单击。
|
||||
<img src="https://foruda.gitee.com/images/1672646275215822535/63b402db_10062986.png">
|
||||
**8.** 确认完毕后点击下载。
|
||||
<img src="https://foruda.gitee.com/images/1672646309787744490/f459adac_10062986.png">
|
||||
**9.** 完成下载,如图:
|
||||
<img src="https://foruda.gitee.com/images/1672646335942429563/2449ed0b_10062986.png">
|
||||
4. 使用mp3转换为mid的工具:不得不说,科技的进步带来了许多便利,让这样困难的事情也变得简单。如果上述方法仍然没有解决你的问题,
|
||||
那么你可以在下一章节中找到有关这个途径的说明。
|
||||
|
||||
### 2.3 .mp3格式转换为.mid格式
|
||||
|
||||
**注意,使用这个技术有一定难度,酌情使用!**
|
||||
|
||||
概述:mp3转mid需要把**模拟的波形频谱信号转为数字乐谱信号**,这个过程**一定有损失**。
|
||||
|
||||
请各位以后不要在答疑群中问类似于我这个转换效果为什么不好这样的问题,谢谢。
|
||||
|
||||
如果直接用**widi**的话相当于对声音进行了**傅里叶变换**,你确实可以分离出其中的音高,但是效果在不同情况下差异较大,
|
||||
尤其是有架子鼓啊啥的玩也的时候,比较**差**。
|
||||
([widi工具链接](https://pan.baidu.com/s/1j_Jui0piQ6rMOXM0GJtqTg) 提取码:b0lw )
|
||||
|
||||
**如果只有钢琴的谱子需要分离,有一个完美的选择**:[这里](https://zhuanlan.zhihu.com/p/270999354)
|
||||
|
||||
如果不然有其他的乐器也需要分离,那么可能就有点困难,像cakewalk就确实也可以吧音频变成mid,但是可能要
|
||||
**先把原MP3分离成人声音轨、贝斯音轨等再傅里叶变换。**
|
||||
|
||||
当然我也可能了解的不全,没准现在已经有传新的技术可以分离的更好了,那就太棒了!(〃'▽'〃)
|
||||
|
||||
另外,我们开发者也象征性的找了一些mp3转mid的网站,我们没使用过,不担保效果。
|
||||
[https://www.serocs.cn/transcription/](https://www.serocs.cn/transcription/)
|
||||
|
||||
同时,midishow论坛里有一些大佬也提供了解决方案,看看他们的发言也是一个不错的选择。
|
||||
|
||||
我就只给个论坛链接了,经常有人问这种问题,你可以去那里随便找到一篇帖子看看。
|
||||
[论坛](https://www.midishow.com/question)
|
||||
|
||||
### 2.4 输出格式的问题
|
||||
|
||||
在前面说到,输出主要有`.mcpack`和`.bdx`文件的输出,接下来我会围绕这两个文件进行简单的说明。
|
||||
|
||||
#### 2.4.1 .mcpack是什么
|
||||
|
||||
输出.mcpack文件其实对于一个**资深基岩版我的世界玩家**应该并不陌生。
|
||||
|
||||
.mcpack文件其实就是我的世界基岩版的附加包,里面一般分为行为包和材质包
|
||||
|
||||
我们生成的命令组属于**行为包** (下图就是一个例子)
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1672647779755793187/884abaa9_10062986.png">
|
||||
|
||||
如果你是国际电脑版基岩玩家就像我一样,是可以直接打开这个文件,并将这个包导入我的世界的。
|
||||
|
||||
关于怎么使用,请看[**这里**](https://gitee.com/EillesWan/Musicreater/blob/pkgver/docs/%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)。
|
||||
|
||||
#### 2.4.2 .bdx是什么
|
||||
|
||||
.bdx 文件其实是FastBuilder这款软件的结构文件,可以导入到我的世界。
|
||||
|
||||
由于这不属于官方文件,且我并不是很熟悉这个结构,所以请对这个格式有问题的好兄弟加一下QQ群,问问群里负责导入的大佬。
|
||||
|
||||
## 第三部分 关于其他问题
|
||||
|
||||
**由于开发者们都很忙,群友们的耐心也都有限,所以恳请大家提出有意义的问题。这里附一个关于提问方法的链接,大家可以看看。**
|
||||
|
||||
[提问的智慧](https://github.com/tvvocold/How-To-Ask-Questions-The-Smart-Way)
|
||||
|
||||
希望不要我把这个文件在聊天中甩给你,那说明我可能已经没有耐心了。
|
||||
|
||||
看完这份说明,如果你打算开始使用我们的工具的话,请移步至[这里](https://gitee.com/EillesWan/Musicreater/blob/pkgver/docs/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)。
|
||||
|
||||
## 结尾
|
||||
|
||||
### 作者\<*金羿*\>(Eilles)联系方式
|
||||
|
||||
1. QQ 2647547478
|
||||
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. 微信 WYI_DoctorYI
|
||||
4. Telegram [@EillesWan](https://t.me/EillesWan)
|
||||
|
||||
### 作者\<*诸葛亮与八卦阵*\>(bgArray)联系方式
|
||||
|
||||
1. QQ 4740437765
|
||||
|
||||
**欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)**
|
||||
|
||||
**欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)**
|
||||
|
||||
**欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)**
|
||||
|
||||
(重要的事情说三遍)
|
||||
|
||||
**(有能力的同志麻烦给仓库star一下)**
|
||||
|
||||
**(有能力的同志麻烦给仓库star一下)**
|
||||
|
||||
**(有能力的同志麻烦给仓库star一下)**
|
||||
32
docs/生成文件的使用说明.md
Normal file
32
docs/生成文件的使用说明.md
Normal file
@@ -0,0 +1,32 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<h2 align="center">库版 Package Version</h2>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
# 生成文件的使用说明
|
||||
|
||||
*由于先前的 **读我文件**(README.md) 过于冗杂,现另辟蹊径来给大家全方位的教程。*
|
||||
|
||||
*这是本库生成后文件的相关说明,不是使用本库的教程,若要查看**本库的演示程序**使用教程,可点击[此处](%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)*
|
||||
|
||||
## 文件格式
|
||||
|
||||
1. 附加包格式(`.mcpack`)
|
||||
|
||||
使用附加包格式导出音乐,则音乐会以指令函数文件(`.mcfunction`)存储于附加包内。在附加包中,函数文件的存储结构应为:
|
||||
|
||||
- `functions\`
|
||||
- `index.mcfunction`
|
||||
- `mscply\`
|
||||
- `progressShow.mcfunction`
|
||||
- `track1.mcfunction`
|
||||
- `track2.mcfunction`
|
||||
- ...
|
||||
- `trackN.mcfunction`
|
||||
|
||||
如图,其中,`index.mcfunction`文件和`mscply`文件夹存在于函数目录的根下;在`mscply`目录中,包含音乐导出的众多音轨播放文件(`trackX.mcfunction`),同时,若生成此包时选择了带有进度条的选项,则会包含`progressShow.mcfunction`文件。
|
||||
|
||||
`index.mcfunction`用于开始播放,其中包含打开各个音轨对应函数的指令,以及加分指令,这里的加分,是将**播放计分板的值大于等于`1`**的所有**玩家**的播放计分板分数增加`1`。同时,若生成此包时选择了自动重置计分板的选项,则会包含一条重置计分板的指令。
|
||||
18
example_convert_bdx.py
Normal file
18
example_convert_bdx.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# THIS PROGRAM IS ONLY A TEST EXAMPLE
|
||||
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
convertion = midiConvert()
|
||||
convertion.convert(input('请输入midi文件路径:'), input('请输入输出路径:'))
|
||||
for i in convertion.toBDXfile(
|
||||
1,
|
||||
input('请输入作者:'),
|
||||
bool(int(input('是否开启进度条(1|0):'))),
|
||||
int(input('请输入指令结构最大生成高度:')),
|
||||
input('请输入计分板名称:'),
|
||||
float(input('请输入音量(0-1]:')),
|
||||
float(input('请输入速度倍率:')),
|
||||
bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
):
|
||||
print(i)
|
||||
24
example_convert_linear_mcpack.py
Normal file
24
example_convert_linear_mcpack.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# THIS PROGRAM IS ONLY A TEST EXAMPLE
|
||||
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
convertion = midiConvert()
|
||||
convertion.convert(input("请输入midi文件路径:"), input("请输入输出路径:"))
|
||||
print(
|
||||
convertion.tomcpack(
|
||||
3,
|
||||
bool(int(input("是否自动重置计分板(1|0):"))),
|
||||
bool(int(input("是否开启进度条(1|0):"))),
|
||||
input("请输入计分板名称:"),
|
||||
float(input("请输入音量(0-1):")),
|
||||
float(input("请输入速度倍率:")),
|
||||
)
|
||||
)
|
||||
|
||||
# for the test
|
||||
# if __name__ == '__main__':
|
||||
# convertion = midiConvert()
|
||||
# convertion.convert(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\victory.mid", ".")
|
||||
# convertion.tomcpack(
|
||||
# 1, True, True, "scb", 1, 1)
|
||||
22
example_convert_mcpack.py
Normal file
22
example_convert_mcpack.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# THIS PROGRAM IS ONLY A TEST EXAMPLE
|
||||
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
convertion = midiConvert()
|
||||
convertion.convert(input('请输入midi文件路径:'), input('请输入输出路径:'))
|
||||
convertion.tomcpack(
|
||||
1,
|
||||
bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
bool(int(input('是否开启进度条(1|0):'))),
|
||||
input('请输入计分板名称:'),
|
||||
float(input('请输入音量(0-1):')),
|
||||
float(input('请输入速度倍率:')),
|
||||
)
|
||||
|
||||
# for the test
|
||||
# if __name__ == '__main__':
|
||||
# convertion = midiConvert()
|
||||
# convertion.convert(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\victory.mid", ".")
|
||||
# convertion.tomcpack(
|
||||
# 1, True, True, "scb", 1, 1)
|
||||
BIN
logo_done_c_Finish_C_Done_CCC_1024px.ico
Normal file
BIN
logo_done_c_Finish_C_Done_CCC_1024px.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
343
magicDemo.py
Normal file
343
magicDemo.py
Normal file
@@ -0,0 +1,343 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 MIDI转换示例程序
|
||||
Musicreater Package Version : Demo for Midi Conversion
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ./Lisence.md
|
||||
Terms & Conditions: ./Lisence.md
|
||||
"""
|
||||
|
||||
languages = {
|
||||
"ZH_CN": {
|
||||
"MSCT": "音·创",
|
||||
"ChooseLang": "选择语言",
|
||||
"LangChd": "当前语言已经切换为",
|
||||
"ZH_CN": "简体中文",
|
||||
"ZH_TW": "繁体中文(台湾)",
|
||||
"EN_GB": "英语(英国)",
|
||||
"EN_US": "英语(美国)",
|
||||
":": ":",
|
||||
",": ",",
|
||||
".": "。",
|
||||
"ChooseFileFormat": "请输入输出格式[BDX(1)或MCPACK(0)]",
|
||||
"ChoosePlayer": "请选择播放方式[计分板(1) 或 延迟(0)]",
|
||||
"ChoosePath": "请输入MIDI路径或所在文件夹",
|
||||
"WhetherArgEntering": "是否为文件夹内文件的转换统一参数[是(1) 或 否(0)]",
|
||||
"EnterArgs": "请输入转换参数",
|
||||
"noteofArgs": "注:文件夹内的全部midi将统一以此参数转换",
|
||||
"ChooseSbReset": "是否自动重置计分板[是(1) 或 否(0)]",
|
||||
"WhetherCstmProgressBar": "是否自定义进度条[是(1) 或 否(0)]",
|
||||
"EnterProgressBarStyle": "请输入进度条样式",
|
||||
"EnterSbName": "请输入计分板名称",
|
||||
"EnterVolume": "请输入音量大小(0~1)",
|
||||
"EnterSpeed": "请输入速度倍率",
|
||||
"EnterAuthor": "请输入作者",
|
||||
"EnterMaxHeight": "请输入指令结构最大生成高度",
|
||||
"ErrEnter": "输入错误",
|
||||
"Re-Enter": "请重新输入",
|
||||
"Dealing": "正在处理",
|
||||
"FileNotFound": "文件(夹)不存在",
|
||||
"ChooseOutPath": "请输入结果输出路径",
|
||||
"EnterSelecter": "请输入播放者选择器",
|
||||
"Saying": "言·论",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
if sys.argv.__len__() > 0:
|
||||
currentLang = sys.argv[0]
|
||||
if not currentLang in languages.keys():
|
||||
currentLang = "ZH_CN"
|
||||
else:
|
||||
currentLang = "ZH_CN"
|
||||
|
||||
|
||||
def _(__):
|
||||
'''
|
||||
`languages`
|
||||
'''
|
||||
return languages[currentLang][__]
|
||||
|
||||
|
||||
import os
|
||||
import random
|
||||
import datetime
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
try:
|
||||
from rich.console import Console
|
||||
except ModuleNotFoundError as E:
|
||||
if input("您需要安装 Rich 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'):
|
||||
os.system("pip install Rich -i https://mirrors.aliyun.com/pypi/")
|
||||
from rich.console import Console
|
||||
else:
|
||||
raise E
|
||||
|
||||
try:
|
||||
import zhdate
|
||||
except ModuleNotFoundError as E:
|
||||
if input("您需要安装 zhdate 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'):
|
||||
os.system("pip install zhdate -i https://mirrors.aliyun.com/pypi/")
|
||||
import zhdate
|
||||
else:
|
||||
raise E
|
||||
|
||||
|
||||
try:
|
||||
import requests
|
||||
except ModuleNotFoundError as E:
|
||||
if input("您需要安装 requests 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'):
|
||||
os.system("pip install requests -i https://mirrors.aliyun.com/pypi/")
|
||||
import requests
|
||||
else:
|
||||
raise E
|
||||
|
||||
|
||||
MainConsole = Console()
|
||||
|
||||
MainConsole.print(
|
||||
"[#121110 on #F0F2F4] ",
|
||||
style="#121110 on #F0F2F4",
|
||||
justify="center",
|
||||
)
|
||||
|
||||
|
||||
# 显示大标题
|
||||
MainConsole.rule(title="[bold #AB70FF]欢迎使用音·创独立转换器", characters="=", style="#26E2FF")
|
||||
MainConsole.rule(
|
||||
title="[bold #AB70FF]Welcome to Independent Musicreater Convernter", characters="-"
|
||||
)
|
||||
|
||||
|
||||
# 显示箴言部分
|
||||
MainConsole.print(
|
||||
"[#121110 on #F0F2F4]"
|
||||
+ random.choice(
|
||||
requests.get(
|
||||
"https://gitee.com/EillesWan/Musicreater/raw/master/resources/myWords.txt"
|
||||
)
|
||||
.text.strip("\r\n")
|
||||
.split("\r\n")
|
||||
),
|
||||
style="#121110 on #F0F2F4",
|
||||
justify="center",
|
||||
)
|
||||
|
||||
|
||||
from typing import Any, Literal, Optional, TextIO
|
||||
|
||||
JustifyMethod = Literal["default", "left", "center", "right", "full"]
|
||||
OverflowMethod = Literal["fold", "crop", "ellipsis", "ignore"]
|
||||
|
||||
# 高级的打印函数
|
||||
def prt(
|
||||
*objects: Any,
|
||||
sep: str = " ",
|
||||
end: str = "\n",
|
||||
justify: Optional[JustifyMethod] = None,
|
||||
overflow: Optional[OverflowMethod] = None,
|
||||
no_wrap: Optional[bool] = None,
|
||||
emoji: Optional[bool] = None,
|
||||
markup: Optional[bool] = None,
|
||||
highlight: Optional[bool] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
crop: bool = True,
|
||||
soft_wrap: Optional[bool] = None,
|
||||
new_line_start: bool = False,
|
||||
) -> None:
|
||||
"""打印到控制台。
|
||||
|
||||
Args:
|
||||
objects (位置性的args): 要记录到终端的对象。
|
||||
sep (str, 可选): 要在打印数据之间写入的字符串。默认为""。
|
||||
end (str, optio可选nal): 在打印数据结束时写入的字符串。默认值为"\\\\n"。
|
||||
style (Union[str, Style], 可选): 应用于输出的样式。默认为`None`。
|
||||
justify (str, 可选): 校正位置,可为"default", "left", "right", "center" 或 "full". 默认为`None`。
|
||||
overflow (str, 可选): 控制溢出:"ignore"忽略, "crop"裁剪, "fold"折叠, "ellipsis"省略号。默认为`None`。
|
||||
no_wrap (Optional[bool], 可选): 禁用文字包装。默认为`None`。
|
||||
emoji (Optional[bool], 可选): 启用表情符号代码,或使用控制台默认的`None`。默认为`None`。
|
||||
markup (Optional[bool], 可选): 启用标记,或`None`使用控制台默认值。默认为`None`。
|
||||
highlight (Optional[bool], 可选): 启用自动高亮,或`None`使用控制台默认值。默认为`None`。
|
||||
width (Optional[int], 可选): 输出的宽度,或`None`自动检测。默认为`None`。
|
||||
crop (Optional[bool], 可选): 裁剪输出到终端的宽度。默认为`True`。
|
||||
soft_wrap (bool, 可选): 启用软包装模式,禁止文字包装和裁剪,或`None``用于 控制台默认值。默认为`None`。
|
||||
new_line_start (bool, False): 如果输出包含多行,在开始时插入一个新行。默认值为`False`。
|
||||
"""
|
||||
MainConsole.print(
|
||||
*objects,
|
||||
sep=sep,
|
||||
end=end,
|
||||
style="#F0F2F4 on #121110",
|
||||
justify=justify,
|
||||
overflow=overflow,
|
||||
no_wrap=no_wrap,
|
||||
emoji=emoji,
|
||||
markup=markup,
|
||||
highlight=highlight,
|
||||
width=width,
|
||||
height=height,
|
||||
crop=crop,
|
||||
soft_wrap=soft_wrap,
|
||||
new_line_start=new_line_start,
|
||||
)
|
||||
|
||||
|
||||
prt(f"{_('LangChd')}{_(':')}{_(currentLang)}")
|
||||
|
||||
# 高级的输入函数
|
||||
def ipt(
|
||||
*objects: Any,
|
||||
sep: str = " ",
|
||||
justify: Optional[JustifyMethod] = None,
|
||||
overflow: Optional[OverflowMethod] = None,
|
||||
no_wrap: Optional[bool] = None,
|
||||
emoji: Optional[bool] = None,
|
||||
markup: Optional[bool] = None,
|
||||
highlight: Optional[bool] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
crop: bool = True,
|
||||
soft_wrap: Optional[bool] = None,
|
||||
new_line_start: bool = False,
|
||||
password: bool = False,
|
||||
stream: Optional[TextIO] = None,
|
||||
) -> str:
|
||||
"""显示一个提示并等待用户的输入。
|
||||
|
||||
它的工作方式与Python内建的 :func:`input` 函数相同,如果Python内建的 :mod:`readline` 模块先前已经加载,则提供详细的行编辑和历史功能。
|
||||
|
||||
Args:
|
||||
objects (位置性的args): 要记录到终端的对象。
|
||||
sep (str, 可选): 要在打印数据之间写入的字符串。默认为""。
|
||||
end (str, optio可选nal): 在打印数据结束时写入的字符串。默认值为"\\\\n"。
|
||||
style (Union[str, Style], 可选): 应用于输出的样式。默认为`None`。
|
||||
justify (str, 可选): 校正位置,可为"default", "left", "right", "center" 或 "full". 默认为`None`。
|
||||
overflow (str, 可选): 控制溢出:"ignore"忽略, "crop"裁剪, "fold"折叠, "ellipsis"省略号。默认为`None`。
|
||||
no_wrap (Optional[bool], 可选): 禁用文字包装。默认为`None`。
|
||||
emoji (Optional[bool], 可选): 启用表情符号代码,或使用控制台默认的`None`。默认为`None`。
|
||||
markup (Optional[bool], 可选): 启用标记,或`None`使用控制台默认值。默认为`None`。
|
||||
highlight (Optional[bool], 可选): 启用自动高亮,或`None`使用控制台默认值。默认为`None`。
|
||||
width (Optional[int], 可选): 输出的宽度,或`None`自动检测。默认为`None`。
|
||||
crop (Optional[bool], 可选): 裁剪输出到终端的宽度。默认为`True`。
|
||||
soft_wrap (bool, 可选): 启用软包装模式,禁止文字包装和裁剪,或`None``用于 控制台默认值。默认为`None`。
|
||||
new_line_start (bool, False): 如果输出包含多行,在开始时插入一个新行。默认值为`False`。
|
||||
password (bool, 可选): 隐藏已经输入的文案,默认值为`False`。
|
||||
stream (TextIO, 可选): 可选从文件中读取(而非控制台),默认为 `None`。
|
||||
|
||||
Returns:
|
||||
str: 从stdin读取的字符串
|
||||
"""
|
||||
MainConsole.print(
|
||||
*objects,
|
||||
sep=sep,
|
||||
end="",
|
||||
style="#F0F2F4 on #121110",
|
||||
justify=justify,
|
||||
overflow=overflow,
|
||||
no_wrap=no_wrap,
|
||||
emoji=emoji,
|
||||
markup=markup,
|
||||
highlight=highlight,
|
||||
width=width,
|
||||
height=height,
|
||||
crop=crop,
|
||||
soft_wrap=soft_wrap,
|
||||
new_line_start=new_line_start,
|
||||
)
|
||||
|
||||
return MainConsole.input("", password=password, stream=stream)
|
||||
|
||||
|
||||
def formatipt(notice: str, fun, errnote: str = "", *extraArg):
|
||||
'''循环输入,以某种格式
|
||||
notice: 输入时的提示
|
||||
fun: 格式函数
|
||||
errnote: 输入不符格式时的提示
|
||||
*extraArg: 对于函数的其他参数'''
|
||||
while True:
|
||||
result = ipt(notice)
|
||||
try:
|
||||
funresult = fun(result, *extraArg)
|
||||
break
|
||||
except:
|
||||
prt(errnote)
|
||||
continue
|
||||
return result, funresult
|
||||
|
||||
|
||||
# 获取midi列表
|
||||
while True:
|
||||
midipath = ipt(f"{_('ChoosePath')}{_(':')}").lower()
|
||||
if os.path.exists(midipath):
|
||||
if os.path.isfile(midipath):
|
||||
midis = (midipath,)
|
||||
elif os.path.isdir(midipath):
|
||||
midis = tuple(
|
||||
(
|
||||
os.path.join(midipath, i)
|
||||
for i in os.listdir(midipath)
|
||||
if i.lower().endswith('.mid') or i.lower().endswith('.midi')
|
||||
)
|
||||
)
|
||||
else:
|
||||
prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}")
|
||||
continue
|
||||
else:
|
||||
prt(f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}")
|
||||
continue
|
||||
break
|
||||
|
||||
# 获取输出地址
|
||||
outpath = formatipt(
|
||||
f"{_('ChooseOutPath')}{_(':')}",
|
||||
os.path.exists,
|
||||
f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}",
|
||||
).lower()
|
||||
|
||||
|
||||
# 选择输出格式
|
||||
while True:
|
||||
fileFormat = ipt(f"{_('ChooseFileFormat')}{_(':')}").lower()
|
||||
if fileFormat in ('0', 'mcpack'):
|
||||
fileFormat = 0
|
||||
prt(_("EnterArgs"))
|
||||
if len(midis) > 1:
|
||||
prt(_("noteofArgs"))
|
||||
|
||||
elif fileFormat in ('1', 'bdx'):
|
||||
fileFormat = 1
|
||||
while True:
|
||||
playerFormat = ipt(f"{_('ChoosePlayer')}{_(':')}").lower()
|
||||
if playerFormat in ('0', '延迟'):
|
||||
playerFormat = 0
|
||||
elif playerFormat in ('1', '计分板'):
|
||||
playerFormat = 1
|
||||
else:
|
||||
prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}")
|
||||
continue
|
||||
break
|
||||
else:
|
||||
prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}")
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
if fileFormat == 0:
|
||||
pass
|
||||
|
||||
|
||||
MainConsole.input()
|
||||
67
magicFun.py
Normal file
67
magicFun.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 请依照 Apache 2.0 许可证进行许可
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 MIDI转换示例程序
|
||||
Musicreater Package Version : Demo for Midi Conversion
|
||||
|
||||
Copyright 2022 all the developers of Musicreater
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from rich.console import Console
|
||||
|
||||
|
||||
MainConsole = Console()
|
||||
|
||||
import requests
|
||||
import random
|
||||
|
||||
|
||||
# 欸嘿!
|
||||
while True:
|
||||
|
||||
MainConsole.print(
|
||||
"[#121110 on #F0F2F4] ",
|
||||
style="#121110 on #F0F2F4",
|
||||
justify="center",
|
||||
)
|
||||
|
||||
|
||||
MainConsole.rule(title="[bold #AB70FF]欢迎使用音·创独立转换器", characters="=", style="#26E2FF")
|
||||
MainConsole.rule(
|
||||
title="[bold #AB70FF]Welcome to Independent Musicreater Convernter", characters="-"
|
||||
)
|
||||
|
||||
|
||||
MainConsole.print(
|
||||
"[#121110 on #F0F2F4]"
|
||||
+ random.choice(
|
||||
requests.get(
|
||||
"https://gitee.com/EillesWan/Musicreater/raw/master/resources/myWords.txt"
|
||||
)
|
||||
.text.strip("\r\n")
|
||||
.split("\r\n")
|
||||
),
|
||||
style="#121110 on #F0F2F4",
|
||||
justify="center",
|
||||
)
|
||||
|
||||
MainConsole.print()
|
||||
153
mid_analyse.py
Normal file
153
mid_analyse.py
Normal file
@@ -0,0 +1,153 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# Form generated from reading UI file 'mid_analyse.ui'
|
||||
##
|
||||
# Created by: Qt User Interface Compiler version 6.4.1
|
||||
##
|
||||
# WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
##########################################################################
|
||||
|
||||
# from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
# QMetaObject, QObject, QPoint, QRect,
|
||||
# QSize, QTime, QUrl, Qt)
|
||||
# from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
# QFont, QFontDatabase, QGradient, QIcon,
|
||||
# QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
# QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
# from PySide6.QtWidgets import (QApplication, QGroupBox, QHBoxLayout, QLabel,
|
||||
# QLineEdit, QPushButton, QSizePolicy, QWidget)
|
||||
|
||||
import sys
|
||||
from PySide6.QtWidgets import QApplication, QWidget, QGroupBox, QPushButton, \
|
||||
QLabel, QLineEdit, QHBoxLayout, QFileDialog
|
||||
from PySide6.QtCore import QRect, QMetaObject, Slot
|
||||
|
||||
|
||||
class Ui_Form(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.groupBox = None
|
||||
self.horizontalLayout = None
|
||||
self.horizontalLayoutWidget = None
|
||||
self.close_button = None
|
||||
self.fileChoseButton = None
|
||||
self.input_button = None
|
||||
self.note_count_label = None
|
||||
self.note_count_shower = None
|
||||
self.output_button = None
|
||||
|
||||
def setupUi(self, Form):
|
||||
if not Form.objectName():
|
||||
Form.setObjectName(u"Form")
|
||||
Form.resize(582, 355)
|
||||
self.groupBox = QGroupBox(Form)
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.groupBox.setGeometry(QRect(10, 0, 561, 311))
|
||||
self.fileChoseButton = QPushButton(self.groupBox)
|
||||
self.fileChoseButton.setObjectName(u"file_chose_button")
|
||||
self.fileChoseButton.setGeometry(QRect(10, 20, 75, 24))
|
||||
self.note_count_label = QLabel(self.groupBox)
|
||||
self.note_count_label.setObjectName(u"note_count_label")
|
||||
self.note_count_label.setGeometry(QRect(20, 50, 54, 16))
|
||||
self.note_count_shower = QLineEdit(self.groupBox)
|
||||
self.note_count_shower.setObjectName(u"note_count_shower")
|
||||
self.note_count_shower.setGeometry(QRect(70, 50, 113, 20))
|
||||
self.horizontalLayoutWidget = QWidget(Form)
|
||||
self.horizontalLayoutWidget.setObjectName(u"horizontalLayoutWidget")
|
||||
self.horizontalLayoutWidget.setGeometry(QRect(10, 310, 561, 41))
|
||||
self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget)
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.input_button = QPushButton(self.horizontalLayoutWidget)
|
||||
self.input_button.setObjectName(u"input_button")
|
||||
|
||||
self.horizontalLayout.addWidget(self.input_button)
|
||||
|
||||
self.output_button = QPushButton(self.horizontalLayoutWidget)
|
||||
self.output_button.setObjectName(u"output_button")
|
||||
|
||||
self.horizontalLayout.addWidget(self.output_button)
|
||||
|
||||
self.close_button = QPushButton(self.horizontalLayoutWidget)
|
||||
self.close_button.setObjectName(u"close_button")
|
||||
|
||||
self.horizontalLayout.addWidget(self.close_button)
|
||||
|
||||
Form.setWindowTitle("Mid解析器")
|
||||
|
||||
self.groupBox.setTitle("mid信息")
|
||||
self.fileChoseButton.setText("选择文件")
|
||||
self.note_count_label.setText("音符数")
|
||||
self.input_button.setText("导入")
|
||||
self.output_button.setText("导出分析")
|
||||
self.close_button.setText("关闭")
|
||||
|
||||
QMetaObject.connectSlotsByName(Form)
|
||||
|
||||
# self.ui.btnCalculate.clicked.connect(self.fileLoading)
|
||||
|
||||
def fileLoading(self):
|
||||
filePath, _ = QFileDialog.getOpenFileName(
|
||||
self.groupBox, # 父窗口对象
|
||||
"选择文件", # 标题
|
||||
r"./", # 起始目录
|
||||
"mid类型 (*.mid *.midi)" # 选择类型过滤项,过滤内容在括号中
|
||||
)
|
||||
print(filePath)
|
||||
|
||||
@Slot()
|
||||
def on_fileChoseButton_clicked(self):
|
||||
filePath, _ = QFileDialog.getOpenFileName(
|
||||
self.groupBox, # 父窗口对象
|
||||
"选择文件", # 标题
|
||||
r"./", # 起始目录
|
||||
"mid类型 (*.mid *.midi)" # 选择类型过滤项,过滤内容在括号中
|
||||
)
|
||||
print(filePath)
|
||||
|
||||
|
||||
class MidAnalyseGui(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.ui = Ui_Form()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.fileChoseButton.clicked.connect(self.fileLoading)
|
||||
|
||||
def fileLoading(self):
|
||||
filePath, _ = QFileDialog.getOpenFileName(
|
||||
self.ui.groupBox, # 父窗口对象
|
||||
"选择文件", # 标题
|
||||
r"./", # 起始目录
|
||||
"mid类型 (*.mid *.midi)" # 选择类型过滤项,过滤内容在括号中
|
||||
)
|
||||
print(filePath)
|
||||
|
||||
@Slot()
|
||||
def on_fileChoseButton_clicked(self):
|
||||
filePath, _ = QFileDialog.getOpenFileName(
|
||||
self.ui.groupBox, # 父窗口对象
|
||||
"选择文件", # 标题
|
||||
r"./", # 起始目录
|
||||
"mid类型 (*.mid *.midi)" # 选择类型过滤项,过滤内容在括号中
|
||||
)
|
||||
print(filePath)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv) # 创建一个QApplication,也就是你要开发的软件app
|
||||
# MainWindow = QMainWindow() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
# MainWindow = QWidget() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
ui = MidAnalyseGui() # ui是你创建的ui类的实例化对象
|
||||
# ui.setupUi(MainWindow) # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
|
||||
ui.show() # 执行QMainWindow的show()方法,显示这个QMainWindow
|
||||
sys.exit(app.exec()) # 使用exit()或者点击关闭按钮退出QApplication
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
MainWindow = QWidget()
|
||||
ui = Ui_Form()
|
||||
ui.setupUi(MainWindow)
|
||||
ui.show()
|
||||
sys.exit(app.exec())
|
||||
101
mid_analyse.ui
Normal file
101
mid_analyse.ui
Normal file
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>582</width>
|
||||
<height>355</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>561</width>
|
||||
<height>311</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>mid信息</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="file_chose_button">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>75</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="note_count_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>50</y>
|
||||
<width>54</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>音符数</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="note_count_shower">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>50</y>
|
||||
<width>113</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>310</y>
|
||||
<width>561</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="input_button">
|
||||
<property name="text">
|
||||
<string>导入</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="output_button">
|
||||
<property name="text">
|
||||
<string>导出分析</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="close_button">
|
||||
<property name="text">
|
||||
<string>关闭</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
34
msctPkgver/__init__.py
Normal file
34
msctPkgver/__init__.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""一个简单的基于音·创的我的世界音频操作工具"""
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
__version__ = '0.1.0'
|
||||
__all__ = []
|
||||
__author__ = (('金羿', 'Eilles Wan'), ('诸葛亮与八卦阵', 'bgArray'), ('鸣凤鸽子', 'MingFengPigeon'))
|
||||
|
||||
"""
|
||||
音·创 库版 (Musicreater Package Version)
|
||||
是一款免费开源的针对《我的世界:基岩版》的midi音乐转换库
|
||||
Musicreater pkgver (Package Version 音·创 库版)
|
||||
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ../Lisence.md
|
||||
Terms & Conditions: ../Lisence.md
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from .main import *
|
||||
|
||||
print('此Midi转换功能由音·创开发者开发,版权归参与开发的人员共同所有。')
|
||||
print('Copyright © 2022 all the developers of Musicreater')
|
||||
print("小贴:不妨试试Mid-BDX转换网页:在线的多功能Midi转换器")
|
||||
print("https://dislink.github.io/midi2bdx/")
|
||||
|
||||
60
msctPkgver/exceptions.py
Normal file
60
msctPkgver/exceptions.py
Normal file
@@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 (Musicreater Package Version)
|
||||
是一款免费开源的针对《我的世界:基岩版》的midi音乐转换库
|
||||
Musicreater pkgver (Package Version 音·创 库版)
|
||||
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ../Lisence.md
|
||||
Terms & Conditions: ../Lisence.md
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
class MSCTBaseException(Exception):
|
||||
"""音·创库版本的所有错误均继承于此"""
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
|
||||
def 喵(self,):
|
||||
for i in self.args:
|
||||
print(i+"喵!")
|
||||
|
||||
def crash_it(self):
|
||||
raise self
|
||||
|
||||
|
||||
class CrossNoteError(MSCTBaseException):
|
||||
'''同通道下同音符交叉出现所产生的错误'''
|
||||
pass
|
||||
|
||||
|
||||
class NotDefineTempoError(MSCTBaseException):
|
||||
'''没有Tempo设定导致时间无法计算的错误'''
|
||||
pass
|
||||
|
||||
|
||||
class MidiDestroyedError(MSCTBaseException):
|
||||
'''Midi文件损坏'''
|
||||
pass
|
||||
|
||||
class ChannelOverFlowError(MSCTBaseException):
|
||||
'''一个midi中含有过多的通道(数量应≤16)'''
|
||||
pass
|
||||
|
||||
class NotDefineProgramError(MSCTBaseException):
|
||||
'''没有Program设定导致没有乐器可以选择的错误'''
|
||||
pass
|
||||
|
||||
217
msctPkgver/magicmain.py
Normal file
217
msctPkgver/magicmain.py
Normal file
@@ -0,0 +1,217 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需使用或借鉴 请依照 Apache 2.0 许可证进行许可
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 (Musicreater Package Version)
|
||||
是一款免费开源的针对《我的世界:基岩版》的midi音乐转换库
|
||||
注意!除了此源文件以外,任何属于此仓库以及此项目的文件均依照Apache许可证进行许可
|
||||
Musicreater pkgver (Package Version 音·创 库版)
|
||||
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
|
||||
Note! Except for this source file, all the files in this repository and this project are licensed under Apache License 2.0
|
||||
|
||||
Copyright 2022 all the developers of Musicreater
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
|
||||
def _toCmdList_m1(
|
||||
self,
|
||||
scoreboardname: str = "mscplay",
|
||||
volume: float = 1.0,
|
||||
speed: float = 1.0) -> list:
|
||||
"""
|
||||
使用Dislink Sforza的转换思路,将midi转换为我的世界命令列表
|
||||
:param scoreboardname: 我的世界的计分板名称
|
||||
:param volume: 音量,注意:这里的音量范围为(0,1],如果超出将被处理为正确值,其原理为在距离玩家 (1 / volume -1) 的地方播放音频
|
||||
:param speed: 速度,注意:这里的速度指的是播放倍率,其原理为在播放音频的时候,每个音符的播放时间除以 speed
|
||||
:return: tuple(命令列表, 命令个数, 计分板最大值)
|
||||
"""
|
||||
tracks = []
|
||||
if volume > 1:
|
||||
volume = 1
|
||||
if volume <= 0:
|
||||
volume = 0.001
|
||||
|
||||
commands = 0
|
||||
maxscore = 0
|
||||
|
||||
for i, track in enumerate(self.midi.tracks):
|
||||
|
||||
ticks = 0
|
||||
instrumentID = 0
|
||||
singleTrack = []
|
||||
|
||||
for msg in track:
|
||||
ticks += msg.time
|
||||
# print(msg)
|
||||
if msg.is_meta:
|
||||
if msg.type == "set_tempo":
|
||||
tempo = msg.tempo
|
||||
else:
|
||||
if msg.type == "program_change":
|
||||
# print("TT")
|
||||
instrumentID = msg.program
|
||||
if msg.type == "note_on" and msg.velocity != 0:
|
||||
nowscore = round(
|
||||
(ticks * tempo)
|
||||
/ ((self.midi.ticks_per_beat * float(speed)) * 50000)
|
||||
)
|
||||
maxscore = max(maxscore, nowscore)
|
||||
soundID, _X = self.__Inst2soundIDwithX(instrumentID)
|
||||
singleTrack.append(
|
||||
"execute @a[scores={" +
|
||||
str(scoreboardname) +
|
||||
"=" +
|
||||
str(nowscore) +
|
||||
"}" +
|
||||
f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}")
|
||||
commands += 1
|
||||
if len(singleTrack) != 0:
|
||||
tracks.append(singleTrack)
|
||||
|
||||
return [tracks, commands, maxscore]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ============================
|
||||
|
||||
|
||||
|
||||
|
||||
import mido
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class NoteMessage:
|
||||
def __init__(self, channel, pitch, velocity, startT, lastT, midi, now_bpm, change_bpm=None):
|
||||
self.channel = channel
|
||||
self.note = pitch
|
||||
self.velocity = velocity
|
||||
self.startTime = startT
|
||||
self.lastTime = lastT
|
||||
self.tempo = now_bpm # 这里要程序实现获取bpm可以参考我的程序
|
||||
|
||||
def mt2gt(mt, tpb_a, bpm_a):
|
||||
return mt / tpb_a / bpm_a * 60
|
||||
self.startTrueTime = mt2gt(self.startTime, midi.ticks_per_beat, self.tempo) # / 20
|
||||
# delete_extra_zero(round_up())
|
||||
if change_bpm is not None:
|
||||
self.lastTrueTime = mt2gt(self.lastTime, midi.ticks_per_beat, change_bpm) # / 20
|
||||
else:
|
||||
self.lastTrueTime = mt2gt(self.lastTime, midi.ticks_per_beat, self.tempo) # / 20
|
||||
# delete_extra_zero(round_up())
|
||||
print((self.startTime * self.tempo) / (midi.ticks_per_beat * 50000))
|
||||
|
||||
def __str__(self):
|
||||
return "noteMessage channel=" + str(self.channel) + " note=" + str(self.note) + " velocity=" + \
|
||||
str(self.velocity) + " startTime=" + str(self.startTime) + " lastTime=" + str(self.lastTime) + \
|
||||
" startTrueTime=" + str(self.startTrueTime) + " lastTrueTime=" + str(self.lastTrueTime)
|
||||
|
||||
|
||||
def load(mid: mido.MidiFile):
|
||||
|
||||
type_ = [False, False, False] # note_off / note_on+0 / mixed
|
||||
|
||||
is_tempo = False
|
||||
|
||||
# 预检
|
||||
for i, track in enumerate(mid.tracks):
|
||||
for msg in track:
|
||||
# print(msg)
|
||||
if msg.is_meta is not True:
|
||||
if msg.type == 'note_on' and msg.velocity == 0:
|
||||
type_[1] = True
|
||||
elif msg.type == "note_off":
|
||||
type_[0] = True
|
||||
if msg.is_meta is True and msg.type == "set_tempo":
|
||||
is_tempo = True
|
||||
|
||||
if is_tempo is not True:
|
||||
raise Exception("这个mid没有可供计算时间的tempo事件")
|
||||
|
||||
if type_[0] is True and type_[1] is True:
|
||||
type_[2] = True
|
||||
type_[1] = False
|
||||
type_[0] = False
|
||||
print(type_)
|
||||
|
||||
bpm = 0
|
||||
recent_change_bpm = 0
|
||||
is_change_bpm = False
|
||||
# 实检
|
||||
for i, track in enumerate(mid.tracks):
|
||||
noteOn = []
|
||||
trackS = []
|
||||
ticks = 0
|
||||
for msg in track:
|
||||
print(msg)
|
||||
ticks += msg.time
|
||||
print(ticks)
|
||||
if msg.is_meta is True and msg.type == "set_tempo":
|
||||
recent_change_bpm = bpm
|
||||
bpm = 60000000 / msg.tempo
|
||||
is_change_bpm = True
|
||||
|
||||
if msg.type == 'note_on' and msg.velocity != 0:
|
||||
noteOn.append([msg, msg.note, ticks])
|
||||
if type_[1] is True:
|
||||
if msg.type == 'note_on' and msg.velocity == 0:
|
||||
for u in noteOn:
|
||||
index = 0
|
||||
if u[1] == msg.note:
|
||||
lastMessage = u[0]
|
||||
lastTick = u[2]
|
||||
break
|
||||
index += 1
|
||||
print(lastTick)
|
||||
if is_change_bpm and recent_change_bpm != 0:
|
||||
trackS.append(NoteMessage(msg.channel, msg.note, lastMessage.velocity, lastTick, ticks - lastTick,
|
||||
mid, recent_change_bpm, bpm))
|
||||
is_change_bpm = False
|
||||
else:
|
||||
trackS.append(
|
||||
NoteMessage(msg.channel, msg.note, lastMessage.velocity, lastTick, ticks - lastTick,
|
||||
mid, bpm))
|
||||
# print(noteOn)
|
||||
# print(index)
|
||||
try:
|
||||
noteOn.pop(index)
|
||||
except IndexError:
|
||||
noteOn.pop(index - 1)
|
||||
print(trackS)
|
||||
for j in trackS:
|
||||
print(j)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
load(mido.MidiFile("test.mid"))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1547
msctPkgver/main.py
Normal file
1547
msctPkgver/main.py
Normal file
File diff suppressed because it is too large
Load Diff
47
poem.txt
Normal file
47
poem.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
> 是谁把科技的领域布满政治的火药
|
||||
>
|
||||
> 是谁把纯净的蓝天染上暗淡的沉灰
|
||||
>
|
||||
> 中国人民无不热爱自己伟大的祖国
|
||||
>
|
||||
> 我们不会忘记屈辱历史留下的惨痛
|
||||
>
|
||||
> 我们希望世界和平
|
||||
>
|
||||
> 我们希望获得世界的尊重
|
||||
>
|
||||
> 愿世上再也没有战争
|
||||
>
|
||||
> 无论是热还是冷
|
||||
>
|
||||
> 无论是经济还是政治
|
||||
>
|
||||
> 让美妙的和平的优雅的音乐响彻世界
|
||||
>
|
||||
> ——金羿
|
||||
> 2022 5 7
|
||||
|
||||
|
||||
|
||||
> Who has dropped political gunpowder into the technology
|
||||
>
|
||||
> Who has dyed clear blue sky into the dark grey
|
||||
>
|
||||
> All Chinese people love our great homeland
|
||||
>
|
||||
> We *WILL* remember the remain pain of the humiliating history
|
||||
>
|
||||
> We love the whole world but in peace
|
||||
>
|
||||
> We love everyone but under respect
|
||||
>
|
||||
> It is to be hoped that the war ends forever
|
||||
>
|
||||
> Whatever it is cold or hot
|
||||
>
|
||||
> Whatever it is economical or political
|
||||
>
|
||||
> Just let the wonderful music of peace surround the world
|
||||
>
|
||||
> ---- Eilles Wan
|
||||
> 7/5 2022
|
||||
580
pp.py
Normal file
580
pp.py
Normal file
@@ -0,0 +1,580 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# Form generated from reading UI file 'PySide6-Pkg.ui'
|
||||
##
|
||||
# Created by: Qt User Interface Compiler version 6.4.1
|
||||
##
|
||||
# WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
##########################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
|
||||
QCursor, QFont, QFontDatabase, QGradient,
|
||||
QIcon, QImage, QKeySequence, QLinearGradient,
|
||||
QPainter, QPalette, QPixmap, QRadialGradient,
|
||||
QTransform)
|
||||
from PySide6.QtWidgets import (
|
||||
QApplication,
|
||||
QCheckBox,
|
||||
QComboBox,
|
||||
QHBoxLayout,
|
||||
QHeaderView,
|
||||
QLabel,
|
||||
QMainWindow,
|
||||
QMenu,
|
||||
QMenuBar,
|
||||
QSizePolicy,
|
||||
QSlider,
|
||||
QSpinBox,
|
||||
QStatusBar,
|
||||
QTabWidget,
|
||||
QTableWidget,
|
||||
QTableWidgetItem,
|
||||
QTextEdit,
|
||||
QToolButton,
|
||||
QVBoxLayout,
|
||||
QWidget)
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
if not MainWindow.objectName():
|
||||
MainWindow.setObjectName(u"MainWindow")
|
||||
MainWindow.resize(800, 600)
|
||||
self.action = QAction(MainWindow)
|
||||
self.action.setObjectName(u"action")
|
||||
icon = QIcon()
|
||||
iconThemeName = u"document-open"
|
||||
if QIcon.hasThemeIcon(iconThemeName):
|
||||
icon = QIcon.fromTheme(iconThemeName)
|
||||
else:
|
||||
icon.addFile(u".", QSize(), QIcon.Normal, QIcon.Off)
|
||||
|
||||
self.action.setIcon(icon)
|
||||
self.action_Input = QAction(MainWindow)
|
||||
self.action_Input.setObjectName(u"action_Input")
|
||||
self.centralwidget = QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.verticalLayoutWidget = QWidget(self.centralwidget)
|
||||
self.verticalLayoutWidget.setObjectName(u"verticalLayoutWidget")
|
||||
self.verticalLayoutWidget.setGeometry(QRect(0, 0, 951, 611))
|
||||
self.verticalLayout = QVBoxLayout(self.verticalLayoutWidget)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.tabO = QTabWidget(self.verticalLayoutWidget)
|
||||
self.tabO.setObjectName(u"tabO")
|
||||
self.tab = QWidget()
|
||||
self.tab.setObjectName(u"tab")
|
||||
self.verticalLayoutWidget_2 = QWidget(self.tab)
|
||||
self.verticalLayoutWidget_2.setObjectName(u"verticalLayoutWidget_2")
|
||||
self.verticalLayoutWidget_2.setGeometry(QRect(0, 0, 881, 591))
|
||||
self.verticalLayout_2 = QVBoxLayout(self.verticalLayoutWidget_2)
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.tableWidget = QTableWidget(self.verticalLayoutWidget_2)
|
||||
self.tableWidget.setObjectName(u"tableWidget")
|
||||
|
||||
self.verticalLayout_2.addWidget(self.tableWidget)
|
||||
|
||||
self.tabO.addTab(self.tab, "")
|
||||
self.tab_2 = QWidget()
|
||||
self.tab_2.setObjectName(u"tab_2")
|
||||
self.label = QLabel(self.tab_2)
|
||||
self.label.setObjectName(u"label")
|
||||
self.label.setGeometry(QRect(10, 10, 71, 16))
|
||||
self.widget = QWidget(self.tab_2)
|
||||
self.widget.setObjectName(u"widget")
|
||||
self.widget.setGeometry(QRect(0, 30, 281, 131))
|
||||
self.verticalLayoutWidget_3 = QWidget(self.widget)
|
||||
self.verticalLayoutWidget_3.setObjectName(u"verticalLayoutWidget_3")
|
||||
self.verticalLayoutWidget_3.setGeometry(QRect(10, 0, 271, 131))
|
||||
self.verticalLayout_3 = QVBoxLayout(self.verticalLayoutWidget_3)
|
||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||
self.label_2 = QLabel(self.verticalLayoutWidget_3)
|
||||
self.label_2.setObjectName(u"label_2")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.label_2)
|
||||
|
||||
self.label_4 = QLabel(self.verticalLayoutWidget_3)
|
||||
self.label_4.setObjectName(u"label_4")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.label_4)
|
||||
|
||||
self.label_5 = QLabel(self.verticalLayoutWidget_3)
|
||||
self.label_5.setObjectName(u"label_5")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.label_5)
|
||||
|
||||
self.label_7 = QLabel(self.verticalLayoutWidget_3)
|
||||
self.label_7.setObjectName(u"label_7")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.label_7)
|
||||
|
||||
self.label_6 = QLabel(self.verticalLayoutWidget_3)
|
||||
self.label_6.setObjectName(u"label_6")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.label_6)
|
||||
|
||||
self.label_3 = QLabel(self.verticalLayoutWidget_3)
|
||||
self.label_3.setObjectName(u"label_3")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.label_3)
|
||||
|
||||
self.widget_2 = QWidget(self.tab_2)
|
||||
self.widget_2.setObjectName(u"widget_2")
|
||||
self.widget_2.setGeometry(QRect(280, 30, 281, 131))
|
||||
self.verticalLayoutWidget_4 = QWidget(self.widget_2)
|
||||
self.verticalLayoutWidget_4.setObjectName(u"verticalLayoutWidget_4")
|
||||
self.verticalLayoutWidget_4.setGeometry(QRect(10, 0, 271, 131))
|
||||
self.verticalLayout_4 = QVBoxLayout(self.verticalLayoutWidget_4)
|
||||
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
|
||||
self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
|
||||
self.label_9 = QLabel(self.verticalLayoutWidget_4)
|
||||
self.label_9.setObjectName(u"label_9")
|
||||
|
||||
self.verticalLayout_4.addWidget(self.label_9)
|
||||
|
||||
self.label_8 = QLabel(self.verticalLayoutWidget_4)
|
||||
self.label_8.setObjectName(u"label_8")
|
||||
|
||||
self.verticalLayout_4.addWidget(self.label_8)
|
||||
|
||||
self.label_10 = QLabel(self.verticalLayoutWidget_4)
|
||||
self.label_10.setObjectName(u"label_10")
|
||||
|
||||
self.verticalLayout_4.addWidget(self.label_10)
|
||||
|
||||
self.label_12 = QLabel(self.verticalLayoutWidget_4)
|
||||
self.label_12.setObjectName(u"label_12")
|
||||
|
||||
self.verticalLayout_4.addWidget(self.label_12)
|
||||
|
||||
self.label_13 = QLabel(self.verticalLayoutWidget_4)
|
||||
self.label_13.setObjectName(u"label_13")
|
||||
|
||||
self.verticalLayout_4.addWidget(self.label_13)
|
||||
|
||||
self.label_11 = QLabel(self.verticalLayoutWidget_4)
|
||||
self.label_11.setObjectName(u"label_11")
|
||||
|
||||
self.verticalLayout_4.addWidget(self.label_11)
|
||||
|
||||
self.widget_3 = QWidget(self.tab_2)
|
||||
self.widget_3.setObjectName(u"widget_3")
|
||||
self.widget_3.setGeometry(QRect(10, 160, 781, 191))
|
||||
self.verticalLayoutWidget_5 = QWidget(self.widget_3)
|
||||
self.verticalLayoutWidget_5.setObjectName(u"verticalLayoutWidget_5")
|
||||
self.verticalLayoutWidget_5.setGeometry(QRect(0, 0, 781, 191))
|
||||
self.verticalLayout_5 = QVBoxLayout(self.verticalLayoutWidget_5)
|
||||
self.verticalLayout_5.setObjectName(u"verticalLayout_5")
|
||||
self.verticalLayout_5.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.label_14 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_14.setObjectName(u"label_14")
|
||||
|
||||
self.horizontalLayout.addWidget(self.label_14)
|
||||
|
||||
self.comboBox = QComboBox(self.verticalLayoutWidget_5)
|
||||
self.comboBox.setObjectName(u"comboBox")
|
||||
|
||||
self.horizontalLayout.addWidget(self.comboBox)
|
||||
|
||||
self.toolButton = QToolButton(self.verticalLayoutWidget_5)
|
||||
self.toolButton.setObjectName(u"toolButton")
|
||||
|
||||
self.horizontalLayout.addWidget(self.toolButton)
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout)
|
||||
|
||||
self.horizontalLayout_5 = QHBoxLayout()
|
||||
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
||||
self.horizontalLayout_4 = QHBoxLayout()
|
||||
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
||||
self.horizontalLayout_2 = QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
||||
self.label_15 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_15.setObjectName(u"label_15")
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.label_15)
|
||||
|
||||
self.horizontalSlider = QSlider(self.verticalLayoutWidget_5)
|
||||
self.horizontalSlider.setObjectName(u"horizontalSlider")
|
||||
self.horizontalSlider.setOrientation(Qt.Horizontal)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.horizontalSlider)
|
||||
|
||||
self.horizontalLayout_4.addLayout(self.horizontalLayout_2)
|
||||
|
||||
self.label_17 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_17.setObjectName(u"label_17")
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.label_17)
|
||||
|
||||
self.horizontalSlider_3 = QSlider(self.verticalLayoutWidget_5)
|
||||
self.horizontalSlider_3.setObjectName(u"horizontalSlider_3")
|
||||
self.horizontalSlider_3.setOrientation(Qt.Horizontal)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.horizontalSlider_3)
|
||||
|
||||
self.horizontalLayout_5.addLayout(self.horizontalLayout_4)
|
||||
|
||||
self.horizontalLayout_9 = QHBoxLayout()
|
||||
self.horizontalLayout_9.setObjectName(u"horizontalLayout_9")
|
||||
self.label_21 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_21.setObjectName(u"label_21")
|
||||
|
||||
self.horizontalLayout_9.addWidget(self.label_21)
|
||||
|
||||
self.spinBox = QSpinBox(self.verticalLayoutWidget_5)
|
||||
self.spinBox.setObjectName(u"spinBox")
|
||||
|
||||
self.horizontalLayout_9.addWidget(self.spinBox)
|
||||
|
||||
self.horizontalLayout_5.addLayout(self.horizontalLayout_9)
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_5)
|
||||
|
||||
self.horizontalLayout_16 = QHBoxLayout()
|
||||
self.horizontalLayout_16.setObjectName(u"horizontalLayout_16")
|
||||
self.horizontalLayout_13 = QHBoxLayout()
|
||||
self.horizontalLayout_13.setObjectName(u"horizontalLayout_13")
|
||||
self.label_24 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_24.setObjectName(u"label_24")
|
||||
|
||||
self.horizontalLayout_13.addWidget(self.label_24)
|
||||
|
||||
self.comboBox_3 = QComboBox(self.verticalLayoutWidget_5)
|
||||
self.comboBox_3.setObjectName(u"comboBox_3")
|
||||
|
||||
self.horizontalLayout_13.addWidget(self.comboBox_3)
|
||||
|
||||
self.horizontalLayout_6 = QHBoxLayout()
|
||||
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
|
||||
self.label_18 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_18.setObjectName(u"label_18")
|
||||
|
||||
self.horizontalLayout_6.addWidget(self.label_18)
|
||||
|
||||
self.textEdit = QTextEdit(self.verticalLayoutWidget_5)
|
||||
self.textEdit.setObjectName(u"textEdit")
|
||||
self.textEdit.setMaximumSize(QSize(16777215, 22))
|
||||
|
||||
self.horizontalLayout_6.addWidget(self.textEdit)
|
||||
|
||||
self.horizontalLayout_8 = QHBoxLayout()
|
||||
self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
|
||||
self.label_20 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_20.setObjectName(u"label_20")
|
||||
self.label_20.setMaximumSize(QSize(16777215, 22))
|
||||
|
||||
self.horizontalLayout_8.addWidget(self.label_20)
|
||||
|
||||
self.textEdit_2 = QTextEdit(self.verticalLayoutWidget_5)
|
||||
self.textEdit_2.setObjectName(u"textEdit_2")
|
||||
self.textEdit_2.setMaximumSize(QSize(16777215, 22))
|
||||
|
||||
self.horizontalLayout_8.addWidget(self.textEdit_2)
|
||||
|
||||
self.horizontalLayout_6.addLayout(self.horizontalLayout_8)
|
||||
|
||||
self.horizontalLayout_13.addLayout(self.horizontalLayout_6)
|
||||
|
||||
self.horizontalLayout_16.addLayout(self.horizontalLayout_13)
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_16)
|
||||
|
||||
self.horizontalLayout_7 = QHBoxLayout()
|
||||
self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
|
||||
self.label_19 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_19.setObjectName(u"label_19")
|
||||
self.label_19.setMaximumSize(QSize(16777215, 22))
|
||||
|
||||
self.horizontalLayout_7.addWidget(self.label_19)
|
||||
|
||||
self.textEdit1 = QTextEdit(self.verticalLayoutWidget_5)
|
||||
self.textEdit1.setObjectName(u"textEdit1")
|
||||
self.textEdit1.setMaximumSize(QSize(16777215, 22))
|
||||
|
||||
self.horizontalLayout_7.addWidget(self.textEdit1)
|
||||
|
||||
self.horizontalLayout_11 = QHBoxLayout()
|
||||
self.horizontalLayout_11.setObjectName(u"horizontalLayout_11")
|
||||
self.checkBox_2 = QCheckBox(self.verticalLayoutWidget_5)
|
||||
self.checkBox_2.setObjectName(u"checkBox_2")
|
||||
|
||||
self.horizontalLayout_11.addWidget(self.checkBox_2)
|
||||
|
||||
self.checkBox = QCheckBox(self.verticalLayoutWidget_5)
|
||||
self.checkBox.setObjectName(u"checkBox")
|
||||
|
||||
self.horizontalLayout_11.addWidget(self.checkBox)
|
||||
|
||||
self.label_22 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_22.setObjectName(u"label_22")
|
||||
|
||||
self.horizontalLayout_11.addWidget(self.label_22)
|
||||
|
||||
self.textEdit_3 = QTextEdit(self.verticalLayoutWidget_5)
|
||||
self.textEdit_3.setObjectName(u"textEdit_3")
|
||||
self.textEdit_3.setMaximumSize(QSize(16777215, 22))
|
||||
|
||||
self.horizontalLayout_11.addWidget(self.textEdit_3)
|
||||
|
||||
self.horizontalLayout_7.addLayout(self.horizontalLayout_11)
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_7)
|
||||
|
||||
self.horizontalLayout_18 = QHBoxLayout()
|
||||
self.horizontalLayout_18.setObjectName(u"horizontalLayout_18")
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_18)
|
||||
|
||||
self.horizontalLayout_12 = QHBoxLayout()
|
||||
self.horizontalLayout_12.setObjectName(u"horizontalLayout_12")
|
||||
self.label_23 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_23.setObjectName(u"label_23")
|
||||
self.label_23.setMaximumSize(QSize(120, 16777215))
|
||||
|
||||
self.horizontalLayout_12.addWidget(self.label_23)
|
||||
|
||||
self.comboBox_2 = QComboBox(self.verticalLayoutWidget_5)
|
||||
self.comboBox_2.setObjectName(u"comboBox_2")
|
||||
self.comboBox_2.setMaximumSize(QSize(200, 16777215))
|
||||
|
||||
self.horizontalLayout_12.addWidget(self.comboBox_2)
|
||||
|
||||
self.horizontalLayout_14 = QHBoxLayout()
|
||||
self.horizontalLayout_14.setObjectName(u"horizontalLayout_14")
|
||||
self.label_25 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_25.setObjectName(u"label_25")
|
||||
|
||||
self.horizontalLayout_14.addWidget(self.label_25)
|
||||
|
||||
self.comboBox_4 = QComboBox(self.verticalLayoutWidget_5)
|
||||
self.comboBox_4.setObjectName(u"comboBox_4")
|
||||
|
||||
self.horizontalLayout_14.addWidget(self.comboBox_4)
|
||||
|
||||
self.horizontalLayout_12.addLayout(self.horizontalLayout_14)
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_12)
|
||||
|
||||
self.horizontalLayout_15 = QHBoxLayout()
|
||||
self.horizontalLayout_15.setObjectName(u"horizontalLayout_15")
|
||||
self.label_26 = QLabel(self.verticalLayoutWidget_5)
|
||||
self.label_26.setObjectName(u"label_26")
|
||||
|
||||
self.horizontalLayout_15.addWidget(self.label_26)
|
||||
|
||||
self.comboBox_5 = QComboBox(self.verticalLayoutWidget_5)
|
||||
self.comboBox_5.setObjectName(u"comboBox_5")
|
||||
|
||||
self.horizontalLayout_15.addWidget(self.comboBox_5)
|
||||
|
||||
self.verticalLayout_5.addLayout(self.horizontalLayout_15)
|
||||
|
||||
self.tabO.addTab(self.tab_2, "")
|
||||
self.tab_3 = QWidget()
|
||||
self.tab_3.setObjectName(u"tab_3")
|
||||
self.tabO.addTab(self.tab_3, "")
|
||||
self.tab_4 = QWidget()
|
||||
self.tab_4.setObjectName(u"tab_4")
|
||||
self.tabO.addTab(self.tab_4, "")
|
||||
|
||||
self.verticalLayout.addWidget(self.tabO)
|
||||
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QMenuBar(MainWindow)
|
||||
self.menubar.setObjectName(u"menubar")
|
||||
self.menubar.setGeometry(QRect(0, 0, 800, 26))
|
||||
self.menu = QMenu(self.menubar)
|
||||
self.menu.setObjectName(u"menu")
|
||||
MainWindow.setMenuBar(self.menubar)
|
||||
self.statusbar = QStatusBar(MainWindow)
|
||||
self.statusbar.setObjectName(u"statusbar")
|
||||
MainWindow.setStatusBar(self.statusbar)
|
||||
|
||||
self.menubar.addAction(self.menu.menuAction())
|
||||
self.menu.addAction(self.action)
|
||||
self.menu.addAction(self.action_Input)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
|
||||
self.tabO.setCurrentIndex(1)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow)
|
||||
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
MainWindow.setWindowTitle(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"MainWindow", None))
|
||||
self.action.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u6253\u5f00 Open",
|
||||
None))
|
||||
self.action_Input.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u5bfc\u5165 Input",
|
||||
None))
|
||||
self.tabO.setTabText(
|
||||
self.tabO.indexOf(
|
||||
self.tab), QCoreApplication.translate(
|
||||
"MainWindow", u"Tab 1", None))
|
||||
self.label.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_2.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_4.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_5.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_7.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_6.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_3.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_9.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_8.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_10.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_12.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_13.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_11.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"TextLabel", None))
|
||||
self.label_14.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u9ed8\u8ba4\u4fdd\u5b58\u8def\u5f84\uff1a",
|
||||
None))
|
||||
self.toolButton.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow", u"...", None))
|
||||
self.label_15.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u901f\u5ea6\u500d\u7387",
|
||||
None))
|
||||
self.label_17.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u97f3\u91cf\u500d\u7387",
|
||||
None))
|
||||
self.label_21.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u6700\u5927\u6307\u4ee4\u751f\u6210\u9ad8\u5ea6",
|
||||
None))
|
||||
self.label_24.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u9009\u62e9\u5668\u6a21\u5f0f",
|
||||
None))
|
||||
self.label_18.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u8ba1\u5206\u677f\u540d\u79f0",
|
||||
None))
|
||||
self.label_20.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u73a9\u5bb6\u9009\u62e9\u5668",
|
||||
None))
|
||||
self.label_19.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"bdx\u4f5c\u8005\u540d\u79f0",
|
||||
None))
|
||||
self.checkBox_2.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u662f\u5426\u542f\u7528\u8fdb\u5ea6\u6761",
|
||||
None))
|
||||
self.checkBox.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u662f\u5426\u81ea\u5b9a\u4e49\u8fdb\u5ea6\u6761",
|
||||
None))
|
||||
self.label_22.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u81ea\u5b9a\u4e49\u8fdb\u5ea6\u6761\u5185\u5bb9\uff1a",
|
||||
None))
|
||||
self.label_23.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u9009\u62e9\u547d\u4ee4\u683c\u5f0f\u7248\u672c",
|
||||
None))
|
||||
self.label_25.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u9009\u62e9\u8f6c\u6362\u7b97\u6cd5\u7248\u672c",
|
||||
None))
|
||||
self.label_26.setText(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u9009\u62e9\u5bfc\u51fa\u6a21\u5f0f",
|
||||
None))
|
||||
self.tabO.setTabText(
|
||||
self.tabO.indexOf(
|
||||
self.tab_2), QCoreApplication.translate(
|
||||
"MainWindow", u"Tab 2", None))
|
||||
self.tabO.setTabText(
|
||||
self.tabO.indexOf(
|
||||
self.tab_3), QCoreApplication.translate(
|
||||
"MainWindow", u"\u9875", None))
|
||||
self.tabO.setTabText(
|
||||
self.tabO.indexOf(
|
||||
self.tab_4), QCoreApplication.translate(
|
||||
"MainWindow", u"\u9875", None))
|
||||
self.menu.setTitle(
|
||||
QCoreApplication.translate(
|
||||
"MainWindow",
|
||||
u"\u6587\u4ef6",
|
||||
None))
|
||||
# retranslateUi
|
||||
|
||||
|
||||
# Error: PySide6-Pkg.ui: Warning: The name 'textEdit' (QTextEdit) is already in use, defaulting to 'textEdit1'.
|
||||
#
|
||||
#
|
||||
# while executing
|
||||
# 'C:\Users\lc\AppData\Roaming\Python\Python39\site-packages\PySide6\uic
|
||||
# -g python PySide6-Pkg.ui'
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
from PySide6 import QtWidgets
|
||||
|
||||
app = QtWidgets.QApplication(sys.argv) # 创建一个QApplication,也就是你要开发的软件app
|
||||
MainWindow = QtWidgets.QMainWindow() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
# MainWindow = QtWidgets.QWidget() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
ui = Ui_MainWindow() # ui是你创建的ui类的实例化对象
|
||||
ui.setupUi(MainWindow) # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
|
||||
MainWindow.show() # 执行QMainWindow的show()方法,显示这个QMainWindow
|
||||
sys.exit(app.exec_()) # 使用exit()或者点击关闭按钮退出QApplication
|
||||
47
pp_main_write.py
Normal file
47
pp_main_write.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import sys
|
||||
from PySide6.QtWidgets import QApplication, QWidget
|
||||
from PySide6.QtWidgets import QLabel, QPushButton
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtGui import QPixmap
|
||||
|
||||
|
||||
class MusicreaterGUI:
|
||||
def __init__(self):
|
||||
self.button, self.label = None, None
|
||||
|
||||
def setupUi(self, window):
|
||||
window.setWindowTitle("音·创") # 窗口标题
|
||||
window.resize(300, 150) # 重置大小
|
||||
|
||||
self.label = QLabel(window) # 在窗口上创建实例化label
|
||||
string = "welcome to musicreater"
|
||||
self.label.setText(string)
|
||||
self.label.setGeometry(80, 50, 150, 20)
|
||||
|
||||
self.button = QPushButton(window)
|
||||
self.button.setText("close")
|
||||
self.button.setGeometry(120, 100, 50, 20)
|
||||
self.button.clicked.connect(window.close)
|
||||
|
||||
|
||||
class MusicreaterWidget(QWidget, MusicreaterGUI): # 很棒的继承,请 体会
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv) # 创建应用程序实例对象
|
||||
app.setApplicationDisplayName("Musicreater-pp")
|
||||
app.setApplicationVersion("v0.0.1")
|
||||
app.setEffectEnabled(Qt.UI_AnimateCombo)
|
||||
app.setWindowIcon(QPixmap(r"logo_done_c_Finish_C_Done_CCC_1024px.ico"))
|
||||
|
||||
window_ = MusicreaterWidget() # 窗口实例化
|
||||
window_.show()
|
||||
n = app.exec()
|
||||
print(n)
|
||||
try:
|
||||
sys.exit(n)
|
||||
except SystemExit:
|
||||
print("hi, error")
|
||||
@@ -1,49 +0,0 @@
|
||||
[tool.briefcase]
|
||||
project_name = "Musicreater"
|
||||
bundle = "com.ryoun.musicreater"
|
||||
version = "0.0.1"
|
||||
url = "https://musicreater.ryoun.com/musicreater"
|
||||
license = "Apache Software License"
|
||||
author = 'Eilles Wan'
|
||||
author_email = "W-YI_DoctorYI@outlook.com"
|
||||
|
||||
[tool.briefcase.app.musicreater]
|
||||
formal_name = "Musicreater"
|
||||
description = "Musicreater is an Eilles's app that is used for creating musics in Minecraft: Bedrock Edition"
|
||||
icon = "src/musicreater/resources/musicreater"
|
||||
sources = ['src/musicreater']
|
||||
requires = []
|
||||
|
||||
|
||||
[tool.briefcase.app.musicreater.macOS]
|
||||
requires = [
|
||||
'toga-cocoa>=0.3.0.dev20',
|
||||
]
|
||||
|
||||
[tool.briefcase.app.musicreater.linux]
|
||||
requires = [
|
||||
'toga-gtk>=0.3.0.dev20',
|
||||
]
|
||||
system_requires = [
|
||||
'libgirepository1.0-dev',
|
||||
'libcairo2-dev',
|
||||
'libpango1.0-dev',
|
||||
'libwebkitgtk-3.0-0',
|
||||
'gir1.2-webkit-3.0',
|
||||
]
|
||||
|
||||
[tool.briefcase.app.musicreater.windows]
|
||||
requires = [
|
||||
'toga-winforms>=0.3.0.dev20',
|
||||
]
|
||||
|
||||
# Mobile deployments
|
||||
[tool.briefcase.app.musicreater.iOS]
|
||||
requires = [
|
||||
'toga-iOS>=0.3.0.dev20',
|
||||
]
|
||||
|
||||
[tool.briefcase.app.musicreater.android]
|
||||
requires = [
|
||||
'toga-android>=0.3.0.dev20',
|
||||
]
|
||||
1401
src/Musicreater.py
1401
src/Musicreater.py
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
briefcase
|
||||
@@ -1,10 +0,0 @@
|
||||
Metadata-Version: 2.1
|
||||
Briefcase-Version: 0.3.5
|
||||
Name: musicreater
|
||||
Formal-Name: Musicreater
|
||||
App-ID: com.ryoun.musicreater.musicreater
|
||||
Version: 0.0.1
|
||||
Home-page: https://musicreater.ryoun.com/musicreater
|
||||
Author: Eilles Wan
|
||||
Author-email: W-YI_DoctorYI@outlook.com
|
||||
Summary: Musicreater is an Eilles's app that is used for creating musics in Minecraft: Bedrock Edition
|
||||
@@ -1,364 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import threading
|
||||
import sys
|
||||
|
||||
from musicreater.msctspt.threadOpera import NewThread
|
||||
from musicreater.msctspt.bugReporter import version
|
||||
from musicreater.nmcsup.log import log
|
||||
|
||||
__version__ = version.version[1]+version.version[0]
|
||||
__author__ = 'W-YI (金羿)'
|
||||
|
||||
|
||||
log("系统工作————————加载变量及函数")
|
||||
|
||||
|
||||
print("更新执行位置...")
|
||||
|
||||
if sys.platform == 'win32':
|
||||
os.chdir(__file__[:len(__file__)-__file__[len(__file__)::-1].index('\\')])
|
||||
log("更新执行位置,当前文件位置"+__file__)
|
||||
else:
|
||||
try:
|
||||
os.chdir(__file__[:len(__file__) -
|
||||
__file__[len(__file__)::-1].index('/')])
|
||||
except:
|
||||
pass
|
||||
log("其他平台:"+sys.platform+"更新执行位置,当前文件位置"+__file__)
|
||||
print('完成!')
|
||||
|
||||
|
||||
|
||||
print('建立变量,存入内存,载入字典常量函数')
|
||||
|
||||
# 主体部分
|
||||
|
||||
# 支持多文件同时操作
|
||||
|
||||
# dataset[{ 'mainset':{ 'x':'y' }, 'musics': [ { 'set' :{ 'A':'B' } , 'note' : [ [ 'a' , b ], ] }, ] }, ]
|
||||
|
||||
# 编辑:
|
||||
# 修改主设置: dataset[第几个项目]['mainset']['什么设置'] = '设置啥'
|
||||
# 修改音乐: dataset[第几个项目]['musics'][第几个音轨]['notes'][第几个音符][音符还是时间(0,1)] = 改成啥
|
||||
# 修改音轨设置: dataset[第几个项目]['musics'][第几个音轨]['set']['什么设置'] = '设置啥'
|
||||
#
|
||||
# 新增音轨: dataset[第几个项目]['musics'].append(datasetmodelpart)
|
||||
#
|
||||
'''
|
||||
dataset=[
|
||||
{
|
||||
'mainset':{
|
||||
'PackName':"Ryoun",
|
||||
'MusicTitle':'Noname',
|
||||
'IsRepeat':False,
|
||||
'PlayerSelect':''
|
||||
},
|
||||
'musics':[
|
||||
{
|
||||
'set':{
|
||||
'EntityName':'music_support',
|
||||
'ScoreboardName':'music_support',
|
||||
'Instrument':'harp',
|
||||
'FileName':"Music"
|
||||
},
|
||||
'notes':[
|
||||
[0.0,1.0],
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
'''
|
||||
|
||||
global dataset
|
||||
|
||||
dataset = [
|
||||
{
|
||||
'mainset': {
|
||||
'PackName': "Ryoun",
|
||||
'MusicTitle': 'Noname',
|
||||
'IsRepeat': False,
|
||||
'PlayerSelect': ''
|
||||
},
|
||||
'musics': [
|
||||
{
|
||||
'set': {
|
||||
'EntityName': 'MusicSupport',
|
||||
'ScoreboardName': 'MusicSupport',
|
||||
'Instrument': 'note.harp',
|
||||
'FileName': "Music"
|
||||
},
|
||||
'notes': [
|
||||
[0.0, 1.0],
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
global is_new_file
|
||||
global is_save
|
||||
global ProjectName
|
||||
global NowMusic
|
||||
|
||||
is_new_file = True
|
||||
is_save = True
|
||||
ProjectName = ''
|
||||
NowMusic = 0
|
||||
|
||||
def DMM(): # 反回字典用于编辑
|
||||
datasetmodelpart = {
|
||||
'set': {
|
||||
'EntityName': 'MusicSupport',
|
||||
'ScoreboardName': 'MusicSupport',
|
||||
'Instrument': 'note.harp',
|
||||
'FileName': "Music"
|
||||
},
|
||||
'notes': []
|
||||
}
|
||||
return datasetmodelpart
|
||||
|
||||
print("完成")
|
||||
|
||||
# 菜单命令
|
||||
print('加载菜单命令...')
|
||||
|
||||
def exitapp(cmd):
|
||||
|
||||
log("程序正常退出", False)
|
||||
global is_save
|
||||
if is_save == False:
|
||||
if '/s' in cmd:
|
||||
saveProject()
|
||||
else:
|
||||
print("您尚未保存,请使用 /s 开关保存并退出")
|
||||
return False
|
||||
|
||||
try:
|
||||
global dataset
|
||||
del dataset
|
||||
except:
|
||||
pass
|
||||
|
||||
if '/c' in cmd:
|
||||
print("清除log(此句不载入日志)")
|
||||
try:
|
||||
if os.path.exists("./log/"):
|
||||
shutil.rmtree("./log/")
|
||||
if os.path.exists("./logs/"):
|
||||
shutil.rmtree("./logs/")
|
||||
if os.path.exists("./cache/"):
|
||||
shutil.rmtree("./cache/")
|
||||
except:
|
||||
print("无法清除日志及临时文件")
|
||||
|
||||
exit()
|
||||
|
||||
print('退出函数加载完成!')
|
||||
|
||||
print("载入文件读取函数")
|
||||
|
||||
def ReadFile(fn: str):
|
||||
from nmcsup.nmcreader import ReadFile as fileRead
|
||||
k = fileRead(fn)
|
||||
if k == False:
|
||||
log("找不到"+fn)
|
||||
return False
|
||||
else:
|
||||
return k
|
||||
|
||||
def ReadMidi(midfile: str):
|
||||
from nmcsup.nmcreader import ReadMidi as midiRead
|
||||
k = midiRead(midfile)
|
||||
if k == False:
|
||||
log("找不到"+midfile)
|
||||
return False
|
||||
else:
|
||||
return k
|
||||
|
||||
print('完成!')
|
||||
|
||||
print("载入命令函数")
|
||||
|
||||
def saveProject(cmd: list):
|
||||
global is_new_file
|
||||
if '/a' in cmd:
|
||||
log("另存项目")
|
||||
ProjectName = cmd[cmd.index('/a')+1]
|
||||
else:
|
||||
if is_new_file:
|
||||
print("初次存储请使用 /a 开关规定存储文件名")
|
||||
log("文件未保存")
|
||||
return False
|
||||
|
||||
log("存储文件:"+ProjectName)
|
||||
with open(ProjectName, 'w', encoding='utf-8') as f:
|
||||
json.dump(dataset[0], f)
|
||||
global is_save
|
||||
is_save = True
|
||||
|
||||
print('保存项目函数加载完成!')
|
||||
|
||||
def loadMusic(cmd: list):
|
||||
if '/mid' in cmd:
|
||||
th = NewThread(ReadMidi, (cmd[cmd.index('/mid')+1],))
|
||||
th.start()
|
||||
|
||||
def midiSPT(th):
|
||||
for i in th.getResult():
|
||||
datas = DMM()
|
||||
datas['notes'] = i
|
||||
dataset[0]['musics'].append(datas)
|
||||
del th
|
||||
global is_save
|
||||
is_save = False
|
||||
threading.Thread(target=midiSPT, args=(th,)).start()
|
||||
del th
|
||||
elif '/txt' in cmd:
|
||||
th = NewThread(ReadFile, (cmd[cmd.index('/txt')+1],))
|
||||
th.start()
|
||||
|
||||
def midiSPT(th):
|
||||
for i in th.getResult():
|
||||
datas = DMM()
|
||||
datas['notes'] = i
|
||||
dataset[0]['musics'].append(datas)
|
||||
del th
|
||||
global is_save
|
||||
is_save = False
|
||||
threading.Thread(target=midiSPT, args=(th,)).start()
|
||||
elif '/input' in cmd:
|
||||
datas = []
|
||||
for i in cmd[cmd.index('/input')+1:]:
|
||||
datas.append([str(i), 1.0])
|
||||
from nmcsup.trans import note2list
|
||||
datat = DMM()
|
||||
datat['notes'] = note2list(datas)
|
||||
dataset[0]['musics'].append(datat)
|
||||
del datas, datat
|
||||
global is_save
|
||||
is_save = False
|
||||
else:
|
||||
log("无参数,无法读入。")
|
||||
print("请查看帮助文件查看指令格式。")
|
||||
return False
|
||||
|
||||
print('音轨载入函数加载完成!')
|
||||
|
||||
def funBuild(cmd: list):
|
||||
if '/file' in cmd:
|
||||
from msctspt.funcOpera import makeFuncFiles
|
||||
makepath = cmd[cmd.index('/file')+1]
|
||||
if makepath[-1] != '/':
|
||||
makepath += '/'
|
||||
makeFuncFiles(dataset[0], makepath)
|
||||
elif '/directory' in cmd:
|
||||
from msctspt.funcOpera import makeFunDir
|
||||
makepath = cmd[cmd.index('/directory')+1]
|
||||
if makepath[-1] != '/':
|
||||
makepath += '/'
|
||||
makeFunDir(dataset[0], makepath)
|
||||
elif '/mcpack' in cmd:
|
||||
import zipfile
|
||||
from msctspt.funcOpera import makeFunDir
|
||||
makepath = cmd[cmd.index('/mcpack')+1]
|
||||
if makepath[-1] != '/':
|
||||
makepath += '/'
|
||||
|
||||
if not os.path.exists('./temp/'):
|
||||
os.makedirs('./temp/')
|
||||
makeFunDir(dataset[0], './temp/')
|
||||
shutil.move('./temp/'+dataset[0]['mainset']['PackName'] +
|
||||
"Pack/behavior_packs/"+dataset[0]['mainset']['PackName']+"/functions", './')
|
||||
shutil.move('./temp/'+dataset[0]['mainset']['PackName'] + "Pack/behavior_packs/" +
|
||||
dataset[0]['mainset']['PackName']+"/manifest.json", './')
|
||||
with zipfile.ZipFile(makepath+dataset[0]['mainset']['PackName']+'.mcpack', "w") as zipobj:
|
||||
for i in os.listdir('./functions/'):
|
||||
zipobj.write('./functions/'+i)
|
||||
zipobj.write('./manifest.json')
|
||||
shutil.move('./functions', './temp/')
|
||||
shutil.move('./manifest.json', './temp/')
|
||||
shutil.rmtree("./temp/")
|
||||
else:
|
||||
log("无参数,无法读入。")
|
||||
print("请查看帮助文件查看指令格式。")
|
||||
return False
|
||||
|
||||
print("函数建立函数加载完成")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def __main__():
|
||||
|
||||
if sys.platform == 'win32':
|
||||
os.system("cls")
|
||||
else:
|
||||
os.system("clear")
|
||||
|
||||
if sys.platform in ('win32', 'linux'):
|
||||
print("您当前的运行环境为标准桌面,您可以打开 Musicreater.py 运行窗口模式的 音·创")
|
||||
print("您也可以输入 win 指令在不退出命令行模式的同时打开窗口模式\n")
|
||||
|
||||
print(__author__+" 音·创 —— 当前核心版本 "+__version__+'\n')
|
||||
|
||||
nowWorkPath = os.path.split(os.path.realpath(__file__))[0]
|
||||
|
||||
while True:
|
||||
|
||||
strcmd = input("MSCT "+nowWorkPath+">")
|
||||
cmd = strcmd.lower().split(' ')
|
||||
|
||||
if cmd[0] == 'exit':
|
||||
exitapp(cmd[1:])
|
||||
elif cmd[0] == 'save':
|
||||
saveProject(cmd[1:])
|
||||
elif cmd[0] == 'load':
|
||||
loadMusic(cmd[1:])
|
||||
elif cmd[0] == 'win':
|
||||
def run(cmd):
|
||||
os.system(cmd)
|
||||
if sys.platform == 'win32':
|
||||
NewThread(run, ("python "+os.path.split(os.path.realpath(__file__))
|
||||
[0]+"/Musicreater.py",)).start()
|
||||
else:
|
||||
NewThread(run, ("python3 "+os.path.split(os.path.realpath(__file__))
|
||||
[0]+"/Musicreater.py",)).start()
|
||||
elif cmd[0] == 'chdir':
|
||||
nowWorkPath = os.path.realpath(cmd[1])
|
||||
os.chdir(nowWorkPath)
|
||||
elif cmd[0] == 'build':
|
||||
funBuild(cmd[1:])
|
||||
else:
|
||||
os.system(strcmd)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
__main__
|
||||
@@ -1,4 +0,0 @@
|
||||
from musicreater.app import main
|
||||
|
||||
if __name__ == '__main__':
|
||||
main().main_loop()
|
||||
@@ -1,133 +0,0 @@
|
||||
"""
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
"""
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
import toga
|
||||
from toga.style import Pack
|
||||
from toga.style.pack import COLUMN, ROW
|
||||
|
||||
from musicreater.Cmd_Msct import *
|
||||
from musicreater.msctspt.bugReporter import version
|
||||
|
||||
from musicreater.resources.ChineseLang import LANGUAGE
|
||||
|
||||
|
||||
|
||||
__version__ = version.version[1]+version.version[0]
|
||||
__author__ = 'W-YI (金羿)'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if sys.platform == 'win32':
|
||||
os.chdir(__file__[:len(__file__)-__file__[len(__file__)::-1].index('\\')])
|
||||
log("更新执行位置,当前文件位置"+__file__)
|
||||
else:
|
||||
try:
|
||||
os.chdir(__file__[:len(__file__) -
|
||||
__file__[len(__file__)::-1].index('/')])
|
||||
except:
|
||||
pass
|
||||
log("其他平台:"+sys.platform+"更新执行位置,当前文件位置"+__file__)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Musicreater(toga.App):
|
||||
'''音·创 本体\n
|
||||
W-YI 金羿\n
|
||||
QQ 2647547478\n
|
||||
音·创 开发交流群 861684859\n
|
||||
Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com\n
|
||||
版权所有 Team-Ryoun 金羿\n
|
||||
若需转载或借鉴 请附作者\n
|
||||
'''
|
||||
|
||||
|
||||
|
||||
def startup(self):
|
||||
|
||||
|
||||
# Start to draw the window
|
||||
|
||||
main_box = toga.Box(style=Pack(direction=COLUMN))
|
||||
|
||||
self.noticeLabel = toga.Label('MSCT >>>',style=Pack(padding=(0, 5)))
|
||||
|
||||
self.inputBox = toga.TextInput(style=Pack(flex=1))
|
||||
#dispImage = toga.ImageView("./resources/oddevenmatrix.png")
|
||||
|
||||
cmd_box = toga.Box(style=Pack(direction=ROW, padding=5))
|
||||
|
||||
cmd_box.add(self.noticeLabel)
|
||||
cmd_box.add(self.inputBox)
|
||||
# cmd_box.add(dispImage)
|
||||
|
||||
button = toga.Button(
|
||||
LANGUAGE['main']['run'],
|
||||
on_press=self.showMessage,
|
||||
style=Pack(padding=5)
|
||||
)
|
||||
|
||||
|
||||
main_box.add(cmd_box)
|
||||
main_box.add(button)
|
||||
|
||||
|
||||
self.main_window = toga.MainWindow(title=self.formal_name)
|
||||
self.main_window.content = main_box
|
||||
self.main_window.show()
|
||||
|
||||
self.main_window.info_dialog('',"{} {} —— {} {}".format(__author__,LANGUAGE['main']['name'],LANGUAGE['main']['version'],__version__))
|
||||
|
||||
self.nowWorkPath = os.path.split(os.path.realpath(__file__))[0]
|
||||
|
||||
|
||||
def showMessage(self, widget):
|
||||
|
||||
strcmd = self.inputBox.value
|
||||
|
||||
cmd = strcmd.lower().split(' ')
|
||||
|
||||
if cmd[0] == 'exit':
|
||||
if exitapp(cmd[1:]) == False:
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['FormatError'])
|
||||
elif cmd[0] == 'save':
|
||||
if saveProject(cmd[1:]) == False:
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['FormatError'])
|
||||
elif cmd[0] == 'load':
|
||||
if loadMusic(cmd[1:]) == False:
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['FormatError'])
|
||||
elif cmd[0] == 'chdir':
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['NotAvailable'])
|
||||
return
|
||||
nowWorkPath = os.path.realpath(cmd[1])
|
||||
os.chdir(nowWorkPath)
|
||||
elif cmd[0] == 'build':
|
||||
if funBuild(cmd[1:]) == False:
|
||||
self.main_window.info_dialog('',LANGUAGE['command']['FormatError'])
|
||||
else:
|
||||
return
|
||||
os.system(strcmd)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
return Musicreater()
|
||||
@@ -1,141 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__version__ = '0.0.1'
|
||||
__all__ = ['run_server', 'subscribe', 'unsubscribe', 'send_command', 'tellraw']
|
||||
__author__ = 'Fuckcraft <https://gitee.com/fuckcraft>'
|
||||
|
||||
import os
|
||||
import json
|
||||
import uuid
|
||||
import logging
|
||||
import asyncio
|
||||
import time
|
||||
import websockets
|
||||
|
||||
# 写这段代码的时候,只有我和上帝知道这段代码是干什么的。
|
||||
# 现在只有上帝知道。
|
||||
|
||||
# 此函数用于向 Minecraft 订阅请求
|
||||
async def subscribe(websocket, event_name):
|
||||
'''
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要订阅的请求 :
|
||||
|
||||
返回:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'eventName': str(event_name) # 示例:PlayerMessage
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'subscribe',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 消除订阅请求
|
||||
async def unsubscribe(webscket):
|
||||
'''
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要消除订阅的请求 :
|
||||
|
||||
返回:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
"body": {
|
||||
"eventName": str(event_name) # PlayerMessage
|
||||
},
|
||||
"header": {
|
||||
"requestId": str(uuid.uuid4()),
|
||||
"messagePurpose": "unsubscribe",
|
||||
"version": 1,
|
||||
"messageType": "commandRequest"
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 执行命令
|
||||
async def send_command(websocket, command):
|
||||
'''
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: command : 执行的命令 :
|
||||
|
||||
返回:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'origin': {
|
||||
'type': 'player'
|
||||
},
|
||||
'commandLine': str(command),
|
||||
'version': 1
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'commandRequest',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 发送消息
|
||||
async def tellraw(websocket, message):
|
||||
'''
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: message : 发送的消息 :
|
||||
|
||||
返回:
|
||||
None
|
||||
'''
|
||||
|
||||
command = {
|
||||
'rawtext':[
|
||||
{
|
||||
'text':'[{}] {}'.format(time.asctime(), message)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# 增加 json 可读性
|
||||
# command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
command = json.dumps(command)
|
||||
command = 'tellraw @a {}'.format(command)
|
||||
|
||||
await send_command(websocket, command)
|
||||
|
||||
def run_server(function):
|
||||
# 修改 ip 地址和端口
|
||||
start_server = websockets.serve(function, 'localhost', 8080)
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
00:13:19 更新执行位置,当前文件位置F:\W-YI\Programming\音·创\程序\src\musicreater\Cmd_Msct.py
|
||||
00:13:19 更新执行位置,当前文件位置F:\W-YI\Programming\音·创\程序\src\musicreater\app.py
|
||||
@@ -1,173 +0,0 @@
|
||||
音·创(Musicreater)是由金羿(W-YI)开发的一款《我的世界》基岩版音乐生成辅助软件
|
||||
本软件源代码依照Apache软件协议公开。
|
||||
|
||||
Copyright © W-YI 2021
|
||||
|
||||
本软件是金羿前作函数音创和世界音创的集合版本,同时增加了大量功能更新。
|
||||
|
||||
|
||||
To-Do
|
||||
1.可以导出自定义的结构文件用于存储要导入地图中的结构
|
||||
2.进度条
|
||||
3.可以将音乐写入音符盒(红乐)
|
||||
4.更换tk库为briefcase库,支持安卓系统
|
||||
5.支持自动给音符盒绑定更多的音色
|
||||
6.可以由.schematic文件导入地图,亦可反向处理
|
||||
7.支持自定义指令方块区域的长宽高等
|
||||
8.支持自定义创建websockeet服务器播放音乐(感谢由 Fuckcraft <https://github.com/fuckcraft> “鸣凤鸽子”等 带来的我的世界websocket服务器功能)
|
||||
9.支持使用红石播放指令音乐
|
||||
10.支持采用延时的播放器
|
||||
11.支持使用bdx导出结构
|
||||
12.支持采用tp的方法播放
|
||||
13.支持识别曲谱图片解析音乐
|
||||
14.支持使用瀑布流的方式播放音乐
|
||||
15.帮助菜单
|
||||
16.多语言
|
||||
17.支持自动搜寻地图目录位置(网易&微软)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
新更新日志
|
||||
|
||||
Beta 0.0.4.3
|
||||
2021 11 3~2021 12 26
|
||||
1.不断改进包以及代码可读性
|
||||
2.修正部分源码错误
|
||||
3.修正部分格式错误
|
||||
4.加强对Linux系统的支持
|
||||
5.新增命令行模式
|
||||
6.代码中新增大量注释
|
||||
|
||||
|
||||
Beta 0.0.4 ~ Beta 0.0.4.2
|
||||
2021 11 20 ~ 2021 11 21
|
||||
1.完全支持Linux系统
|
||||
2.支持以.RyStruct导出结构
|
||||
3.修复大量bug
|
||||
4.支持拖拽打开(参数1为.msct文件)
|
||||
|
||||
|
||||
Beta 0.0.3.1~0.0.3.5
|
||||
2021 11 1~2021 11 2
|
||||
1.更新部分提示信息使之更加科学
|
||||
2.强制性限制不得使用非Win32平台打开此程序
|
||||
3.支持在Windwos7上使用此程序(发现错误并解决:DLL缺失MSVCP140.dll)
|
||||
4.开始对结构导出进行部分支持
|
||||
5.发现红乐写入的错误,正在排查修复
|
||||
|
||||
|
||||
|
||||
|
||||
Beta 0.0.3
|
||||
2021 10 29 ~ 2021 10 31
|
||||
1.修改部分窗口排版
|
||||
2.修复指令载入地图的结构的错误
|
||||
3.修复指令生成出现的指令错误(感谢 昀梦<QQ1515399885> 找出bug并指正)
|
||||
4.支持生成红石音乐(以音符盒存储的音乐),并写入地图
|
||||
5.修复了生成指令音乐导致的错误
|
||||
6.修复bdx文件y轴过长导致无法生成完毕的错误,现在bdx的y轴为200格
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Beta 0.0.2
|
||||
2021 10 25
|
||||
1.修复了邮件发送错误报告无法生成压缩包的问题
|
||||
2.修复了导入音轨时无法获得进程返回值的问题
|
||||
3.修复了.bdx文件生成时无法选择文件的问题
|
||||
4.修复了生成指令音乐(计分板)没有起始方块的问题
|
||||
5.新增了创建Websocket的功能,可以在localhost:8080创建websocket服务器播放音乐(感谢由 Fuckcraft <https://gitee.com/fuckcraft> “鸣凤鸽子”等 带来的我的世界websocket服务器功能(fcwslib) )
|
||||
6.解决了打包成可执行文件时无法正常退出的问题
|
||||
|
||||
|
||||
|
||||
Beta 0.0.1
|
||||
2021 10月
|
||||
1.支持生成.bdx文件(感谢由 Charlie_Ping “查理平” 带来的bdx转换功能)
|
||||
2.逐步增强对安卓系统的支持
|
||||
3.逐步放弃对Windows的强行要求
|
||||
4.逐步提升性能,增加多线程
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Alpha部分更新日志
|
||||
|
||||
Alpha 0.0.0
|
||||
2021 8 20
|
||||
1.集合了 函数音创0.1.4.1 与 世界音创Beta0.0.1 的功能于本应用
|
||||
2.新增了可以生成 .mcpack 包的方法
|
||||
|
||||
Alpha 0.0.1
|
||||
2021 8 25
|
||||
1.新增两个彩蛋(就是函数音创命令行模式的彩蛋
|
||||
|
||||
Alpha 0.0.1.1
|
||||
2021 8 25
|
||||
1.修复大量已知问题
|
||||
2.修复了部分彩蛋bug,但是程序仍然不会正常退出
|
||||
3.菜单界面优化
|
||||
|
||||
Alpha 0.0.1.2
|
||||
2021.8.29
|
||||
1.修复大量已知问题
|
||||
2.现在可以操作指令文件了
|
||||
3.窗口界面优化
|
||||
|
||||
Alpha 0.0.2
|
||||
2021 9 5
|
||||
1.修复部分已知问题
|
||||
2.指令链导入之时仅生成链式方块且允许折转
|
||||
3.[Dev]正在逐步支持结构导出
|
||||
|
||||
Alpha 0.0.3
|
||||
2021 9 7
|
||||
1.修复指令链转入世界的摆放错误
|
||||
2.指令存储的音乐(包括函数)支持不同玩家不同的播放
|
||||
3.支持播放进度条
|
||||
4.删除彩蛋任务栏图标
|
||||
4.[Dev]已确定导出结构格式
|
||||
|
||||
Alpha 0.0.3.1
|
||||
2021 9 11
|
||||
1.取消输入玩家选择器时不会出现bug了
|
||||
2.删除日志文件修改为删除临时文件
|
||||
3.可以删除用于确认档案存在的文件了
|
||||
|
||||
Alpha 0.0.4
|
||||
2021 10 4-5
|
||||
1.可以将大函数导入世界(以一条链执行多个函数的方式)
|
||||
2.关闭了试听音乐的功能,但是保留其函数于funOpera.py中
|
||||
3.修改部分代码,减少更多bug
|
||||
4.发现指令链转入世界的摆放错误,但是没改正
|
||||
|
||||
1.0.3
|
||||
2021 10 5-6
|
||||
1.解决一些已知问题
|
||||
2.解决了文件读取造成的字符编码问题
|
||||
3.使用PyPinyin库将汉字转化为拼音首字母
|
||||
|
||||
Alpha 0.0.4.1
|
||||
2021 10 9
|
||||
1.将清除日志功能设置为结束后统一清除,避免了清除过程中文件占用导致的问题
|
||||
|
||||
Alpha 0.0.5
|
||||
2021 10 10
|
||||
1.支持使用邮件方式发送错误报告(日志)
|
||||
|
||||
Alpha 0.0.5.1
|
||||
1.修复了邮件发送错误报告无法发送的问题
|
||||
2.修复了打包成.exe文件之后无法正常退出的问题
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
import os
|
||||
import brotli
|
||||
|
||||
'''感谢由 Charlie_Ping “查理平” 带来的bdx转换代码'''
|
||||
|
||||
|
||||
class BdxConverter:
|
||||
__header = "BD@"
|
||||
__bin_header = b"BDX"
|
||||
__generator_author = b"&Charlie_Ping"
|
||||
|
||||
keys = {
|
||||
# x--, x++, addSmallX(-128~127), addX(-32768~32767), addBigX(-2147483648~2147483647)
|
||||
"x": [b"\x0f", b"\x0e", b"\x1c", b"\x14", b"\x15"],
|
||||
"y": [b"\x11", b"\x10", b"\x1d", b"\x16", b"\x17"],
|
||||
"z": [b"\x13", b"\x12", b"\x1e", b"\x18", b"\x19"],
|
||||
"end": b"\x58",
|
||||
"isSigned": b"\x5a",
|
||||
"placeCommandBlockWithData": b"\x1b",
|
||||
"placeBlock": b"\x07"
|
||||
}
|
||||
|
||||
def __init__(self, file_path: str, author: str, blocks):
|
||||
self.author = author
|
||||
self.blocks = blocks
|
||||
self.file_path = file_path
|
||||
self.direction = [0, 0, 0]
|
||||
self.block_type = self.get_block_type
|
||||
self.__file = self.create_and_upload_file
|
||||
|
||||
@property
|
||||
def get_block_type(self):
|
||||
"""
|
||||
blocks
|
||||
[
|
||||
{
|
||||
"direction": [x: int, y: int, z: int],
|
||||
block_name: str,
|
||||
particular_value: int,
|
||||
}
|
||||
]
|
||||
:return: list 给出的所有方块种类名称
|
||||
"""
|
||||
block_type = set()
|
||||
for block in self.blocks:
|
||||
block_type.add(block["block_name"])
|
||||
block_type = list(block_type)
|
||||
return block_type
|
||||
|
||||
@property
|
||||
def create_and_upload_file(self):
|
||||
"""
|
||||
(瞎用property? 害怕
|
||||
创建一个bdx文件
|
||||
要close!
|
||||
:return: 一个文件对象
|
||||
"""
|
||||
_dir = os.path.dirname(self.file_path)
|
||||
if not os.path.isdir(_dir):
|
||||
os.makedirs(_dir)
|
||||
_bytes = self.__bin_header
|
||||
_bytes += b"\x00"
|
||||
_bytes += self.author.encode("utf-8") + self.__generator_author
|
||||
for i in self.block_type:
|
||||
_bytes += b"\x00\x01"
|
||||
_bytes += bytes(i, encoding="utf-8")
|
||||
_bytes += b"\x00"
|
||||
_bytes += self.upload_blocks()
|
||||
_bytes += b"X"
|
||||
with open(self.file_path, "w+") as f:
|
||||
f.write("BD@")
|
||||
f.close()
|
||||
with open(self.file_path, "ab+") as f:
|
||||
f.write(brotli.compress(_bytes))
|
||||
f.close()
|
||||
return
|
||||
def upload_blocks(self):
|
||||
"""
|
||||
计算差值
|
||||
写入移动过程
|
||||
写入方块
|
||||
更新差值
|
||||
:return:
|
||||
"""
|
||||
_types = b""
|
||||
for block in self.blocks:
|
||||
# print(f"当前方块:{block['block_name']}, 位置: {block['direction']}]")
|
||||
diff = self.move_pointer(self.direction, block["direction"])
|
||||
_types += diff
|
||||
if block["block_name"] in ["command_block",
|
||||
"chain_command_block",
|
||||
"repeating_command_block"]:
|
||||
_types += self.obtain_command_block(block)
|
||||
else:
|
||||
_types += self.obtain_universal_block(block)
|
||||
self.direction = block["direction"]
|
||||
return _types
|
||||
|
||||
def move_pointer(self, direction: list, new_direction):
|
||||
"""
|
||||
给出 两个[x, y, z]坐标,返回pointer的移动过程
|
||||
:param direction: 坐标 1
|
||||
:param new_direction: 坐标 2
|
||||
:return: bytes
|
||||
"""
|
||||
_bytes = b""
|
||||
for i, sign in enumerate(["x", "y", "z"]):
|
||||
# print(f"<{sign}> 新-旧={new_direction[i]-direction[i]}")
|
||||
distance = new_direction[i] - direction[i]
|
||||
if distance == 0:
|
||||
# print("距离是0?跳过了")
|
||||
continue
|
||||
_bytes += self.obtain_pointer_type(distance, sign)
|
||||
# print(f"向 {sign} 运动了 {distance} 格子")
|
||||
return _bytes
|
||||
|
||||
@classmethod
|
||||
def obtain_pointer_type(cls, num: int, coordinate: str):
|
||||
"""
|
||||
|
||||
用于确定辅助玩家以某一数据类型走指定长度
|
||||
|
||||
-1 -> 0
|
||||
1 -> 1
|
||||
[128, 127] -> 2
|
||||
[-32768, 32767] -> 3
|
||||
[-2147483648, 2147483647] -> 4
|
||||
:param num:
|
||||
:param coordinate: 坐标轴种类,x y 或 z
|
||||
:return:
|
||||
"""
|
||||
if num == 0:
|
||||
return
|
||||
pointer = 0
|
||||
condition = (num != -1, # byte=0, pointer=1
|
||||
num < -1 or num > 1, # byte=1, pointer=2
|
||||
num < -128 or num > 127, # byte=2, pointer=3
|
||||
num < -32768 or num > 32767, # byte=4, pointer=4
|
||||
)
|
||||
for i in condition:
|
||||
if i:
|
||||
pointer += 1
|
||||
pointer_type = cls.keys[coordinate][pointer]
|
||||
|
||||
byte_len = 2 ** (pointer - 2)
|
||||
if byte_len >= 1:
|
||||
num_byte = num.to_bytes(byte_len, byteorder="big", signed=True)
|
||||
return pointer_type + num_byte
|
||||
return pointer_type
|
||||
|
||||
def obtain_universal_block(self, block):
|
||||
"""
|
||||
给定一个方块, 返回此方块在这个bdx中的id和方块data
|
||||
:param block: {block_name: str,particular_value: int}
|
||||
:return: bytes
|
||||
"""
|
||||
block_id = b"\x07" + self.block_type.index(block["block_name"]).to_bytes(2, byteorder="big", signed=False)
|
||||
particular_value = block["particular_value"].to_bytes(2, byteorder="big", signed=False)
|
||||
block_header = block_id + particular_value
|
||||
return block_header
|
||||
|
||||
def obtain_command_block(self, block):
|
||||
"""
|
||||
给定一个命令方块,返回命令方块各种数据
|
||||
:param block: {
|
||||
"direction": [x: int, y: int, z: int]
|
||||
"block_name": str,
|
||||
"particular_value": int,
|
||||
"impluse": int, # unsigned_int32
|
||||
"command": str,
|
||||
"customName": str,
|
||||
"lastOutput": str, # 没特殊要求写个\x00就得了
|
||||
"tickdelay": int, # int32
|
||||
"executeOnFirstTick": int, # 1 bytes
|
||||
"trackOutput": int, # 1 bytes
|
||||
"conditional": int, # 1 bytes
|
||||
"needRedstone": int # 1 bytes
|
||||
}
|
||||
:return: bytes of command_block
|
||||
"""
|
||||
|
||||
block_id = b"\x1b" + self.block_type.index(block["block_name"]).to_bytes(2, byteorder="big", signed=False)
|
||||
particular_value = block["particular_value"].to_bytes(2, byteorder="big", signed=False)
|
||||
block_header = block_id + particular_value
|
||||
for i in [
|
||||
block["impluse"].to_bytes(4, byteorder="big", signed=False),
|
||||
bytes(block["command"], encoding="utf-8") + b"\x00",
|
||||
bytes(block["customName"], encoding="utf-8") + b"\x00",
|
||||
bytes(block["lastOutput"], encoding="utf-8") + b"\x00",
|
||||
block["tickdelay"].to_bytes(4, byteorder="big", signed=True),
|
||||
block["executeOnFirstTick"].to_bytes(1, byteorder="big"),
|
||||
block["trackOutput"].to_bytes(1, byteorder="big"),
|
||||
block["conditional"].to_bytes(1, byteorder="big"),
|
||||
block["needRedstone"].to_bytes(1, byteorder="big")
|
||||
]:
|
||||
block_header += i
|
||||
return block_header
|
||||
|
||||
if __name__ == '__main__':
|
||||
block = [{"direction": [-1, -1, -1], "block_name": "concrete", "particular_value": 5},
|
||||
{"direction": [1, 5, 1], "block_name": "stained_glass", "particular_value": 7},
|
||||
{"direction": [2, 4, 1], "block_name": "command_block", "particular_value": 3,
|
||||
"impluse": 0,
|
||||
"command": "say A generator test",
|
||||
"customName": "test",
|
||||
"lastOutput": "",
|
||||
"tickdelay": 24,
|
||||
"executeOnFirstTick": 0,
|
||||
"trackOutput": 0,
|
||||
"conditional": 0,
|
||||
"needRedstone": 1
|
||||
},
|
||||
{"direction": [3, 4, 1], "block_name": "concrete", "particular_value": 6},
|
||||
{"direction": [-123412133, 4, 1], "block_name": "concrete", "particular_value": 7}]
|
||||
bdx = BdxConverter("./test02.bdx", "Charlie_Ping",block)
|
||||
@@ -1,134 +0,0 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
'''提供错误报告的基本操作及方法 顺便提供版本更新、安装库等功能'''
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def makeZip(sourceDir, outFilename,compression = 8,exceptFile = None):
|
||||
'''使用compression指定的算法打包目录为zip文件\n
|
||||
默认算法为DEFLATED(8),可用算法如下:\n
|
||||
STORED = 0\n
|
||||
DEFLATED = 8\n
|
||||
BZIP2 = 12\n
|
||||
LZMA = 14\n
|
||||
'''
|
||||
import os, zipfile
|
||||
zipf = zipfile.ZipFile(outFilename, 'w',compression)
|
||||
pre_len = len(os.path.dirname(sourceDir))
|
||||
for parent, dirnames, filenames in os.walk(sourceDir):
|
||||
for filename in filenames:
|
||||
if filename == exceptFile:
|
||||
continue;
|
||||
print(filename)
|
||||
pathfile = os.path.join(parent, filename)
|
||||
arcname = pathfile[pre_len:].strip(os.path.sep) #相对路径
|
||||
zipf.write(pathfile, arcname)
|
||||
|
||||
zipf.close()
|
||||
del zipf,pre_len
|
||||
#以上函数节选并修改自 正在攀登的小蜗牛 的博客:https://blog.csdn.net/qq_21127151/article/details/107503942
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class report():
|
||||
'''发送报告以及相应的任务处理'''
|
||||
def __init__(self,senderName:str = 'Unknown',senderContact:str = 'None',describetion:str = ''):
|
||||
''':param senderName 发送者名称
|
||||
:param senderContact 发送者联系方式
|
||||
:param describetion 问题描述'''
|
||||
self.senderName = senderName;
|
||||
self.senderContact = senderContact;
|
||||
self.describetion = describetion;
|
||||
if not self.senderName :
|
||||
self.senderName = 'Unknown';
|
||||
if not self.senderContact :
|
||||
self.senderContact = 'None';
|
||||
|
||||
|
||||
|
||||
def emailReport(self):
|
||||
'''使用E-mail方法发送当前的日志和临时文件等'''
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText;
|
||||
from email.mime.multipart import MIMEMultipart;
|
||||
from email.header import Header;
|
||||
from musicreater.nmcsup.log import log
|
||||
log("发送错误报告")
|
||||
import os;
|
||||
log("添加标题与正文")
|
||||
msg = MIMEMultipart();
|
||||
#发送者与接收者显示名称
|
||||
msg["From"] = Header(self.senderName,'utf-8');
|
||||
msg["To"] = Header("W-YI (QQ2647547478)",'utf-8');
|
||||
#标题
|
||||
msg["Subject"] = '音·创 - 来自 '+self.senderName+' 的错误报告';
|
||||
#正文
|
||||
msg.attach(MIMEText("来自"+self.senderName+"( "+self.senderContact+" )的错误描述:\n"+self.describetion,'plain','utf-8'));
|
||||
log("添加完毕,正在生成压缩包...")
|
||||
makeZip("./","Temps&Logs.zip",exceptFile="Temps&Logs.zip");
|
||||
attafile=MIMEText(open("Temps&Logs.zip",'rb').read(),"base64",'gb2312');
|
||||
attafile["Content-Type"] = 'application/octet-stream';
|
||||
attafile["Content-Disposition"] = 'attachment;filename="BugReport_from_'+self.senderName+'.zip"';
|
||||
msg.attach(attafile);
|
||||
log("完毕,准备发送")
|
||||
try:
|
||||
smtp = smtplib.SMTP()
|
||||
smtp.connect("smtp.163.com");
|
||||
#SIQQKQQYCZRVIDFJ是授权密码
|
||||
smtp.login("RyounDevTeam@163.com","SIQQKQQYCZRVIDFJ");
|
||||
smtp.sendmail("RyounDevTeam@163.com",["RyounDevTeam@163.com",],msg.as_string())
|
||||
log("错误汇报邮件已发送")
|
||||
except smtplib.SMTPException as e:
|
||||
log("错误汇报邮件发送失败:\n"+str(e));
|
||||
log("清空内存和临时文件")
|
||||
del msg,attafile
|
||||
os.remove("./Temps&Logs.zip")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class version:
|
||||
|
||||
libraries = ('mido','amulet','amulet-core','amulet-nbt','piano_transcription_inference','pypinyin','briefcase','toga','pyinstaller','py7zr','websockets','torch')
|
||||
'''当前开发所需库'''
|
||||
|
||||
version = ('0.0.0','Gamma',)
|
||||
'''当前版本'''
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
self.libraries = version.libraries
|
||||
'''当前开发所需库'''
|
||||
|
||||
self.version = version.version
|
||||
'''当前版本'''
|
||||
|
||||
def installLibraries(self):
|
||||
'''安装全部开发用库'''
|
||||
from sys import platform
|
||||
import os
|
||||
if platform == 'win32':
|
||||
import shutil
|
||||
try:
|
||||
shutil.rmtree(os.getenv('APPDATA')+'\\Musicreater\\')
|
||||
except:
|
||||
pass;
|
||||
for i in self.libraries:
|
||||
print("安装库:"+i)
|
||||
os.system("python -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple")
|
||||
elif platform == 'linux':
|
||||
os.system("sudo apt-get install python3-pip")
|
||||
os.system("sudo apt-get install python3-tkinter")
|
||||
for i in self.libraries:
|
||||
print("安装库:"+i)
|
||||
os.system("sudo python3 -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple")
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""音·创 的函数操作和一些其他功能"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def delPart(Data,starter,ender,includeStart :bool= True,includend :bool= True):
|
||||
'''删除序列从starter物件到ender物件之间的部分\n
|
||||
includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n
|
||||
starter与ender若为None则默认从首或尾开始'''
|
||||
try:
|
||||
if starter == None:
|
||||
includeStart = True;
|
||||
starter = Data[0];
|
||||
if ender == None:
|
||||
includend = True;
|
||||
ender = Data[len(Data)-1];
|
||||
if includend:
|
||||
if includeStart:
|
||||
return Data[Data.index(starter):len(Data)-Data[len(Data)::-1].index(ender)];
|
||||
else:
|
||||
return Data[Data.index(starter)+1:len(Data)-Data[len(Data)::-1].index(ender)];
|
||||
else:
|
||||
if includeStart:
|
||||
return Data[Data.index(starter):len(Data)-Data[len(Data)::-1].index(ender)-1];
|
||||
else:
|
||||
return Data[Data.index(starter)+1:len(Data)-Data[len(Data)::-1].index(ender)-1];
|
||||
except:
|
||||
return 0
|
||||
|
||||
|
||||
def keepart(Data,starter,ender,includeStart :bool= True,includend :bool= True):
|
||||
'''保留序列从starter物件到ender物件之间的部分\n
|
||||
includeStart与inclodend分别控制此函数是否包括starter和ender物件所在部分,默认为真\n
|
||||
starter与ender若为None则默认从首或尾开始'''
|
||||
try:
|
||||
if starter == None:
|
||||
includeStart = True;
|
||||
starter = Data[0];
|
||||
if ender == None:
|
||||
includend = True;
|
||||
ender = Data[len(Data)-1];
|
||||
if includend:
|
||||
if includeStart:
|
||||
return Data[Data.index(starter):Data.index(ender)+1];
|
||||
else:
|
||||
return Data[Data.index(starter)+1:Data.index(ender)+1];
|
||||
else:
|
||||
if includeStart:
|
||||
return Data[Data.index(starter):Data.index(ender)];
|
||||
else:
|
||||
return Data[Data.index(starter)+1:Data.index(ender)];
|
||||
except:
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def lenFunction(fun) -> int:
|
||||
'''取得函数指令部分长度,即忽略#开头的注释'''
|
||||
try:
|
||||
l = 0;
|
||||
for i in fun:
|
||||
if i.replace(" ",'')[0] == '#':
|
||||
l += 1;
|
||||
return len(fun)-l;
|
||||
except:
|
||||
return -1;
|
||||
|
||||
|
||||
|
||||
def funSplit(bigFile,maxCmdLen : int = 10000 ):
|
||||
'''分割bigFile大的函数文件,bigFile需要读入文件流\n
|
||||
返回的部分,每行指令皆带有行尾换行符\\n\n
|
||||
返回-1为大小低于maxCmdLen最长函数指令长度'''
|
||||
bigFile = bigFile.readlines()
|
||||
if lenFunction(bigFile) < maxCmdLen:
|
||||
return -1;
|
||||
part = [];
|
||||
parts = [];
|
||||
l = 0;
|
||||
for i in bigFile:
|
||||
if i.replace(" ",'')[0] == '#':
|
||||
part.append(i+'\n');
|
||||
else:
|
||||
part.append(i+'\n');
|
||||
l += 1;
|
||||
if l >= 10000:
|
||||
parts.append(part)
|
||||
part = [];
|
||||
l = 0;
|
||||
return parts;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def makeFuncFiles(musicset, path='./'):
|
||||
from musicreater.nmcsup.log import log
|
||||
'''在指定目录下生成函数文件'''
|
||||
from musicreater.nmcsup.trans import Note2Cmd
|
||||
commands = []
|
||||
starts = []
|
||||
log("=========================正在在此处生成文件:"+path)
|
||||
maxlen = -1
|
||||
for i in range(len(musicset['musics'])):
|
||||
log('写入第'+str(i)+'个数据')
|
||||
commands.append("scoreboard players add @e[name=\""+musicset['musics'][i]['set']['EntityName']+"\"] "+musicset['musics'][i]['set']['ScoreboardName']+" 1\n")
|
||||
commands.append("execute @e[name=\""+musicset['musics'][i]['set']['EntityName'] +"\",scores={"+musicset['musics'][i]['set']['ScoreboardName']+"=1..10}] ~~~ title @a"+musicset['mainset']['PlayerSelect']+" title "+musicset['mainset']['MusicTitle']+"\n")
|
||||
commands.append("execute @e[name=\""+musicset['musics'][i]['set']['EntityName'] +"\",scores={"+musicset['musics'][i]['set']['ScoreboardName']+"=1..10}] ~~~ title @a"+musicset['mainset']['PlayerSelect']+" subtitle 本函数乐曲由§b§l凌云§r§3函数音乐创建§r生成\n")
|
||||
if len(musicset['musics'][i]['notes']) > maxlen:
|
||||
maxlen = len(musicset['musics'][i]['notes'])
|
||||
starts.append("scoreboard objectives add " +musicset['musics'][i]['set']['ScoreboardName']+" dummy\n")
|
||||
starts.append("summon armor_stand " +musicset['musics'][i]['set']['EntityName']+'\n')
|
||||
with open(path+musicset['mainset']['MusicTitle']+'_Part'+str(i)+'.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(Note2Cmd(musicset['musics'][i]['notes'],musicset['musics'][i]['set']['ScoreboardName'],musicset['musics'][i]['set']['Instrument'],musicset['mainset']['PlayerSelect'],True))
|
||||
if musicset['mainset']['IsRepeat']:
|
||||
log("增加重复语句")
|
||||
for i in range(len(musicset['musics'])):
|
||||
commands.append("execute @e[name=\""+musicset['musics'][i]['set']['EntityName']+"\",scores={"+musicset['musics'][i]['set']['ScoreboardName']+"="+str((maxlen+2)*10)+"}] ~~~ scoreboard players set @e[name=\""+musicset['musics'][i]['set']['EntityName']+"\"] "+musicset['musics'][i]['set']['ScoreboardName']+" -1\n")
|
||||
log("增加版权语句")
|
||||
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
starts.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
log("写入支持文件")
|
||||
with open(path+musicset['mainset']['MusicTitle']+'_Support.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(commands)
|
||||
log("写入开始文件")
|
||||
with open(path+'Start_'+musicset['mainset']['MusicTitle']+'.mcfunction', 'w', encoding='UTF-8') as f:
|
||||
f.writelines(starts)
|
||||
del commands, starts, maxlen
|
||||
log("完成============================")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def makeFunDir(musicset, path='./'):
|
||||
from musicreater.nmcsup.log import log
|
||||
'''在指定目录下生成函数包文件夹'''
|
||||
import os
|
||||
import uuid
|
||||
log("=============================生成函数包文件夹")
|
||||
# note,packname="Ryoun",FileName="Music",EntityName_='music_support',ScoreboardName_='music_support',MusicTitle_='Noname',PlayerSelect_='',Repeat_=False,Instrument_='harp'
|
||||
try:
|
||||
os.makedirs(path+musicset['mainset']['PackName'] +"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/functions")
|
||||
log("已创建目录"+path+musicset['mainset']['PackName'] +"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/functions")
|
||||
except:
|
||||
log("目录已有无需创建")
|
||||
pass
|
||||
# 判断文件皆存在
|
||||
if not(os.path.exists(path+musicset['mainset']['PackName']+"Pack/world_behavior_packs.json") and os.path.exists(path+musicset['mainset']['PackName']+"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/manifest.json")):
|
||||
log("创建manifest.json以及world_behavior_packs.json")
|
||||
behaviorUuid = uuid.uuid4()
|
||||
with open(path+musicset['mainset']['PackName']+"Pack/world_behavior_packs.json", "w") as f:
|
||||
f.write("[\n {\"pack_id\": \"" + str(behaviorUuid) +"\",\n \"version\": [ 0, 0, 1 ]}\n]")
|
||||
with open(path+musicset['mainset']['PackName']+"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/manifest.json", "w") as f:
|
||||
f.write("{\n \"format_version\": 1,\n \"header\": {\n \"description\": \""+musicset['mainset']['PackName']+" Pack : behavior pack\",\n \"version\": [ 0, 0, 1 ],\n \"name\": \""+musicset['mainset']['PackName']+"Pack\",\n \"uuid\": \"" + str(behaviorUuid) + "\"\n },\n \"modules\": [\n {\n \"description\": \""+musicset['mainset']['PackName']+" Pack : behavior pack\",\n \"type\": \"data\",\n \"version\": [ 0, 0, 1 ],\n \"uuid\": \"" + str(uuid.uuid4()) + "\"\n }\n ]\n}")
|
||||
makeFuncFiles(musicset, path+musicset['mainset']['PackName'] +"Pack/behavior_packs/"+musicset['mainset']['PackName']+"/functions/")
|
||||
log("完成============================")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
'''
|
||||
这里是往事,用于记载一些用不到的功能
|
||||
|
||||
#存在于 Musicreater.py 播放(试听)音乐
|
||||
def PlayNote(Notes, t=480): # Notes是音符列表,t是一拍占有的毫秒数
|
||||
tkinter.messagebox.showinfo(title='提示!', message="播放发音不一定标准\n说不定还会坏音响/(ㄒoㄒ)/~~qwq\n请注意。")
|
||||
import winsound
|
||||
import time
|
||||
from nmcsup.trans import mcnote2freq
|
||||
Notes = mcnote2freq(Notes)
|
||||
for frequency, duration in Notes:
|
||||
log("播放:"+str([int(frequency), int(duration*t)]))
|
||||
if int(frequency) != 0:
|
||||
winsound.Beep(int(frequency), int(duration*t))
|
||||
elif int(frequency) == 0:
|
||||
time.sleep(duration*t/1000)
|
||||
|
||||
#同上,执行播放命令
|
||||
def PlayOne():
|
||||
log("试听")
|
||||
tkinter.messagebox.showwarning(title="警告⚠", message="试听音质可能引起您的不适,更可能引起您的扬声器的不适,请酌情播放。")
|
||||
global NowMusic
|
||||
PlayNote(dataset[0]['musics'][NowMusic]['notes'])
|
||||
|
||||
|
||||
|
||||
#同上,是早期 MinecraftMusicFunctionMaker.py (函数音创)的代码转移至音·创时的注解
|
||||
n2c(dataset[0]['musics'][i]['notes'],EntityName=dataset[0]['musics'][i]['set']['EntityName'],ScoreboardName=dataset[0]['musics'][i]['set']['ScoreboardName'],PlayerSelect=dataset[0]['mainset']['PlayerSelect'],Instrument=dataset[0]['musics'][i]['set']["Instrument"])
|
||||
|
||||
|
||||
'''
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
|
||||
|
||||
import threading
|
||||
|
||||
|
||||
class NewThread(threading.Thread):
|
||||
'''新建一个进程来运行函数,函数运行完毕后可以使用.getResult方法获取其返回值'''
|
||||
def __init__(self, func, args=()):
|
||||
super(NewThread, self).__init__()
|
||||
self.func = func
|
||||
self.args = args
|
||||
def run(self):
|
||||
self.result = self.func(*self.args)
|
||||
def getResult(self):
|
||||
threading.Thread.join(self) # 等待线程执行完毕
|
||||
try:
|
||||
return self.result
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
#
|
||||
# ————————————————
|
||||
# 版权声明:上面的类NewThread修改自CSDN博主「星火燎愿」的原创文章中的内容,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
||||
# 原文链接:https://blog.csdn.net/xpt211314/article/details/109543014
|
||||
# ————————————————
|
||||
#
|
||||
@@ -1,308 +0,0 @@
|
||||
"""音·创 的转换工具库"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def hans2pinyin(hans,style=3):
|
||||
"""将汉字字符串转化为拼音字符串"""
|
||||
from pypinyin import lazy_pinyin
|
||||
result = lazy_pinyin(hans=hans,style=style)
|
||||
final = ''
|
||||
for i in result:
|
||||
final += i;
|
||||
return final
|
||||
|
||||
|
||||
|
||||
|
||||
def formCmdBlock(direction:list,command:str,particularValue:int,impluse:int,condition:bool=False,needRedstone:bool=True,tickDelay:int=0,customName:str='',lastOutput:str='',executeOnFirstTick:bool=False,trackOutput:bool=True):
|
||||
"""
|
||||
使用指定项目返回指定的指令方块格式字典
|
||||
:param block: {
|
||||
"direction": [x: int, y: int, z: int] #方块位置
|
||||
"block_name": str, #方块名称(无需指定,默认为command_block)
|
||||
"particular_value": int, #方块特殊值
|
||||
"impluse": int, #方块类型0脉冲 1循环 2连锁 unsigned_int32
|
||||
"command": str, #指令
|
||||
"customName": str, #悬浮字
|
||||
"lastOutput": str, #上次输出
|
||||
"tickdelay": int, #方块延时 int32
|
||||
"executeOnFirstTick": int, #执行第一个选项 1 bytes
|
||||
"trackOutput": int, #是否输出 1 bytes
|
||||
"conditional": int, #是否有条件 1 bytes
|
||||
"needRedstone": int #是否需要红石 1 bytes
|
||||
}
|
||||
:return: 指令方块字典结构
|
||||
"""
|
||||
return {"direction": direction,
|
||||
"block_name": "command_block",
|
||||
"particular_value": particularValue,
|
||||
"impluse": impluse,
|
||||
"command": command,
|
||||
"customName": customName,
|
||||
"lastOutput": lastOutput,
|
||||
"tickdelay": tickDelay,
|
||||
"executeOnFirstTick": executeOnFirstTick,
|
||||
"trackOutput": trackOutput,
|
||||
"conditional": condition,
|
||||
"needRedstone": needRedstone
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
def note2bdx(filePath:str,dire:list,Notes : list,ScoreboardName:str,Instrument:str, PlayerSelect:str='',isProsess:bool=False,height:int = 200) :
|
||||
'''使用方法同Note2Cmd
|
||||
:param 参数说明:
|
||||
filePath: 生成.bdx文件的位置
|
||||
dire: 指令方块在地图中生成的起始位置(相对位置)
|
||||
Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes'])
|
||||
ScoreboardName: 用于执行的计分板名称
|
||||
Instrument: 播放的乐器
|
||||
PlayerSelect: 执行的玩家选择器
|
||||
isProsess: 是否显示进度条(会很卡)
|
||||
height: 生成结构的最高高度
|
||||
:return 返回一个BdxConverter类(实际上没研究过),同时在指定位置生成.bdx文件'''
|
||||
|
||||
|
||||
from musicreater.msctspt.transfer import formCmdBlock
|
||||
from musicreater.nmcsup.trans import Note2Cmd
|
||||
from musicreater.msctspt.bdxOpera_CP import BdxConverter
|
||||
cmd = Note2Cmd(Notes,ScoreboardName,Instrument, PlayerSelect,isProsess)
|
||||
cdl = []
|
||||
for i in cmd:
|
||||
try:
|
||||
if (i[:i.index('#')].replace(' ','') != '\n') and(i[:i.index('#')].replace(' ','') != ''):
|
||||
cdl.append(i[:i.index('#')])
|
||||
except:
|
||||
cdl.append(i)
|
||||
i = 0
|
||||
down = False
|
||||
blocks = [formCmdBlock(dire,cdl.pop(0),1,1)]
|
||||
dire[1]+=1;
|
||||
for j in cdl:
|
||||
if dire[1]+i > height:
|
||||
dire[0]+=1
|
||||
i=0
|
||||
down = not down
|
||||
if dire[1]+i == height :
|
||||
blocks.append(formCmdBlock([dire[0],dire[1]+i,dire[2]],j,5,2,False,False))
|
||||
else:
|
||||
if down:
|
||||
blocks.append(formCmdBlock([dire[0],dire[1]+i,dire[2]],j,0,2,False,False))
|
||||
else:
|
||||
blocks.append(formCmdBlock([dire[0],dire[1]+i,dire[2]],j,1,2,False,False))
|
||||
i+=1
|
||||
del i, cdl, down, cmd
|
||||
return BdxConverter(filePath,'Build by RyounMusicreater',blocks)
|
||||
|
||||
|
||||
|
||||
|
||||
def note2webs(Notes : list,Instrument:str, speed:float = 5.0, PlayerSelect:str='',isProsess:bool=False) :
|
||||
'''传入音符,在oaclhost:8080上建立websocket服务器以供我的世界connect/wssever指令连接
|
||||
:param 参数说明:
|
||||
Notes: 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 例如Musicreater.py的(dataset[0]['musics'][NowMusic]['notes'])
|
||||
Instrument: 播放的乐器
|
||||
speed: 用于控制播放速度,数值越大,播放速度越快,相当于把一秒变为几拍
|
||||
PlayerSelect: 执行的玩家选择器
|
||||
isProsess: 是否显示进度条
|
||||
:return None'''
|
||||
|
||||
import time
|
||||
import fcwslib
|
||||
import asyncio
|
||||
from musicreater.nmcsup.log import log
|
||||
from musicreater.nmcsup.vers import VER
|
||||
|
||||
async def run_server(websocket, path):
|
||||
log('服务器连接创建')
|
||||
await fcwslib.tellraw(websocket, '已连接服务器——音·创'+VER[1]+VER[0]+' 作者:金羿(W-YI)')
|
||||
if isProsess:
|
||||
length = len(Notes)
|
||||
j = 1;
|
||||
for i in range(len(Notes)):
|
||||
await fcwslib.send_command(websocket,'execute @a'+PlayerSelect+' ~ ~ ~ playsound '+Instrument+' @s ~ ~ ~ 1000 '+str(Notes[i][0])+' 1000')
|
||||
if isProsess:
|
||||
fcwslib.send_command(websocket,'execute @a'+PlayerSelect+' ~ ~ ~ title @s actionbar §e▶ 播放中: §a'+str(j)+'/'+str(length)+' || '+str(int(j/length*1000)/10))
|
||||
j+=1;
|
||||
time.sleep(Notes[i][1]/speed)
|
||||
|
||||
fcwslib.run_server(run_server)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import amulet
|
||||
from amulet.api.block import Block
|
||||
from amulet.utils.world_utils import block_coords_to_chunk_coords as bc2cc
|
||||
from amulet_nbt import TAG_String as ts
|
||||
from nmcsup.log import log
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def note2RSworld(world:str,startpos:list,notes:list,instrument:str,speed:float = 2.5,posadder:list = [1,0,0],baseblock:str = 'stone') -> bool:
|
||||
'''传入音符,生成以音符盒存储的红石音乐
|
||||
:param 参数说明:
|
||||
world: 地图文件的路径
|
||||
startpos: list[int,int,int] 开始生成的坐标
|
||||
notes: list[list[float,float]] 以 list[ list[ float我的世界playsound指令音调 , float延续时常(单位s) ] ] 格式存储的音符列表 例如Musicreater.py的dataset[0]['musics'][NowMusic]['notes']
|
||||
instrument: 播放的乐器
|
||||
speed: 一拍占多少个中继器延迟(红石刻/rt)
|
||||
posadder: list[int,int,int] 坐标增加规律,即红石的延长时按照此增加规律增加坐标
|
||||
baseblock: 在中继器下垫着啥方块呢~
|
||||
:return 是否生成成功
|
||||
'''
|
||||
|
||||
|
||||
from musicreater.msctspt.values import height2note,instuments
|
||||
|
||||
|
||||
def formNoteBlock(note:int,instrument:str='note.harp',powered:bool = False):
|
||||
'''生成音符盒方块
|
||||
:param note: 0~24
|
||||
:return Block()'''
|
||||
if powered:
|
||||
powered = 'true';
|
||||
else:
|
||||
powered = 'false';
|
||||
return Block('universal_minecraft','noteblock',{"instrument":ts(instrument.replace("note.",'')),'note':ts(str(note)),'powered':ts(powered)})
|
||||
|
||||
def formRepeater(delay:int,facing:str,locked:bool=False,powered:bool=False):
|
||||
'''生成中继器方块
|
||||
:param delay: 1~4
|
||||
:return Block()'''
|
||||
if powered:powered = 'true';
|
||||
else:powered = 'false';
|
||||
if locked:locked = 'true';
|
||||
else:locked = 'false';
|
||||
return Block('universal_minecraft','repeater',{"delay":ts(str(delay)),'facing':ts(facing),'locked':ts(locked),'powered':ts(powered)})
|
||||
|
||||
|
||||
level = amulet.load_level(world)
|
||||
|
||||
def setblock(block:Block,pos:list):
|
||||
'''pos : list[int,int,int]'''
|
||||
cx, cz = bc2cc(pos[0], pos[2])
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz
|
||||
chunk.blocks[offset_x, pos[1], offset_z] = level.block_palette.get_add_block(block)
|
||||
chunk.changed = True
|
||||
|
||||
# 1拍 x 2.5 rt
|
||||
def placeNoteBlock():
|
||||
for i in notes:
|
||||
try :
|
||||
setblock(formNoteBlock(height2note[i[0]],instrument),[startpos[0],startpos[1]+1,startpos[2]])
|
||||
setblock(Block("universal_minecraft",instuments[i[0]][1]),startpos)
|
||||
except :
|
||||
log("无法放置音符:"+str(i)+'于'+str(startpos))
|
||||
setblock(Block("universal_minecraft",baseblock),startpos)
|
||||
setblock(Block("universal_minecraft",baseblock),[startpos[0],startpos[1]+1,startpos[2]])
|
||||
delay = int(i[1]*speed+0.5)
|
||||
if delay <= 4:
|
||||
startpos[0]+=1
|
||||
setblock(formRepeater(delay,'west'),[startpos[0],startpos[1]+1,startpos[2]])
|
||||
setblock(Block("universal_minecraft",baseblock),startpos)
|
||||
else:
|
||||
for i in range(int(delay/4)):
|
||||
startpos[0]+=1
|
||||
setblock(formRepeater(4,'west'),[startpos[0],startpos[1]+1,startpos[2]])
|
||||
setblock(Block("universal_minecraft",baseblock),startpos)
|
||||
if delay % 4 != 0:
|
||||
startpos[0]+=1
|
||||
setblock(formRepeater(delay%4,'west'),[startpos[0],startpos[1]+1,startpos[2]])
|
||||
setblock(Block("universal_minecraft",baseblock),startpos)
|
||||
startpos[0]+=posadder[0]
|
||||
startpos[1]+=posadder[1]
|
||||
startpos[2]+=posadder[2]
|
||||
try:
|
||||
placeNoteBlock()
|
||||
except:
|
||||
log("无法放置方块了,可能是因为区块未加载叭")
|
||||
level.save()
|
||||
level.close()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ryStruct:
|
||||
|
||||
def __init__(self,world:str) -> None:
|
||||
|
||||
|
||||
self.RyStruct = dict()
|
||||
self._world = world
|
||||
self._level = amulet.load_level(world)
|
||||
|
||||
|
||||
def reloadLevel(self):
|
||||
try:
|
||||
self._level = amulet.load_level(self.world)
|
||||
except:
|
||||
log("无法重载地图")
|
||||
|
||||
def closeLevel(self):
|
||||
try:
|
||||
self._level.close()
|
||||
except:
|
||||
log("无法关闭地图")
|
||||
|
||||
|
||||
def world2Rys(self,startp:list,endp:list,includeAir:bool=False):
|
||||
'''将世界转换为RyStruct字典,注意,此函数运行成功后将关闭地图,若要打开需要运行 reloadLevel
|
||||
:param startp: [x,y,z] 转化的起始坐标
|
||||
:param endp : [x,y,z] 转换的终止坐标,注意,终止坐标需要大于起始坐标,且最终结果包含终止坐标
|
||||
:param includeAir : bool = False 是否包含空气,即空气是否在生成之时覆盖地图内容
|
||||
:return dict RyStruct '''
|
||||
|
||||
|
||||
level = self._level
|
||||
|
||||
|
||||
for x in range(startp[0],endp[0]+1):
|
||||
for y in range(startp[1],endp[1]+1):
|
||||
for z in range(startp[2],endp[2]+1):
|
||||
|
||||
RyStructBlock = dict()
|
||||
|
||||
cx, cz = bc2cc(x, z)
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
universal_block = chunk.block_palette[chunk.blocks[x - 16 * cx, y, z - 16 * cz]]
|
||||
if universal_block == Block("universal_minecraft","air") and includeAir:
|
||||
continue
|
||||
universal_block_entity = chunk.block_entities.get((x, y, z), None)
|
||||
|
||||
RyStructBlock["block"] = str(universal_block)
|
||||
RyStructBlock["blockEntity"] = str(universal_block_entity)
|
||||
|
||||
log("载入方块数据"+str(RyStructBlock))
|
||||
|
||||
self.RyStruct[(x,y,z)] = RyStructBlock
|
||||
|
||||
level.close()
|
||||
|
||||
return self.RyStruct
|
||||
|
||||
|
||||
|
||||
'''
|
||||
RyStruct = {
|
||||
(0,0,0) = {
|
||||
"block": str 完整的方块结构
|
||||
"blockEntity": str | 'None'
|
||||
}
|
||||
}
|
||||
'''
|
||||
@@ -1,59 +0,0 @@
|
||||
|
||||
|
||||
instuments = {
|
||||
'note.banjo' : ['班卓琴','hay_block'],
|
||||
'note.bass' : ['贝斯','planks'],
|
||||
'note.bassattack' : ['低音鼓/贝斯','log'],
|
||||
'note.bd' : ['底鼓','stone'], #即basedrum
|
||||
'note.bell' : ['铃铛/钟琴','gold_block'],
|
||||
'note.bit' : ['比特/“芯片”(方波)','emerald_block'],
|
||||
'note.chime' : ['管钟','packed_ice'],
|
||||
'note.cow_bell' : ['牛铃','soul_sand'],
|
||||
'note.didgeridoo' : ['迪吉里杜管','pumpkin'],
|
||||
'note.flute' : ['长笛','clay'],
|
||||
'note.guitar' : ['吉他','wool'],
|
||||
'note.harp' : ['竖琴/钢琴','concrete'], #任意其他类型的方块皆可
|
||||
'note.hat' : ['击鼓沿/架子鼓','glass'],
|
||||
'note.iron_xylophone' : ['“铁木琴”(颤音琴)','iron_block'],
|
||||
'note.pling' : ['“扣弦”(电钢琴)','glowstone'],
|
||||
'note.snare' : ['小军鼓','sand'],
|
||||
'note.xylophone' : ['木琴','bone_block']
|
||||
}
|
||||
'''乐器对照表\n
|
||||
乐器英文:[中文, 对应音符盒下方块名称]
|
||||
注:方块仅取一个'''
|
||||
|
||||
|
||||
|
||||
height2note = {
|
||||
0.5: 0,
|
||||
0.53: 1,
|
||||
0.56: 2,
|
||||
0.6: 3,
|
||||
0.63: 4,
|
||||
0.67: 5,
|
||||
0.7: 6,
|
||||
0.75: 7,
|
||||
0.8: 8,
|
||||
0.84: 9,
|
||||
0.9: 10,
|
||||
0.94: 11,
|
||||
1.0: 12,
|
||||
|
||||
1.05: 13,
|
||||
1.12: 14,
|
||||
1.2: 15,
|
||||
1.25: 16,
|
||||
1.33: 17,
|
||||
1.4: 18,
|
||||
1.5: 19,
|
||||
1.6: 20,
|
||||
1.7: 21,
|
||||
1.8: 22,
|
||||
1.9: 23,
|
||||
2.0: 24,
|
||||
}
|
||||
'''音高对照表\n
|
||||
MC音高:音符盒音调'''
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
从此日志开始,我的世界函数音乐构建更名为 函数音创 NoteFunCreater(谐音NotFun[狗头]),版本号更为0.1.0开始
|
||||
|
||||
注意,运行此文件需要第三方库:
|
||||
1. mido 用于对midi文件的解码
|
||||
2. py7zr 用于对7z压缩包的压缩与解压等(需pycparser, cffi, texttable, pyzstd, pyppmd, pycryptodomex, multivolumefile, brotli, bcj-cffi支持) -(从0.1.3开始不需要)
|
||||
3. zipfile 用于自动生成函数包的压缩
|
||||
4. pystray 用于支持窗口任务栏
|
||||
5. pillow (相当于Python2的PIL)用于绘图
|
||||
|
||||
|
||||
0.1.0
|
||||
2021 7 10 - 2021 7 12
|
||||
1.程序窗口化
|
||||
2.仅支持基本的菜单操作
|
||||
3.程序文件皆储存至其相应目录下
|
||||
4.程序./bin/目录下文件将会自动防修改
|
||||
5.删除了彩蛋
|
||||
|
||||
|
||||
0.1.1
|
||||
2021 7 14
|
||||
1.新增版本辨别的提示
|
||||
2.窗口中显示歌曲信息
|
||||
|
||||
|
||||
0.1.2
|
||||
2021 7 14 - 2021 7 15
|
||||
1.在没运行过的机器上会自动安装库
|
||||
2.从midi导入时不会删除其他音轨
|
||||
3.改进UI样式
|
||||
4.支持对于单个音轨设置的修改以及音乐主设置的修改
|
||||
5.当未保存便退出时,会询问存储
|
||||
6.新增加载进度提示
|
||||
|
||||
|
||||
0.1.3
|
||||
2021 7 15 - 2021 7 19
|
||||
1.不再从文件中读取音符及乐器信息(所以包更小了)
|
||||
2.改进UI
|
||||
3.修复了修改玩家选择器时变更了音乐标题的bug
|
||||
4.新增删除当前选定音轨按钮
|
||||
5.新增重置设置按钮(将音乐总设置设置为开始时的设置)
|
||||
6.运用多线程加载函数与文件等,程序运行效率更高
|
||||
7.修复变量作用域混淆问题
|
||||
|
||||
|
||||
0.1.3.1
|
||||
2021 7 19
|
||||
1.修复了菜单中无法退出程序的问题
|
||||
|
||||
|
||||
0.1.4
|
||||
2021 7 22
|
||||
1.支持显示指令于列表中
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TO-DO
|
||||
1.支持从midi文件的元信息中收取音符信息并自动生成
|
||||
2.支持生成zip函数包
|
||||
3.支持使用WebSocket接口自动播放已编辑的音乐
|
||||
4.可以编辑多个项目
|
||||
5.能够自动将一个长串的音乐分成多个函数文件
|
||||
6.支持用户导入自己的乐器
|
||||
7.支持汇报崩溃记录(通过邮件附件的方式)
|
||||
8.支持播放字幕
|
||||
9.支持任务栏角标与通知
|
||||
10.将控制台版本的彩蛋移植到此版本,开启了任务栏
|
||||
11.可编辑音符
|
||||
@@ -1,36 +0,0 @@
|
||||
世界音创(NoteMapCreater)是金羿开发的一款用于生成我的世界中各类有关音乐的物件的软件
|
||||
软件禁止商用,源代码始终公开,如使用未经授权的音乐经过此软件生成的任何物件侵犯了他人权利与本软件及其作者无关
|
||||
|
||||
Copyright © W-YI 2021
|
||||
|
||||
开头,特别感谢:
|
||||
KCINE:提供Cinemusicedit函数包(虽然函数包没怎么用过)
|
||||
Charlie_Ping:提供MusiCreaterBot(音乐地图生成QQ机器人)源码核心以及时不时的催更(虽然源码没有抄)
|
||||
金羿(作者本人):提供NoteFunCreater(函数音创)的制作经验以及时不时的摸鱼(虽然不是很支持函数音创)
|
||||
广大群友:高效的催更作业让我以蜗牛的速度前进
|
||||
|
||||
Alpha 0.0.0
|
||||
2021 8 1 - 2021 8 10
|
||||
1.确定了大概的功能
|
||||
2.不支持无参数传入
|
||||
3.可以查看帮助,但是帮助大多功能没实现
|
||||
4.可以从格式文本、midi文件、钢琴声音MP3导入音轨
|
||||
5.可以生成一些方块到世界里,但是没有播放器(半支持bw开关)
|
||||
5.提供了修改文件地址的方法,但是不能修改
|
||||
|
||||
Alpha 0.0.1
|
||||
2021 8 10
|
||||
1.可以从函数音创的工程文件读取音轨
|
||||
2.可以新建一个空白世界来生成
|
||||
3.支持修改输出文件地址
|
||||
4.支持修改输出方块起始位置
|
||||
5.支持指定播放乐器,执行实体,执行积分板,播放玩家选择器
|
||||
6.可以生成指令音乐地图(完全支持-w开关)
|
||||
|
||||
Beta 0.0.0
|
||||
2021 8 X?
|
||||
1.除了-nw 和 -f 开关不支持以外都支持了
|
||||
|
||||
Beta 0.0.1
|
||||
2021 8 19
|
||||
1.修复了大量bug
|
||||
@@ -1,320 +0,0 @@
|
||||
"""音创系列的音符对照表 以及一系列常数"""
|
||||
|
||||
|
||||
|
||||
notes = {
|
||||
'....A' : [0.074, 27.5, 'wood', 8],
|
||||
'....A#' : [0.0787, 29.135, 'wood', 9],
|
||||
'....B' : [0.083, 30.868, 'wood', 10],
|
||||
'...C' : [0.088, 32.703, 'wood', 11],
|
||||
'...C#' : [0.094, 34.648, 'wood', 12],
|
||||
'...D' : [0.1, 36.708, 'wood', 13],
|
||||
'...D#' : [0.105, 38.891, 'log', 0],
|
||||
'...E' : [0.11, 41.203, 'log', 1],
|
||||
'...F' : [0.12, 43.654, 'log', 2],
|
||||
'...F#' : [0.125, 46.249, 'wood', 0],
|
||||
'...G' : [0.13, 48.999, 'wood', 1],
|
||||
'...G#' : [0.14, 51.913, 'wood', 2],
|
||||
'...A' : [0.15, 55.0, 'wood', 3],
|
||||
'...A#' : [0.16, 58.27, 'wood', 4],
|
||||
'...B' : [0.17, 61.735, 'wood', 5],
|
||||
'..C' : [0.18, 65.406, 'wool', 0],
|
||||
'..C#' : [0.19, 69.296, 'wool', 1],
|
||||
'..D' : [0.2, 73.416, 'wool', 2],
|
||||
'..D#' : [0.21, 77.782, 'wool', 3],
|
||||
'..E' : [0.22, 82.407, 'wool', 4],
|
||||
'..F' : [0.235, 87.307, 'wool', 5],
|
||||
'..F#' : [0.25, 92.499, 'concretepowder', 0],
|
||||
'..G' : [0.26, 97.999, 'concretepowder', 1],
|
||||
'..G#' : [0.28, 103.826, 'concretepowder', 2],
|
||||
'..A' : [0.3, 110.0, 'concretepowder', 3],
|
||||
'..A#' : [0.31, 116.541, 'concretepowder', 4],
|
||||
'..B' : [0.33, 123.471, 'concretepowder', 5],
|
||||
'.C' : [0.35, 130.813, 'concretepowder', 6],
|
||||
'.C#' : [0.37, 138.591, 'concretepowder', 7],
|
||||
'.D' : [0.4, 146.832, 'concretepowder', 8],
|
||||
'.D#' : [0.42, 155.563, 'concretepowder', 9],
|
||||
'.E' : [0.44, 164.814, 'concretepowder', 10],
|
||||
'.F' : [0.47, 174.614, 'concretepowder', 11],
|
||||
'.F#' : [0.5, 184.997, 'concretepowder', 12],
|
||||
'.G' : [0.53, 195.998, 'concretepowder', 13],
|
||||
'.G#' : [0.56, 207.652, 'concretepowder', 14],
|
||||
'.A' : [0.6, 220.0, 'concretepowder', 15],
|
||||
'.A#' : [0.63, 233.082, 'concrete', 0],
|
||||
'.B' : [0.67, 246.942, 'concrete', 1],
|
||||
'C' : [0.7, 261.626, 'concrete', 2],
|
||||
'C#' : [0.75, 277.183, 'concrete', 3],
|
||||
'D' : [0.8, 293.665, 'concrete', 4],
|
||||
'D#' : [0.84, 311.127, 'concrete', 5],
|
||||
'E' : [0.9, 329.628, 'concrete', 6],
|
||||
'F' : [0.94, 349.228, 'concrete', 7],
|
||||
'F#' : [1.0, 369.994, 'concrete', 8],
|
||||
'G' : [1.05, 391.995, 'concrete', 9],
|
||||
'G#' : [1.12, 415.305, 'concrete', 10],
|
||||
'A' : [1.2, 440.0, 'concrete', 11],
|
||||
'A#' : [1.25, 466.164, 'concrete', 12],
|
||||
'B' : [1.33, 493.883, 'concrete', 13],
|
||||
'`C' : [1.4, 523.251, 'concrete', 14],
|
||||
'`C#' : [1.5, 554.365, 'concrete', 15],
|
||||
'`D' : [1.6, 587.33, 'stained_hardened_clay', 0],
|
||||
'`D#' : [1.7, 622.254, 'stained_hardened_clay', 1],
|
||||
'`E' : [1.8, 659.255, 'stained_hardened_clay', 2],
|
||||
'`F' : [1.9, 698.456, 'stained_hardened_clay', 3],
|
||||
'`F#' : [2.0, 739.989, 'stained_hardened_clay', 4],
|
||||
'`G' : [2.1, 783.991, 'stained_hardened_clay', 5],
|
||||
'`G#' : [2.24, 830.609, 'stained_hardened_clay', 6],
|
||||
'`A' : [2.4, 880.0, 'stained_hardened_clay', 7],
|
||||
'`A#' : [2.5, 932.328, 'stained_hardened_clay', 8],
|
||||
'`B' : [2.67, 987.767, 'stained_hardened_clay', 9],
|
||||
'``C' : [2.83, 1046.502, 'stained_hardened_clay', 10],
|
||||
'``C#' : [3.0, 1108.731, 'stained_hardened_clay', 11],
|
||||
'``D' : [3.17, 1174.659, 'stained_hardened_clay', 12],
|
||||
'``D#' : [3.36, 1244.508, 'stained_hardened_clay', 13],
|
||||
'``E' : [3.56, 1318.51, 'stained_hardened_clay', 14],
|
||||
'``F' : [3.78, 1396.913, 'stained_hardened_clay', 15],
|
||||
'``F#' : [4.0, 1479.978, 'white_glazed_terracotta', 0],
|
||||
'``G' : [4.24, 1567.982, 'orange_glazed_terracotta', 0],
|
||||
'``G#' : [4.5, 1661.219, 'magenta_glazed_terracotta', 0],
|
||||
'``A' : [4.76, 1760.0, 'light_blue_glazed_terracotta', 0],
|
||||
'``A#' : [5.04, 1864.655, 'yellow_glazed_terracotta', 0],
|
||||
'``B' : [5.34, 1975.533, 'lime_glazed_terracotta', 0],
|
||||
'```C' : [5.66, 2093.005, 'pink_glazed_terracotta', 0],
|
||||
'```C#' : [6.0, 2217.461, 'gray_glazed_terracotta', 0],
|
||||
'```D' : [6.35, 2349.318, 'silver_glazed_terracotta', 0],
|
||||
'```D#' : [6.73, 2489.016, 'cyan_glazed_terracotta', 0],
|
||||
'```E' : [7.13, 2637.02, 'purple_glazed_terracotta', 0],
|
||||
'```F' : [7.55, 2793.826, 'blue_glazed_terracotta', 0],
|
||||
'```F#' : [8.0, 2959.955, 'brown_glazed_terracotta', 0],
|
||||
'```G' : [8.47, 3135.963, 'green_glazed_terracotta', 0],
|
||||
'```G#' : [8.98, 3322.438, 'red_glazed_terracotta', 0],
|
||||
'```A' : [9.51, 3520.0, 'black_glazed_terracotta', 0],
|
||||
'```A#' : [10.08, 3729.31, 'stained_glass', 0],
|
||||
'```B' : [10.68, 3951.066, 'stained_glass', 1],
|
||||
'````C' : [11.31, 4186.009, 'stained_glass', 2],
|
||||
'0' : [0.0, 0.0, 'glass', 0]
|
||||
}
|
||||
'''音符对照表\n
|
||||
音符:[MC音调, 声音频率, 方块名称, 数据值]'''
|
||||
|
||||
|
||||
|
||||
|
||||
#方块
|
||||
'''
|
||||
blocks = {
|
||||
0.074 : ['stained_glass', 3],
|
||||
0.0787 : ['stained_glass', 4],
|
||||
0.083 : ['stained_glass', 5],
|
||||
0.088 : ['stained_glass', 6],
|
||||
0.094 : ['stained_glass', 7],
|
||||
0.1 : ['stained_glass', 8],
|
||||
0.105 : ['stained_glass', 9],
|
||||
0.11 : ['stained_glass', 10],
|
||||
0.12 : ['stained_glass', 11],
|
||||
0.125 : ['stained_glass', 12],
|
||||
0.13 : ['stained_glass', 13],
|
||||
0.14 : ['stained_glass', 14],
|
||||
0.15 : ['stained_glass', 15],
|
||||
0.16 : ['wool', 0],
|
||||
0.17 : ['wool', 1],
|
||||
0.18 : ['wool', 2],
|
||||
0.19 : ['wool', 3],
|
||||
0.2 : ['wool', 4],
|
||||
0.21 : ['wool', 5],
|
||||
0.22 : ['wool', 6],
|
||||
0.235 : ['wool', 7],
|
||||
0.25 : ['concretepowder', 0],
|
||||
0.26 : ['concretepowder', 1],
|
||||
0.28 : ['concretepowder', 2],
|
||||
0.3 : ['concretepowder', 3],
|
||||
0.31 : ['concretepowder', 4],
|
||||
0.33 : ['concretepowder', 5],
|
||||
0.35 : ['concretepowder', 6],
|
||||
0.37 : ['concretepowder', 7],
|
||||
0.4 : ['concretepowder', 8],
|
||||
0.42 : ['concretepowder', 9],
|
||||
0.44 : ['concretepowder', 10],
|
||||
0.47 : ['concretepowder', 11],
|
||||
0.5 : ['concretepowder', 12],
|
||||
0.53 : ['concretepowder', 13],
|
||||
0.56 : ['concretepowder', 14],
|
||||
0.6 : ['concretepowder', 15],
|
||||
0.63 : ['concrete', 0],
|
||||
0.67 : ['concrete', 1],
|
||||
0.7 : ['concrete', 2],
|
||||
0.75 : ['concrete', 3],
|
||||
0.8 : ['concrete', 4],
|
||||
0.84 : ['concrete', 5],
|
||||
0.9 : ['concrete', 6],
|
||||
0.94 : ['concrete', 7],
|
||||
1.0 : ['concrete', 8],
|
||||
1.05 : ['concrete', 9],
|
||||
1.12 : ['concrete', 10],
|
||||
1.2 : ['concrete', 11],
|
||||
1.25 : ['concrete', 12],
|
||||
1.33 : ['concrete', 13],
|
||||
1.4 : ['concrete', 14],
|
||||
1.5 : ['concrete', 15],
|
||||
1.6 : ['stained_hardened_clay', 0],
|
||||
1.7 : ['stained_hardened_clay', 1],
|
||||
1.8 : ['stained_hardened_clay', 2],
|
||||
1.9 : ['stained_hardened_clay', 3],
|
||||
2.0 : ['stained_hardened_clay', 4],
|
||||
2.1 : ['stained_hardened_clay', 5],
|
||||
2.24 : ['stained_hardened_clay', 6],
|
||||
2.4 : ['stained_hardened_clay', 7],
|
||||
2.5 : ['stained_hardened_clay', 8],
|
||||
2.67 : ['stained_hardened_clay', 9],
|
||||
2.83 : ['stained_hardened_clay', 10],
|
||||
3.0 : ['stained_hardened_clay', 11],
|
||||
3.17 : ['stained_hardened_clay', 12],
|
||||
3.36 : ['stained_hardened_clay', 13],
|
||||
3.56 : ['stained_hardened_clay', 14],
|
||||
3.78 : ['stained_hardened_clay', 15],
|
||||
4.0 : ['stained_glass_pane', 0],
|
||||
4.24 : ['stained_glass_pane', 1],
|
||||
4.5 : ['stained_glass_pane', 2],
|
||||
4.76 : ['stained_glass_pane', 3],
|
||||
5.04 : ['stained_glass_pane', 4],
|
||||
5.34 : ['stained_glass_pane', 5],
|
||||
5.66 : ['stained_glass_pane', 6],
|
||||
6.0 : ['stained_glass_pane', 7],
|
||||
6.35 : ['stained_glass_pane', 8],
|
||||
6.73 : ['stained_glass_pane', 9],
|
||||
7.13 : ['stained_glass_pane', 10],
|
||||
7.55 : ['stained_glass_pane', 11],
|
||||
8.0 : ['stained_glass_pane', 12],
|
||||
8.47 : ['stained_glass_pane', 13],
|
||||
8.98 : ['stained_glass_pane', 14],
|
||||
9.51 : ['stained_glass_pane', 15],
|
||||
10.08 : ['stained_glass', 0],
|
||||
10.68 : ['stained_glass', 1],
|
||||
11.31 : ['stained_glass', 2],
|
||||
0.0 : ['glass', 0]
|
||||
}
|
||||
#向查理平致敬!!!!!
|
||||
'''
|
||||
|
||||
|
||||
Blocks = {
|
||||
0.074: 'barrel',
|
||||
0.0787: 'beacon',
|
||||
0.083: 'bedrock',
|
||||
0.088: 'black_glazed_terracotta',
|
||||
0.094: 'blast_furnace',
|
||||
0.1: 'blue_glazed_terracotta',
|
||||
0.105: 'blue_ice',
|
||||
0.11: 'bone_block',
|
||||
0.12: 'bookshelf',
|
||||
0.125: 'brick_block',
|
||||
0.13: 'brown_glazed_terracotta',
|
||||
0.14: 'cartography_table',
|
||||
0.15: 'carved_pumpkin',
|
||||
0.16: 'clay',
|
||||
0.17: 'coal_block',
|
||||
0.18: 'coal_ore',
|
||||
0.19: 'cobblestone',
|
||||
0.2: 'concrete',
|
||||
0.21: 'crafting_table',
|
||||
0.22: 'cyan_glazed_terracotta',
|
||||
0.235: 'diamond_block',
|
||||
0.25: 'diamond_ore',
|
||||
0.26: 'white_glazed_terracotta',
|
||||
0.28: 'dispenser',
|
||||
0.3: 'dried_kelp_block',
|
||||
0.31: 'dropper',
|
||||
0.33: 'emerald_block',
|
||||
0.35: 'emerald_ore',
|
||||
0.37: 'end_bricks',
|
||||
0.4: 'end_stone',
|
||||
0.42: 'fletching_table',
|
||||
0.44: 'furnace',
|
||||
0.47: 'glass',
|
||||
0.5: 'glowingobsidian',
|
||||
0.53: 'glowstone',
|
||||
0.56: 'gold_block',
|
||||
0.6: 'gold_ore',
|
||||
0.63: 'grass',
|
||||
0.67: 'gray_glazed_terracotta',
|
||||
0.7: 'green_glazed_terracotta',
|
||||
0.75: 'hardened_clay',
|
||||
0.8: 'hay_block',
|
||||
0.84: 'iron_block',
|
||||
0.9: 'iron_ore',
|
||||
0.94: 'jukebox',
|
||||
1.0: 'lapis_block',
|
||||
1.05: 'lapis_ore',
|
||||
1.12: 'light_blue_glazed_terracotta',
|
||||
1.2: 'lime_glazed_terracotta',
|
||||
1.25: 'lit_pumpkin',
|
||||
1.33: 'log',
|
||||
1.4: 'loom',
|
||||
1.5: 'magenta_glazed_terracotta',
|
||||
1.6: 'magma',
|
||||
1.7: 'melon_block',
|
||||
1.8: 'web',
|
||||
1.9: 'mossy_cobblestone',
|
||||
2.0: 'nether_brick',
|
||||
2.1: 'nether_wart_block',
|
||||
2.24: 'netherrack',
|
||||
2.4: 'noteblock',
|
||||
2.5: 'observer',
|
||||
2.67: 'obsidian',
|
||||
2.83: 'orange_glazed_terracotta',
|
||||
3.0: 'pink_glazed_terracotta',
|
||||
3.17: 'piston',
|
||||
3.36: 'planks',
|
||||
3.56: 'prismarine',
|
||||
3.78: 'pumpkin',
|
||||
4.0: 'purple_glazed_terracotta',
|
||||
4.24: 'purpur_block',
|
||||
4.5: 'quartz_block',
|
||||
4.76: 'quartz_ore',
|
||||
5.04: 'red_glazed_terracotta',
|
||||
5.34: 'red_nether_brick',
|
||||
5.66: 'red_sandstone',
|
||||
6.0: 'redstone_block',
|
||||
6.35: 'yellow_glazed_terracotta',
|
||||
6.73: 'sandstone',
|
||||
7.13: 'stonebrick',
|
||||
7.55: 'silver_glazed_terracotta',
|
||||
8.0: 'slime',
|
||||
8.47: 'smithing_table',
|
||||
8.98: 'smoker',
|
||||
9.51: 'smooth_stone',
|
||||
10.08: 'snow',
|
||||
10.68: 'soul_sand',
|
||||
11.31: 'sponge',
|
||||
0.0: 'stone'
|
||||
}
|
||||
'''频率对照表\n
|
||||
MC音调:方块名称'''
|
||||
|
||||
|
||||
|
||||
# 乐器
|
||||
Instuments = {
|
||||
'note.banjo' : '班卓',
|
||||
'note.bass' : '低音',
|
||||
'note.bassattack' : '贝斯',
|
||||
'note.bd' : '鼓声',
|
||||
'note.bell' : '铃声',
|
||||
'note.bit' : '比特',
|
||||
'note.cow_bell' : '牛铃',
|
||||
'note.didgeridoo' : '迪吉',
|
||||
'note.flute' : '长笛',
|
||||
'note.guitar' : '吉他',
|
||||
'note.harp' : '竖琴',
|
||||
'note.hat' : '架鼓',
|
||||
'note.chime' : '钟声',
|
||||
'note.iron_xylophone' : '铁琴',
|
||||
'note.pling' : '叮叮',
|
||||
'note.snare' : '响弦',
|
||||
'note.xylophone' : '木琴'
|
||||
}
|
||||
'''乐器对照表\n
|
||||
乐器英文:中文
|
||||
翻译:雪莹工坊Fun-Fer'''
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
"""提供对于音创系列的日志"""
|
||||
|
||||
import datetime,os
|
||||
|
||||
#载入日志功能
|
||||
StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7]
|
||||
'''字符串型的程序开始时间'''
|
||||
|
||||
|
||||
def log(info:str = '',isPrinted:bool = True):
|
||||
'''将信息连同当前时间载入日志'''
|
||||
if not os.path.exists('./log/'):
|
||||
os.makedirs('./log/')
|
||||
with open('./log/'+StrStartTime+'.msct.log', 'a',encoding='UTF-8') as f:
|
||||
f.write(str(datetime.datetime.now())[11:19]+' '+info+'\n')
|
||||
if isPrinted:
|
||||
print(str(datetime.datetime.now())[11:19]+' '+info)
|
||||
@@ -1,87 +0,0 @@
|
||||
|
||||
"""音创系列的文件读取功能"""
|
||||
|
||||
|
||||
|
||||
|
||||
from musicreater.nmcsup.log import log
|
||||
from musicreater.nmcsup.const import notes
|
||||
|
||||
|
||||
|
||||
#从格式文本文件读入一个音轨并存入一个列表
|
||||
def ReadFile(fn : str) -> list:
|
||||
from musicreater.nmcsup.trans import note2list
|
||||
log('打开'+fn+"并读取音符")
|
||||
try:
|
||||
nat = open(fn, 'r', encoding='UTF-8').read().split(" ")
|
||||
del fn
|
||||
except:
|
||||
log("找不到读取目标文件")
|
||||
return False
|
||||
Notes = []
|
||||
log(str(nat)+"已读取")
|
||||
for i in range(int(len(nat)/2)):
|
||||
Notes.append([nat[i*2], float(nat[i*2+1])])
|
||||
Notes = note2list(Notes)
|
||||
log('音符数据更新'+str(Notes))
|
||||
return [Notes,]
|
||||
|
||||
|
||||
#从midi读入多个音轨,返回多个音轨列表
|
||||
def ReadMidi(midfile : str ) -> list:
|
||||
import mido
|
||||
from musicreater.msctspt.threadOpera import NewThread
|
||||
Notes = []
|
||||
try:
|
||||
mid = mido.MidiFile(midfile)
|
||||
except:
|
||||
log("找不到文件或无法读取文件"+midfile)
|
||||
return False
|
||||
# 解析
|
||||
ks = list(notes.values())
|
||||
def loadMidi(track):
|
||||
datas = []
|
||||
for i in track:
|
||||
if i.is_meta:
|
||||
log('元信息'+str(i))
|
||||
pass # 不处理元信息
|
||||
elif 'note_on' in str(i):
|
||||
msg = str(i).replace("note=", '').replace("time=", '').split(" ")
|
||||
log('音符on消息,处理后:'+str(msg))
|
||||
if msg[4] == '0':
|
||||
datas.append([ks[int(msg[2])-20][0], 1.0])
|
||||
log('延续时间0tick--:添加音符'+str([ks[int(msg[2])-20][0], 1.0]))
|
||||
else:
|
||||
datas.append([ks[int(msg[2])-20][0], float(msg[4])/480])
|
||||
log('延续时间'+msg[4]+'tick--:添加音符' +str([ks[int(msg[2])-20][0], float(msg[4])/480]))
|
||||
del msg
|
||||
log('音符增加'+str(datas))
|
||||
return datas
|
||||
for j, track in enumerate(mid.tracks):
|
||||
th = NewThread(loadMidi,(track,))
|
||||
th.start()
|
||||
Notes.append(th.getResult())
|
||||
del ks
|
||||
return Notes
|
||||
|
||||
|
||||
|
||||
|
||||
def ReadOldProject(fn:str) -> list:
|
||||
import json
|
||||
from musicreater.nmcsup.trans import note2list
|
||||
log("读取文件:"+fn)
|
||||
try:
|
||||
with open(fn, 'r', encoding='UTF-8') as c:
|
||||
dataset = json.load(c)
|
||||
except:
|
||||
print('找不到文件:'+fn+",请查看您是否输入正确")
|
||||
log("丢失"+fn)
|
||||
return False
|
||||
for i in range(len(dataset['musics'])):
|
||||
dataset['musics'][i]['notes'] = note2list(dataset['musics'][i]['notes'])
|
||||
#返回 音轨列表 选择器
|
||||
return dataset
|
||||
|
||||
|
||||
@@ -1,254 +0,0 @@
|
||||
|
||||
"""音创系列的转换功能"""
|
||||
|
||||
|
||||
|
||||
from nmcsup.log import log
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 输入一个列表 [ [str, float ], [], ... ] 音符str 值为持续时间float
|
||||
def note2list(Notes : list) -> list:
|
||||
from musicreater.nmcsup.const import notes
|
||||
def change(base):
|
||||
enwo = {
|
||||
'a': 'A',
|
||||
'b': 'B',
|
||||
'c': 'C',
|
||||
'd': "D",
|
||||
"e": "E",
|
||||
'f': 'F',
|
||||
'g': "G"
|
||||
}
|
||||
nuwo = {
|
||||
'6': 'A',
|
||||
'7': 'B',
|
||||
'1': 'C',
|
||||
'2': "D",
|
||||
"3": "E",
|
||||
'4': 'F',
|
||||
'5': "G"
|
||||
}
|
||||
for k, v in enwo.items():
|
||||
if k in base:
|
||||
base = base.replace(k, v)
|
||||
for k, v in nuwo.items():
|
||||
if k in base:
|
||||
base = base.replace(k, v)
|
||||
return base
|
||||
res = []
|
||||
log(" === 音符列表=>音调列表")
|
||||
for i in Notes:
|
||||
s2 = change(i[0])
|
||||
log(' === 正在操作音符'+i[0]+'->'+s2)
|
||||
if s2 in notes.keys():
|
||||
log(" === 找到此音符,加入:"+str(notes[s2][0]))
|
||||
res.append([notes[s2][0], float(i[1])])
|
||||
else:
|
||||
log(' === '+s2+'不在音符表内,此处自动替换为 休止符0 ')
|
||||
res.append(['0', float(i[1])])
|
||||
log(' === 最终反回'+str(res))
|
||||
return res
|
||||
|
||||
|
||||
|
||||
|
||||
def mcnote2freq(Notes):
|
||||
from musicreater.nmcsup.const import notes
|
||||
mcnback = {}
|
||||
for i,j in notes.items():
|
||||
mcnback[j[0]] = i
|
||||
res = []
|
||||
log(" === 我的世界音调表=>频率列表")
|
||||
for i in Notes:
|
||||
log(' === 正在操作音符'+i[0]+'->'+mcnback[i[0]])
|
||||
res.append([notes[mcnback[i[0]]][1], float(i[1])])
|
||||
log(' === 最终反回'+str(res))
|
||||
return res
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#MP3文件转midi文件
|
||||
def Mp32Mid(mp3File, midFile):
|
||||
from piano_transcription_inference import PianoTranscription, sample_rate, load_audio
|
||||
# 加载
|
||||
(audio, _) = load_audio(mp3File, sr=sample_rate, mono=True)
|
||||
# 实例化并转换
|
||||
PianoTranscription(device="cpu").transcribe(audio, midFile)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#传入一个音符列表转为指令列表
|
||||
def Note2Cmd(Notes : list,ScoreboardName:str,Instrument:str, PlayerSelect:str='',isProsess:bool=False) -> list:
|
||||
commands = []
|
||||
a = 0.0
|
||||
if isProsess:
|
||||
length = len(Notes)
|
||||
j = 1
|
||||
for i in range(len(Notes)):
|
||||
commands.append("execute @a"+PlayerSelect+" ~ ~ ~ execute @s[scores={"+ScoreboardName+"="+str(int((a+2)*5+int(Notes[i][1]*5)))+"}] ~ ~ ~ playsound "+Instrument+" @s ~ ~ ~ 1000 "+str(Notes[i][0])+" 1000\n")
|
||||
a += Notes[i][1]
|
||||
if isProsess:
|
||||
commands.append("execute @a"+PlayerSelect+" ~ ~ ~ execute @s[scores={"+ScoreboardName+"="+str(int((a+2)*5+int(Notes[i][1]*5)))+"}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a"+str(j)+"/"+str(length)+" || "+str(int(j/length*1000)/10)+"\n")
|
||||
j+=1
|
||||
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||||
return commands
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import amulet
|
||||
import amulet_nbt
|
||||
from amulet.api.block import Block
|
||||
from amulet.api.block_entity import BlockEntity
|
||||
from amulet.utils.world_utils import block_coords_to_chunk_coords
|
||||
from amulet_nbt import TAG_String,TAG_Compound,TAG_Byte
|
||||
|
||||
|
||||
|
||||
#简单载入方块
|
||||
#level.set_version_block(posx,posy,posz,"minecraft:overworld",("bedrock", (1, 16, 20)),Block(namespace, name))
|
||||
|
||||
|
||||
|
||||
#转入指令列表与位置信息转至世界
|
||||
def Cmd2World(cmd:list,world:str,dire:list):
|
||||
'''将指令以命令链的形式载入世界\n
|
||||
cmd指令列表位为一个序列,中包含指令字符串\n
|
||||
world为地图所在位置,需要指向文件夹,dire为指令方块生成之位置'''
|
||||
level = amulet.load_level(world)
|
||||
cdl = []
|
||||
for i in cmd:
|
||||
try:
|
||||
if (i[:i.index('#')].replace(' ','') != '\n') and(i[:i.index('#')].replace(' ','') != ''):
|
||||
cdl.append(i[:i.index('#')])
|
||||
except:
|
||||
cdl.append(i)
|
||||
i = 0
|
||||
#第一个是特殊
|
||||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("repeating")})
|
||||
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
|
||||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],dire[1],dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(0),'Command': TAG_String(cdl.pop(0))}) })))
|
||||
chunk.blocks[offset_x, dire[1], offset_z] = level.block_palette.get_add_block(universal_block)
|
||||
chunk.block_entities[(dire[0], dire[1], dire[2])] = universal_block_entity
|
||||
chunk.changed = True
|
||||
#集体上移
|
||||
dire[1]+=1;
|
||||
#真正开始
|
||||
down = False
|
||||
for j in cdl:
|
||||
if dire[1]+i >= 255:
|
||||
dire[0]+=1
|
||||
i=0
|
||||
down = not down
|
||||
#定义此方块
|
||||
if dire[1]+i == 254 :
|
||||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('east'),'mode':TAG_String("chain")})
|
||||
else:
|
||||
if down:
|
||||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('down'),'mode':TAG_String("chain")})
|
||||
else:
|
||||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("chain")})
|
||||
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
|
||||
#获取区块
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
|
||||
if down:
|
||||
#定义方块实体
|
||||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],254-i,dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(1),'Command': TAG_String(j)}) })))
|
||||
|
||||
#将方块加入世界
|
||||
chunk.blocks[offset_x, 254-i, offset_z] = level.block_palette.get_add_block(universal_block)
|
||||
chunk.block_entities[(dire[0], 254-i, dire[2])] = universal_block_entity
|
||||
else:
|
||||
#定义方块实体
|
||||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],dire[1]+i,dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(1),'Command': TAG_String(j)}) })))
|
||||
|
||||
#将方块加入世界
|
||||
chunk.blocks[offset_x, dire[1]+i, offset_z] = level.block_palette.get_add_block(universal_block)
|
||||
chunk.block_entities[(dire[0], dire[1]+i, dire[2])] = universal_block_entity
|
||||
#设置为已更新区块
|
||||
chunk.changed = True
|
||||
i+=1
|
||||
del i, cdl
|
||||
#保存世界并退出
|
||||
level.save()
|
||||
level.close()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#音符转成方块再加载到世界里头
|
||||
def Blocks2World(world:str,dire:list,Datas:list):
|
||||
from musicreater.nmcsup.const import Blocks
|
||||
level = amulet.load_level(world)
|
||||
i = 0
|
||||
def setblock(block:str,pos:list):
|
||||
'''pos : list[int,int,int]'''
|
||||
cx, cz = block_coords_to_chunk_coords(pos[0], pos[2])
|
||||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||||
offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz
|
||||
chunk.blocks[offset_x, pos[1], offset_z] = level.block_palette.get_add_block(Block("minecraft",block))
|
||||
chunk.changed = True
|
||||
for j in Datas:
|
||||
if dire[1]+1 >= 255:
|
||||
i = 0
|
||||
dire[0]+=1
|
||||
setblock(Blocks[j[0]],[dire[0],dire[1]+i,dire[2]])
|
||||
i = int(i+j[1]+0.5) #四舍五入
|
||||
level.save()
|
||||
level.close()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#传入音符列表制作播放器指令
|
||||
def Notes2Player(Note,dire:list,CmdData:dict):
|
||||
'''传入音符列表、坐标、指令数据,生成播放器指令'''
|
||||
Notes = {}
|
||||
for i in Note:
|
||||
Notes[i[0]] = ''
|
||||
Notes = list(Notes.keys())
|
||||
from musicreater.nmcsup.const import Blocks
|
||||
Cmds = []
|
||||
for j in Notes:
|
||||
Cmds.append('execute @e[x='+str(dire[0])+',y='+str(dire[1])+',z='+str(dire[2])+',dy='+str(255-dire[1])+',name='+CmdData['Ent']+'] ~ ~ ~ detect ~ ~ ~ '+Blocks[j]+' 0 execute @a '+CmdData['Pls']+' ~ ~ ~ playsound '+CmdData['Ins']+' @s ~ ~ ~ 1000 '+str(j)+' 1000\n')
|
||||
Cmds+=['#本函数由 金羿 音·创 生成\n','execute @e[y='+str(dire[1])+',dy='+str(255-dire[1])+',name='+CmdData['Ent']+'] ~ ~ ~ tp ~ ~1 ~\n','execute @e[y=255,dy=100,name='+CmdData['Ent']+'] ~ ~ ~ tp ~1 '+str(dire[1])+' ~\n','#音·创 开发交流群 861684859']
|
||||
return Cmds
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#传入音符列表生成方块至世界
|
||||
def Datas2BlkWorld(NoteData,world:str,dire:list):
|
||||
for i in range(len(NoteData)):
|
||||
Blocks2World(world,[dire[0],dire[1],dire[2]+i],NoteData[i])
|
||||
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
"""音创系列版本号和版本操作函数"""
|
||||
|
||||
|
||||
|
||||
from musicreater.msctspt.bugReporter import version
|
||||
|
||||
|
||||
#以下下两个值请在 msctspt/bugReporter 的version类中修改
|
||||
VER = version.version
|
||||
'''当前版本'''
|
||||
|
||||
LIBS = version.libraries
|
||||
'''当前所需库'''
|
||||
|
||||
|
||||
|
||||
#判断版本、临时文件与补全库
|
||||
def compver(ver1, ver2):
|
||||
"""
|
||||
传入不带英文的版本号,特殊情况:"10.12.2.6.5">"10.12.2.6"
|
||||
:param ver1: 版本号1
|
||||
:param ver2: 版本号2
|
||||
:return: ver1< = >ver2返回-1/0/1
|
||||
"""
|
||||
list1 = str(ver1).split(".")
|
||||
list2 = str(ver2).split(".")
|
||||
# 循环次数为短的列表的len
|
||||
for i in range(len(list1)) if len(list1) < len(list2) else range(len(list2)):
|
||||
if int(list1[i]) == int(list2[i]):
|
||||
pass
|
||||
elif int(list1[i]) < int(list2[i]):
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
# 循环结束,哪个列表长哪个版本号高
|
||||
if len(list1) == len(list2):
|
||||
return 0
|
||||
elif len(list1) < len(list2):
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
#
|
||||
# ————————————————
|
||||
# 版权声明:上面的函数compver为CSDN博主「基友死得早」的原创文章中的函数,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
|
||||
# 原文链接:https://blog.csdn.net/tinyjm/article/details/93514261
|
||||
# ————————————————
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
def InstallLibs(now,LIBS):
|
||||
'''比对库信息并安装库'''
|
||||
from os import system as run
|
||||
for i in LIBS:
|
||||
if not i in now:
|
||||
print("安装库:"+i)
|
||||
run("python -m pip install "+i+" -i https://pypi.tuna.tsinghua.edu.cn/simple")
|
||||
|
||||
|
||||
def chkver(ver = VER,libs = LIBS):
|
||||
'''通过文件比对版本信息并安装库'''
|
||||
if not os.path.exists(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct'):
|
||||
print("新安装库")
|
||||
os.makedirs(os.getenv('APPDATA')+'\\Musicreater\\')
|
||||
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'w') as f:
|
||||
f.write(ver[0]+'\n')
|
||||
for i in libs:
|
||||
f.write(i+'\n')
|
||||
InstallLibs([],libs)
|
||||
else:
|
||||
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'r') as f:
|
||||
v = f.readlines()
|
||||
cp = compver(ver[0], v[0])
|
||||
if cp != 0:
|
||||
InstallLibs(v[1:],libs)
|
||||
with open(os.getenv('APPDATA')+'\\Musicreater\\msct.ActiveDatas.msct', 'w') as f:
|
||||
f.write(ver[0]+'\n')
|
||||
for i in libs:
|
||||
f.write(i+'\n')
|
||||
del cp
|
||||
|
||||
|
||||
def resetver():
|
||||
'''重置版本信息'''
|
||||
import shutil
|
||||
shutil.rmtree(os.getenv('APPDATA')+'\\Musicreater\\')
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
LANGUAGE = {
|
||||
'main':{
|
||||
"name":"音·创",
|
||||
"version":"当前版本",
|
||||
"run":"执行指令",
|
||||
},
|
||||
'command':{
|
||||
"NotAvailable":"此指令不可用。",
|
||||
"FormatError":"指令格式错误,请查看 命令行操作.md 以查阅指令。"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 441 KiB |
@@ -1,11 +0,0 @@
|
||||
生命灵动 当用激情跃起奋发之力
|
||||
奇偶数阵
|
||||
学海无涯 应用爱意徜徉
|
||||
在生命的起源寻找灵魂的慰藉
|
||||
纪念那一段辉煌灿烂的青春年华
|
||||
以梦想为驱使 创造属于自己的未来
|
||||
集青春之力 绽放爱意之花
|
||||
那个曾与我相伴的人 依稀在我的心头留恋
|
||||
我爱你 我 爱 你
|
||||
你是我灵魂中绽放出最艳丽的花朵
|
||||
心之所向 意之所属
|
||||
1
trans_mid_analyse.bat
Normal file
1
trans_mid_analyse.bat
Normal file
@@ -0,0 +1 @@
|
||||
pyside6-uic mid_analyse.ui -o mid_analyse.py
|
||||
15
update.sh
Normal file
15
update.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
rm -rf ./MusictraterPkgver
|
||||
|
||||
git clone https://gitee.com/EillesWan/Musicreater.git -b pkgver MusictraterPkgver
|
||||
|
||||
cd ./MusictraterPkgver
|
||||
|
||||
python3 -O -m compileall -b .
|
||||
|
||||
find . -name "*.py"|xargs rm -rf
|
||||
|
||||
find . -name "__pycache__" |xargs rm -rf
|
||||
|
||||
rm -rf ./.git
|
||||
|
||||
rm ./.gitignore
|
||||
34
命令行操作.md
34
命令行操作.md
@@ -1,34 +0,0 @@
|
||||
# Musicreater 音·创 命令行模式
|
||||
|
||||
为了对后期安卓的兼容,先支持命令行
|
||||
|
||||
## 命令列表
|
||||
|
||||
### exit \[/s\] \[/c\]
|
||||
|
||||
- ```/s``` 保存并退出
|
||||
- ```/c``` 清除日志
|
||||
|
||||
### save \[/a \<fileName\>\]
|
||||
|
||||
- ```/a <文件名>``` 指定文件名保存
|
||||
|
||||
### load \[/\<loadMethod: input|txt|mid\> \<text|fileName\>\]
|
||||
|
||||
- ```/input <文本>``` 输入音符
|
||||
- ```/txt <文件名>``` 从文本载入音符
|
||||
- ```/mid <文件名>``` 解析midi文件载入音符
|
||||
|
||||
### win
|
||||
|
||||
- 开启窗口模式的 音·创(仅支持的系统下有效)
|
||||
|
||||
### chdir \<direction\>
|
||||
|
||||
- 切换当前工作目录
|
||||
|
||||
### build \[/\<buildMethod: file|directory|mcpack\> \<direction\>\]
|
||||
|
||||
- ```/file <目录位置>``` 在指定目录生成函数文件(散装)
|
||||
- ```/directory <目录位置>``` 在指定目录生成一个附加包目录
|
||||
- ```/mcpack <目录位置>``` 在指定目录生成一个.mcpack附加包
|
||||
29
查看代码数.py
29
查看代码数.py
@@ -1,29 +0,0 @@
|
||||
# -*- conding: utf8 -*-
|
||||
|
||||
import os
|
||||
from src.musicreater.msctspt.funcOpera import keepart
|
||||
|
||||
|
||||
l = 0
|
||||
|
||||
|
||||
|
||||
for path,dir_list,file_list in os.walk(r"./") :
|
||||
for file_name in file_list:
|
||||
if keepart(file_name,'.',None) == '.py':
|
||||
file = os.path.join(path, file_name)
|
||||
print("得到文件名:"+str(file))
|
||||
for i in open(file,'r',encoding="utf-8"):
|
||||
code = i.replace(' ','').replace('\n','')
|
||||
try:
|
||||
code -= code[code.index('#'):]
|
||||
except:
|
||||
pass;
|
||||
if code:
|
||||
print("\t"+code)
|
||||
l+=1
|
||||
else:
|
||||
pass;
|
||||
|
||||
input("\n最终代码行数为:"+str(l))
|
||||
|
||||
@@ -1,224 +0,0 @@
|
||||
{
|
||||
"mainset": {
|
||||
"PackName": "RyounTeamSong",
|
||||
"MusicTitle": "RyounUp",
|
||||
"IsRepeat": false,
|
||||
"PlayerSelect": ""
|
||||
},
|
||||
"musics": [
|
||||
{
|
||||
"set": {
|
||||
"EntityName": "MusicSupport",
|
||||
"ScoreboardName": "MusicSupport",
|
||||
"Instrument": "harp",
|
||||
"FileName": "RyounUp_RyounTeamSong"
|
||||
},
|
||||
"notes": [
|
||||
[
|
||||
".5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
"3",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
".6",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
".5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"6",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"5",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"3",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"2",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"0",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
".5",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
".6",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"6",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"3",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"2",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"5",
|
||||
1.5
|
||||
],
|
||||
[
|
||||
".5",
|
||||
0.5
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"1",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"0",
|
||||
1.0
|
||||
],
|
||||
[
|
||||
"0",
|
||||
1.0
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
测试用/义勇军进行曲.mid
BIN
测试用/义勇军进行曲.mid
Binary file not shown.
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user