Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
lissettecarlr committed May 9, 2024
1 parent 7c6335f commit 0f9e5ca
Show file tree
Hide file tree
Showing 14 changed files with 608 additions and 2 deletions.
107 changes: 107 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# 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

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# 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/

#
temp
57 changes: 55 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,55 @@
# ncmdump
将.ncm格式音频文件转换为flac格式,提供windows客户端和WEB两种使用方式。(Convert .ncm format audio files to flac format, providing two usage options: a Windows client and a web interface.)
# ncm -> flac converter

将.ncm格式音频文件转换为flac格式,提供windows客户端和WEB两种使用方式。

## 1 环境

基本环境:
```bash
pip install mutagen
pip install pycryptodome
```

GUI额外环境:
```bash
pip install PyQt6
pip install pyinstaller
```

WEB额外环境:
```bash
pip install streamlit
```

全安装:
```bash
pip install -r requirements.txt
```

## 2 使用

### 2.1 GUI

运行:
```bash
python gui.py
```

编译:
```bash
pyinstaller --onefile --add-data="file:file" -wF -i file/favicon-32x32.png -n "NCM转换器" .\gui.py
```

效果:
![s1](./file/s1.gif)


### 2.2 WEB

运行:
```bash
streamlit run web.py --server.port 1111
```

效果:
![s2](./file/s2.gif)
Binary file added cplusplus/libncmdump.dll
Binary file not shown.
51 changes: 51 additions & 0 deletions cplusplus/ncmdumpdll.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import ctypes
import os

class NcmdumpDll:
def __init__(self, file_name):
dll_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "libncmdump.dll"))
self.dll = ctypes.CDLL(dll_path)

# Define function prototypes
self.dll.CreateNeteaseCrypt.argtypes = [ctypes.c_char_p]
self.dll.CreateNeteaseCrypt.restype = ctypes.c_void_p

self.dll.Dump.argtypes = [ctypes.c_void_p]
self.dll.Dump.restype = ctypes.c_int

self.dll.FixMetadata.argtypes = [ctypes.c_void_p]
self.dll.FixMetadata.restype = None

self.dll.DestroyNeteaseCrypt.argtypes = [ctypes.c_void_p]
self.dll.DestroyNeteaseCrypt.restype = None

# Convert file name to bytes
file_bytes = file_name.encode('utf-8')

# Allocate memory and copy file name bytes
input_ptr = ctypes.create_string_buffer(file_bytes)

# Create NeteaseCrypt instance
self.netease_crypt = self.dll.CreateNeteaseCrypt(input_ptr)

def dump(self):
return self.dll.Dump(self.netease_crypt)

def fix_metadata(self):
self.dll.FixMetadata(self.netease_crypt)

def destroy(self):
self.dll.DestroyNeteaseCrypt(self.netease_crypt)

def process_file(self):
self.dump()
self.fix_metadata()
self.destroy()

if __name__ == "__main__":
# 文件名
file_path = "YOASOBI.ncm"
# 创建 NeteaseCrypt 类的实例
netease_crypt = NcmdumpDll(file_path)
# 启动转换过程
netease_crypt.process_file()
Binary file added file/bk.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added file/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added file/s1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added file/s2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions gui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QDropEvent,QPixmap, QPainter, QFont, QColor,QFontMetrics,QIcon,QDragEnterEvent
import os
from ncmdump import dump

class DragDropWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setAcceptDrops(True)
self.init_ui()

def init_ui(self):
self.setWindowTitle("NCM转换器")
self.setGeometry(100, 100, 573, 573)

self.setWindowIcon(QIcon(self.get_resource_path("file/favicon-32x32.png")))
# 加载图片
self.original_pixmap = QPixmap(self.get_resource_path("file/bk.png"))

self.label = QLabel(self)
self.label.setPixmap(self.original_pixmap)
self.label.setGeometry(0, 0, 573, 573)
self.update_text('将ncm文件拖拽到此处') # 初始文本内容
def update_text(self, text):
pixmap = self.original_pixmap.copy() # 复制原始的 QPixmap 对象
painter = QPainter(pixmap)
painter.setPen(QColor('black')) # 设置文本颜色
font = QFont('SimHei', 20) # 设置字体和大小
painter.setFont(font)

font_metrics = QFontMetrics(font)
text_width = font_metrics.horizontalAdvance(text)
text_height = font_metrics.height()

x = (pixmap.width() - text_width) // 2
y = (pixmap.height() - text_height) // 2 + font_metrics.ascent()

painter.drawText(x, y, text) # 在图片中居中绘制文本
painter.end()
self.label.setPixmap(pixmap) # 更新 QLabel 中的图片

def get_resource_path(self,relative_path):
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)


def dragEnterEvent(self, event: QDragEnterEvent):
if event.mimeData().hasUrls():
event.acceptProposedAction()

def dropEvent(self, event: QDropEvent):
for url in event.mimeData().urls():
file_path = url.toLocalFile()
if file_path.endswith(".ncm"):
try:
dump(file_path)
self.update_text(f"处理完成:{file_path}")
except Exception as e:
self.update_text(f"处理文件时出错:{str(e)}")


if __name__ == "__main__":
app = QApplication(sys.argv)
widget = DragDropWidget()
widget.show()
sys.exit(app.exec())
1 change: 1 addition & 0 deletions ncmdump/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .core import dump
Loading

0 comments on commit 0f9e5ca

Please sign in to comment.