0

我编写了一个程序,可以帮助我在歌曲的歌词之间快速切换。它从文件中读取歌词.lyr并将它们打印出来给我。

这是一个简化版本,没有任何附加功能,例如edit_line(). 此代码仍然出现问题。

import os

class Lyrics:

    def __init__(self, file):
        '''Initialize new Lyrics object'''
        self.file = file.replace("/", "\\")
        self.path = self.file.rsplit("\\", 1)[0] + "\\"
        self.suffix = "." + self.file.rsplit(".")[-2]
        self.name = self.file\
                    .replace(self.path, "")\
                    .replace(".lyr", "")\
                    .replace(self.suffix, "")

    def draw(self):
        '''Draw lyrics on user's screen'''
        maxlen = len(str(len(self.content)))
        print("[[ %s ]]"%self.name)
        for i,line in enumerate(self.content):
            print("%i  %s"%(i+1, line), end="")

    def play(self):
        '''View lyrics'''
        with open(self.file, "r") as f:
            self.content = f.readlines()
        #os.system("cls")
        self.draw()
        input("[[ Press enter to quit ... ]]")

def main(directory):
    # Get lyric files from directory
    lyric_files = []
    for file in os.listdir(directory):
        if file.endswith(".lyr"):
            lyric_files.append(Lyrics(directory + file))

    # Create variable for showing messages to user
    msg = ""

    # Main loop
    while True:

        # Print lyric files
        #os.system("cls")
        for i, file in enumerate(lyric_files):
            print("%i :: %s"%(i+1, file.name))

        # Handle input
        cmd = input("%s>"%msg)
        if cmd == "bye":
            break
        try:
            lyric_files[int(cmd)-1].play()
            msg = ""
        except ValueError:
            msg = "ValueError: Input must be an integer\n"
        except IndexError:
            msg = "IndexError: Integer must be between 1 and %i\n"%len(lyric_files)


if __name__ == "__main__":
    main("E:\\documents\\lyrics\\")

中的文件E:\documents\lyrics\使用以下格式命名:

Artist - Song.format.lyr`

例如:

E:\documents\lyrics\Adele - Set Fire to the Rain.mp3.lyr

当我打开程序时,它会按原样列出所有文件,然后要求我输入:

1 :: Adele - Set Fire to the Rain
2 :: Eminem - Not Afraid
3 :: Nicki Minaj - Starships
>

Set Fire to the Rain当我用 index打开歌词时1,它们打开得非常完美。但是,当我尝试打开歌词时Not Afraid,我可以在输出中看到大约 50 行歌词,而歌词文件实际上是 120 行左右。然后它要求我输入来自main()函数的输入,ValueError如下所示:

1  first_line_in_lyrics
2  second_line_in_lyrics
i  ...
42 fourty_second_line_in_lyrics
43 fourty_third_line_in_lyrics
1 :: Adele - Set Fire to the Rain
2 :: Eminem - Not Afraid
3 :: Nicki Minaj - Starships
ValueError: Input must be an integer
>

这些文件彼此几乎相同(当然歌词不同)。该程序在 IDLE 上运行良好,但在 python 命令行上却不行。

4

2 回答 2

0

这个问题看起来很奇怪,但并非不可能。这是我们目前得到的:

  1. 由于文件确实打开并且其中一些被打印出来,所以问题必须出在文件的打印上。
  2. 我三次检查了您的代码,问题不在您的draw()方法中。
  3. 由于问题只发生在某些文件上,而其他文件没有,问题可能出在文件本身上。
  4. 由于问题只发生在 python 命令行而不是 IDLE:问题必须在打印某些文件的某些内容,这些文件可以在 IDLE 中打印,但不能在 python 命令行中打印。

如果您确定您的绘图功能看起来完全像这样(我花了一段时间才弄清楚这maxlen件事):

def draw(self):
    '''Draw lyrics on user's screen'''
    maxlen = len(str(len(self.content)))
    print("[[ %s ]]"%self.name)
    for i,line in enumerate(self.content):
        print("%i  %s"%(i+1, line), end="")

我们只剩下这样一个事实,即self.content文件内容本身和/或文件内容本身存在问题。

简单地说:我 99% 确定文件中有一些字符可以由 IDLE 打印,但不能由 python 命令行打印。这样的字符可以是任何东西:%, ', ", ´, |, #,甚至是一些不使用箭头键滚动就看不到的不可见字符。

如果您可以发布您的歌词内容,我可以尝试提供更多帮助。尤其是最后打印的行,以及根本不打印的第一行。

于 2013-01-24T14:32:45.240 回答
0

你说你编写了一个程序:

它从 .lyr 文件中读取歌词并将其打印给我

但是我对您的程序的阅读:

def get_lyric_files(path):
    lyric_files = []
    for lyrics in os.listdir(path):
        if lyrics[:-4].split(".")[-1] in ("wav", "mp3"):
            lyric_files .append(Lyrics(path + lyrics))
    return lyric_files

看起来您从 .mp3 和 .wav 文件中获取歌词。一些 mp3 文件包含歌词标签,但您不解析它们。也许你打算:

lyric_files .append(Lyrics(path + lyrics + '.lyr'))

开始编辑

我现在看到我误读了这一行:

if lyrics[:-4].split(".")[-1] in ("wav", "mp3"):

我以为是:

if lyrics[-4:].split(".")[-1] in ("wav", "mp3"):

此代码匹配*.mp3.???. 如果您只是在寻找 .lyr 文件,为什么不:

if lyrics[-8:] in (".wav.lyr", ".mp3.lyr"):

编辑 2

此外,这也不好:

try:
    lyrics[int(cmd)-1].play()
except ValueError:
    pass
except IndexError:
    pass

您真的要在 .play() 中捕获并忽略 ValueError 和 IndexError 吗?反而:

try:
    lyric = lyrics[int(cmd)-1]
except ValueError:
    print 'You must enter a number'
except IndexError:
    print 'You must enter a number between 1 and', len(lyrics)
else:
    lyric.play()

如果它正在发挥作用,这可能会帮助您找到您的问题,因为它try不会掩盖任何错误。

结束编辑

否则,如果您想从 .mp3 文件中读取歌词,您可以使用 mutagen 之类的库

import mutagen, mutagen.mp3, mutagen.easyid3

# . . .

mp3Tags = mutagen.mp3.MP3(mp3FileName)
lyricFrame = mp3Tags.get("USLT::'eng'")
if lyricFrame:
    lyricText = lyricFrame.text
    lyrics = lyricText.split('\n')
于 2013-01-23T21:28:15.777 回答