对音频打上标签,从标签开始播放

本文介绍了作者使用Python和相关库(如Tkinter和pygame)开发的一个简单的音频播放器,具备添加、删除标记和播放控制功能,尽管代码有待优化,但能满足基本需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于工作需要,需要学习英语,当我在做听力的时候发现,每一段篇章我想听多次的时候每一次都要拖拉到具体位置,而且还很难准确到我想听的时间点,我就简单写了一个打标签的python程序。由于搞得很仓储,没有简化代码,还有前进和后退2s功能没有实现,但是已经满足我的日常需求,之后有时间再修改吧,具体代码如下:

import tkinter as tk
from tkinter import filedialog, StringVar
import pygame
import json


class AudioPlayer():

    def __init__(self):
        pygame.mixer.init()
        self.audio_file = None
        self.markers = {}
        self.duration = 0
        self.position = 0
        self.start_time = 0
        self.audio_from_start = True
        # self.restart = True
        self.update_delay = 1000  # update every second

    def open_audio_file(self):
        # global audio_from_start
        self.audio_from_start = True
        file_path = filedialog.askopenfilename(filetypes=[("Audio Files",
                                                           "*.mp3;*.wav")])
        if file_path:
            self.audio_file = file_path
            pygame.mixer.music.load(self.audio_file)
            self.duration = pygame.mixer.Sound(self.audio_file).get_length()
            # self.update_markers()

    def add_marker(self):
        marker_time = entry.get()
        minutes, seconds = map(int, marker_time.split(":"))
        time = minutes * 60 + seconds
        self.markers[marker_time] = time
        self.markers = dict(sorted(self.markers.items(), key=lambda x: x[1]))
        self.update_markers()

    def delete_marker(self):
        marker_time = entry.get()
        if marker_time in self.markers:
            del self.markers[marker_time]
        self.update_markers()

    def play_from_marker(self, event):
        marker_time = event.widget.cget("text")
        time = self.markers[marker_time]
        self.start_time = time  # 记录开始播放的时间
        pygame.mixer.music.play(start=time)
        self.update_current_time_label()

    def play(self):
        # 这个if好像没用
        if self.audio_from_start:
            pygame.mixer.music.play(start=0.0)
            self.audio_from_start = False
        else:
            pygame.mixer.music.unpause()
        self.update_current_time_label()

    def pause(self):
        pygame.mixer.music.pause()

    def clear(self):
        for widget in markers_frame.winfo_children():
            widget.destroy()
        self.markers = {}

    def save_markers(self):
        try:
            file_path = filedialog.asksaveasfilename(defaultextension='.json',
                                                     filetypes=[('JSON Files',
                                                                 '*.json')])
            if file_path:
                with open(file_path, 'w') as f:
                    json.dump(self.markers, f)
        except (IOError, OSError):
            print("Error saving markers.")

    def load_markers(self):
        try:
            file_path = filedialog.askopenfilename(filetypes=[('JSON Files',
                                                               '*.json')])
            if file_path:
                with open(file_path, 'r') as f:
                    self.markers = json.load(f)
                    self.update_markers()
        except FileNotFoundError:
            print("Markers file not found.")

    def update_current_time_label(self):
        if pygame.mixer.music.get_busy():
            self.position = pygame.mixer.music.get_pos() / 1000
            # 加上开始播放的时间,得到相对位置
            self.position = self.start_time + self.position
            current_time.set(
                f"{int(self.position // 60):02d}:{int(self.position % 60):02d}"
            )
            window.after(self.update_delay, self.update_current_time_label)

    def update_markers(self):

        for widget in markers_frame.winfo_children():
            widget.destroy()
        for marker_time in self.markers:
            marker_button = tk.Button(markers_frame, text=marker_time)
            marker_button.pack(side=tk.LEFT)
            marker_button.bind("<Button-1>", self.play_from_marker)

        # self.after(1000, self.update_markers)
    def rewind(self):
        self.position = pygame.mixer.music.get_pos() / 1000 + self.start_time
        self.position = self.position - 2
        pygame.mixer.music.play(start=self.position)
        self.update_current_time_label()

    def forward(self):
        self.position = pygame.mixer.music.get_pos() / 1000 + self.start_time
        self.position = self.position + 2
        pygame.mixer.music.play(start=self.position)
        self.update_current_time_label()


player = AudioPlayer()
window = tk.Tk()
current_time = StringVar()
current_time.set("00:00")

# 创建一个Frame容器
frame = tk.Frame(window)
frame.pack()  # 将Frame放置在窗口中

open_button = tk.Button(frame,
                        text="Open Audio File",
                        command=player.open_audio_file,
                        width=12)
# open_button.pack()
open_button.grid(row=0, column=0)

load_markers_button = tk.Button(frame,
                                text="Load Markers",
                                command=player.load_markers,
                                width=12)
load_markers_button.grid(row=0, column=1)


def on_enter(event):
    player.add_marker()


entry = tk.Entry(frame, width=12)
entry.grid(row=0, column=2)
entry.bind("<Return>", on_enter)

add_marker_button = tk.Button(frame,
                              text="Add Marker",
                              command=player.add_marker,
                              width=12)
add_marker_button.grid(row=0, column=3)

delete_marker_button = tk.Button(frame,
                                 text="Delete Marker",
                                 command=player.delete_marker,
                                 width=12)
delete_marker_button.grid(row=0, column=4)

save_markers_button = tk.Button(frame,
                                text="Save Markers",
                                command=player.save_markers,
                                width=12)
save_markers_button.grid(row=0, column=5)

markers_frame = tk.Frame(frame)
markers_frame.grid(row=1, columnspan=6)

current_time_label = tk.Label(frame, textvariable=current_time, width=12)
current_time_label.grid(row=2, column=0, sticky=tk.W)

rewind_button = tk.Button(frame,
                          text="Rewind 2s",
                          command=player.rewind,
                          width=12)
rewind_button.grid(row=2, column=1)

forward_button = tk.Button(frame,
                           text="forward 2s",
                           command=player.forward,
                           width=12)
forward_button.grid(row=2, column=2)

play_button = tk.Button(frame, text="Play", command=player.play, width=12)
play_button.grid(row=2, column=3)

pause_button = tk.Button(frame, text="Pause", command=player.pause, width=12)
pause_button.grid(row=2, column=4)

clear_button = tk.Button(frame, text="Clear", command=player.clear, width=12)
clear_button.grid(row=2, column=5)

# window.after(0, player.update_current_time_label)
window.mainloop()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值