Compare commits
No commits in common. "b6309cf16c63af657d0721d44a8975dc0930149d" and "a30d678c082c0f196d76a313a9938ce8c75a7dde" have entirely different histories.
b6309cf16c
...
a30d678c08
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,10 +1,7 @@
|
|||||||
**/__pycache__
|
|
||||||
.vscode
|
|
||||||
.venv
|
|
||||||
|
|
||||||
recordings/
|
|
||||||
*.mkv
|
*.mkv
|
||||||
*.png
|
|
||||||
out/
|
out/
|
||||||
|
|
||||||
scores
|
.venv
|
||||||
|
mscz/
|
||||||
|
recordings/
|
||||||
|
**/__pycache__
|
@ -1,25 +1,86 @@
|
|||||||
|
from xml.etree import ElementTree
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import zipfile
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from PIL import Image, ImageOps
|
from PIL import Image, ImageOps
|
||||||
from modules import logger, mscz
|
from modules import logger
|
||||||
|
|
||||||
RATIO = 16/9 # 16:9
|
RATIO = 16/9 # 16:9
|
||||||
|
|
||||||
|
|
||||||
|
def get_elements(root, attribute):
|
||||||
|
return [i for i in root if i.tag == attribute]
|
||||||
|
|
||||||
|
def get_element(root, attribute):
|
||||||
|
elems = get_elements(root, attribute)
|
||||||
|
|
||||||
|
if len(elems) > 1:
|
||||||
|
print(f"More than one '{attribute}' found", file=sys.stderr)
|
||||||
|
if len(elems) == 0:
|
||||||
|
raise IndexError(f"No '{attribute}' found !")
|
||||||
|
|
||||||
|
return elems[0]
|
||||||
|
|
||||||
|
def create_pagebreaks(data):
|
||||||
|
"""
|
||||||
|
Replaces all manual linebreaks by pagebreaks in a .mscx file (xml)
|
||||||
|
"""
|
||||||
|
root = ElementTree.fromstring(data)
|
||||||
|
|
||||||
|
score = get_element(root, "Score")
|
||||||
|
parts = get_elements(score, "Part")
|
||||||
|
staffs = get_elements(score, "Staff")
|
||||||
|
for part in parts:
|
||||||
|
staffs += get_elements(part, "Staff")
|
||||||
|
|
||||||
|
changes = 0
|
||||||
|
for staff in staffs:
|
||||||
|
measures = get_elements(staff, "Measure")
|
||||||
|
for measure in measures:
|
||||||
|
layoutbreaks = get_elements(measure, "LayoutBreak")
|
||||||
|
for layoutbreak in layoutbreaks:
|
||||||
|
subtype = get_element(layoutbreak, "subtype")
|
||||||
|
if subtype.text == "line":
|
||||||
|
subtype.text = "page"
|
||||||
|
changes += 1
|
||||||
|
|
||||||
|
|
||||||
|
return ElementTree.tostring(root), changes
|
||||||
|
|
||||||
|
def remove_footer(data):
|
||||||
|
"""
|
||||||
|
Disable page footer in .mss (xml)
|
||||||
|
"""
|
||||||
|
root = ElementTree.fromstring(data)
|
||||||
|
|
||||||
|
style = get_element(root, "Style")
|
||||||
|
show_footer = get_element(style, "showFooter")
|
||||||
|
show_footer.text = 0
|
||||||
|
|
||||||
|
return ElementTree.tostring(root)
|
||||||
|
|
||||||
|
def prepare_mscz(source, dest):
|
||||||
|
shutil.copy(source, dest)
|
||||||
|
with zipfile.ZipFile(source) as inzip, zipfile.ZipFile(dest, "w") as outzip:
|
||||||
|
for inzipinfo in inzip.infolist():
|
||||||
|
with inzip.open(inzipinfo) as infile:
|
||||||
|
if inzipinfo.filename.endswith(".mscx"):
|
||||||
|
new_data, changes = create_pagebreaks(infile.read())
|
||||||
|
outzip.writestr(inzipinfo.filename, new_data)
|
||||||
|
elif inzipinfo.filename.endswith(".mss"):
|
||||||
|
new_data = remove_footer(infile.read())
|
||||||
|
outzip.writestr(inzipinfo.filename, new_data)
|
||||||
|
else:
|
||||||
|
outzip.writestr(inzipinfo.filename, infile.read())
|
||||||
|
|
||||||
def generate_images(mscz_file, base_dest):
|
def generate_images(mscz_file, base_dest):
|
||||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||||
tmp_mscz = os.path.join(tmpdirname, "score.mscz")
|
tmp_mscz = os.path.join(tmpdirname, "score.mscz")
|
||||||
mscz.apply(
|
prepare_mscz(mscz_file, tmp_mscz)
|
||||||
mscz_file,
|
|
||||||
tmp_mscz,
|
|
||||||
[
|
|
||||||
mscz.patches.create_pagebreaks,
|
|
||||||
mscz.patches.remove_footer
|
|
||||||
]
|
|
||||||
)
|
|
||||||
logger.log(".mscz file patched")
|
logger.log(".mscz file patched")
|
||||||
|
|
||||||
subprocess.call(["mscore", tmp_mscz, "-o", base_dest+".png"])
|
subprocess.call(["mscore", tmp_mscz, "-o", base_dest+".png"])
|
||||||
|
22
src/images_to_video.sh
Executable file
22
src/images_to_video.sh
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
IN=$1
|
||||||
|
[[ $IN ]]|| IN="concat.txt"
|
||||||
|
FILES=$(cat $IN | grep file | awk '{print $2}' | uniq)
|
||||||
|
|
||||||
|
echo $FILES
|
||||||
|
|
||||||
|
# Get the larger width and height of all the images
|
||||||
|
WIDTH=$(identify -format "%w\n" $FILES | sort -nr | head -1)
|
||||||
|
HEIGHT=$(identify -format "%h\n" $FILES | sort -nr | head -1)
|
||||||
|
|
||||||
|
echo $WIDTH x $HEIGHT
|
||||||
|
|
||||||
|
# Center all the images and pad them to the larger width and height
|
||||||
|
# Set the border color to the dominant color of the image
|
||||||
|
for f in $FILES; do
|
||||||
|
BORDER_COLOR=$(magick $f -format "%[pixel:p{0,0}]" info:)
|
||||||
|
#BORDER_COLOR="srgb(255,255,255)"
|
||||||
|
echo "Border color: $BORDER_COLOR"
|
||||||
|
magick $f -gravity center -background none -extent ${WIDTH}x${HEIGHT} -bordercolor $BORDER_COLOR -border 0x0 $f
|
||||||
|
done
|
@ -1,111 +0,0 @@
|
|||||||
from xml.etree import ElementTree
|
|
||||||
import functools
|
|
||||||
import zipfile
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Patches
|
|
||||||
"""
|
|
||||||
class Patches:
|
|
||||||
def __init__(self):
|
|
||||||
self._data = {}
|
|
||||||
def __getattr__(self, key):
|
|
||||||
return self._data[key]
|
|
||||||
|
|
||||||
|
|
||||||
patches = Patches()
|
|
||||||
|
|
||||||
def register_patch(file_ext):
|
|
||||||
def inner_wrapper(view):
|
|
||||||
patches._data[view.__name__] = (view, file_ext)
|
|
||||||
|
|
||||||
@functools.wraps(view)
|
|
||||||
def wrapped_view(**kwargs):
|
|
||||||
return view(**kwargs)
|
|
||||||
|
|
||||||
return wrapped_view
|
|
||||||
return inner_wrapper
|
|
||||||
|
|
||||||
|
|
||||||
@register_patch("mscx")
|
|
||||||
def create_pagebreaks(data):
|
|
||||||
"""
|
|
||||||
Replaces all manual linebreaks by pagebreaks in a .mscx file (xml)
|
|
||||||
"""
|
|
||||||
root = ElementTree.fromstring(data)
|
|
||||||
|
|
||||||
score = get_element(root, "Score")
|
|
||||||
parts = get_elements(score, "Part")
|
|
||||||
staffs = get_elements(score, "Staff")
|
|
||||||
for part in parts:
|
|
||||||
staffs += get_elements(part, "Staff")
|
|
||||||
|
|
||||||
for staff in staffs:
|
|
||||||
measures = get_elements(staff, "Measure")
|
|
||||||
for measure in measures:
|
|
||||||
layoutbreaks = get_elements(measure, "LayoutBreak")
|
|
||||||
for layoutbreak in layoutbreaks:
|
|
||||||
subtype = get_element(layoutbreak, "subtype")
|
|
||||||
if subtype.text == "line":
|
|
||||||
subtype.text = "page"
|
|
||||||
|
|
||||||
|
|
||||||
return ElementTree.tostring(root)
|
|
||||||
|
|
||||||
@register_patch("mss")
|
|
||||||
def remove_footer(data):
|
|
||||||
"""
|
|
||||||
Disable page footer in .mss (xml)
|
|
||||||
"""
|
|
||||||
root = ElementTree.fromstring(data)
|
|
||||||
|
|
||||||
style = get_element(root, "Style")
|
|
||||||
show_footer = get_element(style, "showFooter")
|
|
||||||
show_footer.text = 0
|
|
||||||
|
|
||||||
return ElementTree.tostring(root)
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
The "main" apply function
|
|
||||||
"""
|
|
||||||
def get_elements(root, attribute):
|
|
||||||
return [i for i in root if i.tag == attribute]
|
|
||||||
|
|
||||||
def get_element(root, attribute):
|
|
||||||
elems = get_elements(root, attribute)
|
|
||||||
|
|
||||||
if len(elems) > 1:
|
|
||||||
print(f"More than one '{attribute}' found", file=sys.stderr)
|
|
||||||
if len(elems) == 0:
|
|
||||||
raise IndexError(f"No '{attribute}' found !")
|
|
||||||
|
|
||||||
return elems[0]
|
|
||||||
|
|
||||||
def apply(source, dest, patches):
|
|
||||||
"""
|
|
||||||
Apply functions to patch files inside a mscz
|
|
||||||
- source : source file
|
|
||||||
- dest : destination file, must differ
|
|
||||||
- patches : list of (function, file extension)
|
|
||||||
"""
|
|
||||||
patches_by_ext = {}
|
|
||||||
for func, ext in patches:
|
|
||||||
if ext not in patches_by_ext:
|
|
||||||
patches_by_ext[ext] = []
|
|
||||||
|
|
||||||
patches_by_ext[ext].append(func)
|
|
||||||
|
|
||||||
shutil.copy(source, dest)
|
|
||||||
with zipfile.ZipFile(source) as inzip, zipfile.ZipFile(dest, "w") as outzip:
|
|
||||||
for inzipinfo in inzip.infolist():
|
|
||||||
with inzip.open(inzipinfo) as infile:
|
|
||||||
ext = inzipinfo.filename.split(".")[-1]
|
|
||||||
if ext in patches_by_ext:
|
|
||||||
data = infile.read()
|
|
||||||
for func in patches_by_ext[ext]:
|
|
||||||
data = func(data)
|
|
||||||
outzip.writestr(inzipinfo.filename, data)
|
|
||||||
else:
|
|
||||||
outzip.writestr(inzipinfo.filename, infile.read())
|
|
Loading…
Reference in New Issue
Block a user