import os import sys import fitz import requests import subprocess from PIL import Image from music21 import converter def download(url: str, directory: str, filename: str): if directory != "" and not os.path.exists(directory): os.makedirs(directory) # Create the full path for the file to be saved file_path = os.path.join(directory, filename) # Send a GET request to the URL response = requests.get(url, stream=True) # Check if the request was successful if response.status_code == 200: # Open the file in write-binary mode with open(file_path, "wb") as file: # Write the contents of the response to the file for chunk in response.iter_content(chunk_size=1024): if chunk: # Filter out keep-alive new chunks file.write(chunk) print(f"The file has been downloaded and saved to {file_path}") else: print(f"Failed to download the file. Status code: {response.status_code}") return os.path.join(directory, filename) if sys.platform.startswith("linux"): apkname = "MuseScore.AppImage" extra_dir = "squashfs-root" if not os.path.exists(apkname): download( url="https://master.dl.sourceforge.net/project/musescore.mirror/v4.2.0/MuseScore-4.2.0.233521125-x86_64.AppImage?viasf=1", directory="./", filename=apkname, ) if not os.path.exists(extra_dir): subprocess.run(["chmod", "+x", f"./{apkname}"]) subprocess.run([f"./{apkname}", "--appimage-extract"]) MSCORE = f"./{extra_dir}/AppRun" os.environ["QT_QPA_PLATFORM"] = "offscreen" else: MSCORE = "D:/Program Files/MuseScore 3/bin/MuseScore3.exe" def add_title_to_xml(xml_path: str, title: str): midi_data = converter.parse(xml_path) # 将标题添加到 MIDI 文件中 midi_data.metadata.movementName = title midi_data.metadata.composer = "Transcripted by AI" # 保存修改后的 MIDI 文件 midi_data.write("musicxml", fp=xml_path) def xml2abc(xml_path: str): result = subprocess.run( ["python", "xml2abc.py", xml_path], stdout=subprocess.PIPE, text=True ) if result.returncode == 0: return result.stdout return "" def xml2mxl(xml_path: str): mxl_file = xml_path.replace(".musicxml", ".mxl") command = [MSCORE, "-o", mxl_file, xml_path] result = subprocess.run(command) print(result) return mxl_file def midi2xml(mid_file: str, title: str): xml_file = mid_file.replace(".mid", ".musicxml") command = [MSCORE, "-o", xml_file, mid_file] result = subprocess.run(command) add_title_to_xml(xml_file, title) print(result) return xml_file def xml2midi(xml_file: str): midi_file = xml_file.replace(".musicxml", ".mid") command = [MSCORE, "-o", midi_file, xml_file] result = subprocess.run(command) print(result) return midi_file def pdf2img(pdf_path: str): output_path = pdf_path.replace(".pdf", ".jpg") doc = fitz.open(pdf_path) # 创建一个图像列表 images = [] for page_number in range(doc.page_count): page = doc[page_number] # 将页面渲染为图像 image = page.get_pixmap() # 将图像添加到列表 images.append( Image.frombytes("RGB", [image.width, image.height], image.samples) ) # 竖向合并图像 merged_image = Image.new( "RGB", (images[0].width, sum(image.height for image in images)) ) y_offset = 0 for image in images: merged_image.paste(image, (0, y_offset)) y_offset += image.height # 保存合并后的图像为JPG merged_image.save(output_path, "JPEG") # 关闭PDF文档 doc.close() return output_path def xml2jpg(xml_file: str): pdf_score = xml_file.replace(".musicxml", ".pdf") command = [MSCORE, "-o", pdf_score, xml_file] result = subprocess.run(command) print(result) return pdf_score, pdf2img(pdf_score)