为什么pygame音乐不会倒退

问题描述

我编写了非常简单的代码来加载 MP3 并播放歌曲,我试图让音乐返回 5 秒,但它没有。第一次点击持续 5 秒,然后持续不到 5 秒并停止前进。

代码

def backwards():
    cur_sec = pygame.mixer.music.get_pos()/1000 - 5
    print(cur_sec) # prints in seconds correctly but never decreases
    pygame.mixer.music.set_pos(cur_sec)

即使是这个相对时间也会产生与以前相同的效果

import pygame
from tkinter import *

root = Tk()
pygame.mixer.init()
pygame.mixer.music.load('music.mp3')

Button(root,text='Clikc',command=lambda:pygame.mixer.music.play()).pack()
Button(root,text='Clicker',command=lambda:pygame.mixer.music.set_pos(-5)).pack() #using relative time as said by pygame documentation

root.mainloop()

如果这应该可以完美运行,那么我也许可以举一个可重复的示例。有没有关于 pygame 的事情我忘记了?提前致谢:D

解决方法

根据get_pos()的文档:

这将获取音乐已播放的毫秒数 为了。返回的时间只代表音乐播放了多长时间 玩;它不考虑任何起始位置偏移。

因此它可能不会返回正在播放的音乐的实际位置。

您需要自己跟踪经过的时间并使用rewind()set_pos()来设置音乐的播放位置。下面是一个例子:

import time
import tkinter as tk
import pygame

stime = None

def play():
    global stime
    pygame.mixer.music.play()
    stime = time.time()

def backwards():
    global stime
    if stime:
        elapsed = time.time() - stime
        delta = min(elapsed,5)
        pygame.mixer.music.rewind()
        pygame.mixer.music.set_pos(elapsed-delta)
        stime += delta # adjust the "play start time" after backwards

root = tk.Tk()

pygame.mixer.init()
pygame.mixer.music.load("Leader of the Band.mp3")

tk.Button(root,text="Play",width=10,command=play).pack()
tk.Button(root,text="Back 5s",command=backwards).pack()

label = tk.Label(root,font="Consolas 12")
label.pack()

# function to show the music elapsed time
def tick():
    global stime
    if not pygame.mixer.music.get_busy():
        stime = None
    elapsed = time.time()-stime if stime else 0
    mins,secs = divmod(elapsed,60)
    label.config(text=f"{mins:02.0f}:{secs:06.3f}")
    label.after(100,tick)

tick()

root.mainloop()

更新:添加“暂停”功能:

import time
import tkinter as tk
import pygame

stime = None
is_paused = False
elapsed = 0

def play():
    global stime,is_paused
    pygame.mixer.music.play()
    stime = time.time()
    is_paused = False
    pause_btn.config(text="Pause")

def backwards():
    global stime,is_paused,elapsed
    if stime and not is_paused:
        elapsed = time.time() - stime
        delta = min(elapsed,5)
        '''
        pygame.mixer.music.rewind()
        pygame.mixer.music.set_pos(elapsed-delta)
        '''
        pygame.mixer.music.play(start=elapsed-delta)
        stime += delta

def pause():
    global is_paused,stime,elapsed
    is_paused = not is_paused
    now = time.time()
    if is_paused:
        elapsed = now - stime  # save the elapsed time
        pygame.mixer.music.pause()
        pause_btn.config(text="Resume")
    else:
        pygame.mixer.music.unpause()
        pause_btn.config(text="Pause")
        stime = now - elapsed # adjust the start time

root = tk.Tk()

pygame.mixer.init()
pygame.mixer.music.load("Leader of the Band.mp3")

tk.Button(root,command=play).pack()
back_btn = tk.Button(root,command=backwards)
back_btn.pack()
pause_btn = tk.Button(root,text="Pause",command=pause)
pause_btn.pack()

label = tk.Label(root,font="Consolas 12")
label.pack()

def tick():
    global stime,elapsed
    if not is_paused:
        if not pygame.mixer.music.get_busy():
            stime = None
        elapsed = time.time()-stime if stime else 0
        mins,60)
        label.config(text=f"{mins:02.0f}:{secs:06.3f}")
    back_btn.config(state="disabled" if is_paused else "normal")
    label.after(100,tick)

tick()
root.mainloop()