首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >游戏,声音(Mp3)不玩

游戏,声音(Mp3)不玩
EN

Stack Overflow用户
提问于 2022-07-17 12:45:33
回答 1查看 53关注 0票数 0

我试图播放声音文件(.mp3)与游戏和Tkinter,但当我启动它,我从来没有听到任何东西。这是代码:

代码语言:javascript
复制
from tkinter import StringVar, filedialog
import os 
import tkinter
import pygame
from pygame import *
 
root = tkinter.Tk()
path = filedialog.askdirectory()

pygame.init()
pygame.mixer.init()

def startm():
    if clicked.get() == mp3[0]:

        pygame.mixer.music.load(mp3[0])
        

if not path:
    print('Canceled')
else:
    mp3 = [fn for fn in os.listdir(path) if fn.lower().endswith('.mp3') and os.path.isfile(os.path.join(path, fn))]
    clicked = StringVar()
    tkinter.OptionMenu(root, clicked, mp3[0], *mp3).pack()

    w = tkinter.Button(root,text="start",command=startm)
    w.pack()

root.mainloop()

程序运行,但声音不起作用

EN

回答 1

Stack Overflow用户

发布于 2022-07-17 13:25:16

这里有几件事情要注意,为什么音频不播放,为什么逻辑有缺陷。

  1. 没有播放音频是因为你只是在加载音乐,而不是播放它。要演奏音乐,你必须说pygame.mixer.music.play().

现在,即使添加了

  1. ,您也不会注意到任何播放内容。这是因为if条件是没有意义的。if clicked.get() == mp3[0]:行的意思是:只有当选项菜单中的选择与mp3列表中的第一项相同时,才能播放歌曲。但是用户应该能够播放他们选择的任何歌曲,而不仅仅是列表中的第一首歌曲。所以你应该移除它。

  1. 现在您会注意到,尽管删除了它,但是您将得到另一个错误,因为文件路径不存在。基本上,clicked.get()只是文件名,而不是文件路径。使用这样的文件名将迫使python检查歌曲所在的相对路径。但是没有相对路径,以至于路径是真的。因此,您必须使用绝对路径。

  1. 现在要使用绝对路径,您将注意到歌曲的绝对路径将显示在选项菜单中。但是你不想那样,你只需要选项菜单上显示的歌曲名,但是你想用绝对路径播放这首歌,所以必须有某种映射,比如:

代码语言:javascript
复制
{ "song_name": "D:/path/to/dir/song_name.mp3" } # Key will be displayed in optionmenu but value will be used in `pygame` to load the music.

因此,进行上述更改的代码如下:

代码语言:javascript
复制
from glob import glob # (5) Mentioned in extra changes
from pathlib import Path # (6)
...
...

def startm():
    song_name = clicked.get() 
    song_abs_path = songs[song_name] # (4) Get the absolute path from the songs dictionary 
    # if clicked.get() == mp3[0]: # (2) Getting rid of this line
    pygame.mixer.music.load(song_abs_path) # (3) Loading song with its absolute path and not relative path 
    pygame.mixer.music.play() # (1) Play the song after loading it

if not path:
    print('Canceled')
else:
    mp3_abs_paths = glob(f"{path}/*.mp3") # (5) Choose all the mp3 files from the given path
    mp3_names = [Path(path).name for path in mp3_abs_paths] # (6) List of all the song names
    songs = {k:v for k,v in zip(mp3_names,mp3_abs_paths)} # (4) A dictionary in the format mentioned above above
    
    clicked = StringVar()
    tkinter.OptionMenu(root, clicked, mp3_names[0], *mp3_names).pack()

    w = tkinter.Button(root,text="start",command=startm)
    w.pack()

上面我提到的更改在上面代码的注释中做了标记,以使它更容易理解。

我做了一些额外的改变:

  1. I介绍了一个模块,它将使您的生活更加轻松,glob。它基本上可以替代您对mp3.

的列表理解所做的工作

  1. I使用了pathlib中的Path,因为它在许多方面比os.path更好,而且它也使将来与路径相关的操作比pathlib更简单一些。

另外,我要做的是取代OptionMenu,因为它有点俗气,海事组织。ttk.Combobox是一个很好的替代品。

代码语言:javascript
复制
from tkinter import ttk

clicked = StringVar() # You can also get rid of this and start using `combo.get()` as it gives same value as `clicked.get()` and `clicked` becomes useless then.
combo = ttk.Combobox(root, values=mp3_names, state='readonly',textvariable=clicked)
combo.current(0) # Make the first item of the list as the current selection
combo.pack()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73011911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档