3

一起用Python做个自动化弹钢琴脚本,我竟然弹出了《天空之城》!

 3 years ago
source link: https://blog.csdn.net/hhladminhhl/article/details/120148627
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

小时候一直有一个想成为钢琴家的梦想,最近在网上看到了一个开源的钢琴演奏网页autopiano,可以支持键盘按键弹奏、鼠标点击弹奏。

突然灵机一动,能不能用Python自动化脚本弹奏一曲美妙的钢琴曲呢?今天就一起带大家如何用Python实现自动化弹出一首《天空之城》!

首先一起来看看最终实现的演奏效果:
在这里插入图片描述
下面,我们就开始介绍如何实现这个自动化弹钢琴脚本的。

一、核心功能设计

总体的实现相对是比较简单的,主要分为以下4步实现:

  • 实现演奏函数,通过手指及时间间隔模拟弹钢琴
  • 添加各个演奏旋律线程,通过多线程模拟双手演奏效果
  • 确定需要演奏的钢琴乐谱,确认主旋律、和弦、右手拇指、右手食指、左手拇指、左手食指
  • 自动切换打开键盘钢琴(auto piano)网页,通过键盘键入实现模拟演奏功能

二、实现步骤

1. 演奏函数

我们首先需要模拟出演奏时,各个按键的停顿间隔时间,实现键盘控制,通过传入的音乐乐符和时间实现各个现场手指的演奏。核心代码如下:

# author:Dragon少年
def play_piano(music, keytime):
    for n in music:
        if n.isupper():
            keyboard.press(Key.shift)
            time.sleep(0.001)
            keyboard.press(n.lower())
            time.sleep(keytime - 0.001)
            keyboard.release(n.lower())
            keyboard.release(Key.shift)
        elif n == "|" or n == ")":
            pass
        elif n in "!@$%^*(":
            keyboard.press(Key.shift)
            time.sleep(0.001)
            keyboard.press("1245689"["!@$%^*(".index(n)])
            time.sleep(keytime - 0.001)
            keyboard.release("1245689"["!@$%^*(".index(n)])
            keyboard.release(Key.shift)
        elif n != " " and n != "-":
            keyboard.press(n)
            if music.index(n) != len(music) - 1 and music[music.index(n) + 1] == ")":
                time.sleep(keytime / 2)
            else:
                time.sleep(keytime)
            keyboard.release(n)
        elif n == "-":
            time.sleep(2 * keytime)
        else:
            time.sleep(keytime)

2. 添加演奏旋律多线程

因为整首音乐弹奏的时候,有时候需要双手同时控制演奏,所以我们需要通过线程模拟出主旋律、和弦、右手拇指、右手食指、左手拇指、左手食指各个部分的演奏效果,通过多线程开启上面的演奏函数。核心代码如下:

# author:Dragon少年
def thread_play(play_piano, keytime, right="", left="", rightThumb="", rightIndexFinger="", leftThumb="",
                leftIndexFinger=""):
    # 运行线程
    rt = threading.Thread(target=play_piano, args=(right, keytime))  # 主旋律线程
    lt = threading.Thread(target=play_piano, args=(left, keytime))  # 和弦线程
    rtt = threading.Thread(target=play_piano, args=(rightThumb, keytime))  # 右手拇指线程
    rift = threading.Thread(target=play_piano, args=(rightIndexFinger, keytime))  # 右手食指线程
    ltt = threading.Thread(target=play_piano, args=(leftThumb, keytime))  # 左手拇指线程
    lift = threading.Thread(target=play_piano, args=(leftIndexFinger, keytime))  # 右手食指线程

3. 手指演奏曲谱

双手弹琴那么就需要确认好整首音乐中,各个手指的弹奏节奏和弹奏内容。我们需要模拟出各个阶段需要的演奏音乐并拼出整首音乐。下面就以《天空之城》为例,核心代码如下:

# author:Dragon少年
# 右手
right = "s-as f |a --u |p -ops |" \
            "o --uu|i-uis-|u - sss|a-Ii a |" \
            "a --|"
# 左手
left = "etu --|0wr --|qet --|" \
       "80w --|9qe --|80w --|7Qr --|" \
       "370Wr |"
# 演奏线程
thread_play(play_piano, 0.3, right, left)
right = "---op|s-as f |a --u |p -ops |" \
        "o --uu|i-uis-|u - sss|a-Ii a |" \
        "a --pa|s-as f |a --u |p -ops |"
left = "----|etu --|0wr --|qet --|" \
       "80w --|9qe --|80w --|7Qr --|" \
       "370Wr u |etu --|0wr --|qet --|"
# 演奏线程
thread_play(play_piano, 0.25, right, left)
# 右手
right = "o --uu|i sa-s |d fs--|sap a O |" \
        "p --sd|f-df h |d --o |s-as f |" \
        "f --oo|pas asd |s-oo- |d s a p |"
# 左手
left = "80w --|9qe --|680 --|9ey 0 -|" \
       "e ---|89w -t |579 --|60e -t |" \
       "370 w -|q -q -|0 ---|9 ---|"
# 右拇指
rightThumb = "----|----|----|--W -|" \
             "s ---|----|----|----|" \
             "----|----|----|g f d s |"
# 右食指
rightIndexFinger = "----|----|----|--r -|" \
                   "u ---|----|----|----|" \
                   "----|e -r -|w ---|e ---|"
# 左拇指
leftThumb = "----|----|----|----|" \
            "----|----|----|----|" \
            "----|t -y -|t ---|t ---|"
# 演奏线程
thread_play(play_piano, 0.25, right, left, rightThumb, rightIndexFinger, leftThumb)
# 右手
right = "a --f |j -h -|fds -s |d-sd h |" \
        "f --f |j -h -|"
# 左手
left = "3 %70Wru|60e 37w |48qer w |59q e t |" \
       "80wty -|60e 37w |"
# 右手拇指
rightThumb = "f ---|----|----|----|" \
             "----|----|"
# 右食指
rightIndexFinger = "----|----|----|----|" \
                   "----|----|"
# 左拇指
leftThumb = "----|----|----|----|" \
            "----|----|"
# 演奏线程
thread_play(play_piano, 0.25, right, left, rightThumb, rightIndexFinger, leftThumb)
# 右手
right = "fds -s |d-sd a |u --op|"
# 左手
left = "48qer w |7 -7 % |6 ---|"
# 右拇指
rightThumb = "----|9 ---|8"
# 右食指
rightIndexFinger = "----|q ---|0"
# 左拇指
leftThumb = "----|----|p"
# 多线程模拟手指弹琴,按键时间为0.3s
thread_play(play_piano, 0.3, right, left, rightThumb, rightIndexFinger, leftThumb)
right = "s-as f |a --u |p -ops |" \
        "o --uu|i-uis-|u - sss|a-Ii a |" \
        "a --|"
left = "etu --|0wr --|qet --|" \
       "80w --|9qe --|80w --|7Qr --|" \
       "370Wr |"
thread_play(play_piano, 0.4, right, left)

4. 钢琴模拟演奏

最后我们只需要打开钢琴auto piano网页,(注意:博主这里是直接通过桌面任务栏程序打开的浏览器窗口,所以需要手动浏览器先打开自由钢琴网页)通过控制键盘按键,实现手指演奏曲谱线程,就可以模拟弹奏出整首音乐了。核心代码如下:

# author:Dragon少年
# 控制键盘键入
keyboard = Controller()
# 切换到键盘钢琴网页端
keyboard.press(Key.cmd)
# 延时
time.sleep(1)
keyboard.press("d")
keyboard.release("d")
keyboard.release(Key.cmd)
# 链接的方式点击桌面任务栏的正在运行程序print_control_identifiers()
dlg = Desktop(backend="uia").任务栏.运行中的程序.child_window(title="Google Chrome - 1 个运行窗口", auto_id="Chrome",
                                                     control_type="Button").click()
time.sleep(2)
keyboard.press(Key.f11)
keyboard.release(Key.f11)

至此,自动化弹钢琴就实现完成了,当然如果需要实现别的钢琴演奏,只需要会看乐谱,根据乐谱修改各个阶段手指弹奏线程,就可以实现不同乐曲的钢琴演奏啦!

最后大家一起来欣赏欣赏Python演奏的钢琴曲《天空之城》效果如何吧!

在这里插入图片描述
若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。

创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

Dragon少年 | 文

如果本篇博客有任何错误,请批评指教,不胜感激 !


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK