209 lines
7.1 KiB
Python
209 lines
7.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
@Time : 2023/4/10/010 11:10
|
|
@Author : 李子
|
|
@Url : https://github.com/kslz
|
|
"""
|
|
from PySide6 import QtCore
|
|
from PySide6.QtCore import Signal, QThread
|
|
from PySide6.QtWidgets import QPushButton
|
|
|
|
from utils.tools import *
|
|
|
|
|
|
class FastOutputSoundBTN(QPushButton):
|
|
def __init__(self, text, info_id, parent):
|
|
super().__init__(text, parent)
|
|
self.info_id = info_id
|
|
self.clicked.connect(self.fast_output_sound)
|
|
# self.setText("快速导出")
|
|
# info = Info.get_by_id(self.info_id)
|
|
# wav_path = info.info_raw_file_path
|
|
# start_time = info.info_start_time
|
|
# end_time = info.info_end_time
|
|
|
|
def fast_output_sound(self):
|
|
info = Info.get_by_id(self.info_id)
|
|
wav_path = info.info_raw_file_path
|
|
start_time = info.info_start_time
|
|
end_time = info.info_end_time
|
|
output_name = str(self.info_id) + ".wav"
|
|
fast_output_sound(wav_path, start_time, end_time, output_name)
|
|
|
|
class DeleteBTN(QPushButton):
|
|
def __init__(self, text, info_id, parent, info_is_del):
|
|
super().__init__(text, parent)
|
|
self.info_id = info_id
|
|
self.info_is_del = info_is_del
|
|
if self.info_is_del == False:
|
|
self.setText("删除")
|
|
else:
|
|
self.setText("恢复")
|
|
|
|
self.clicked.connect(self.change_is_del_sound)
|
|
|
|
def change_is_del_sound(self):
|
|
# 肯定是伪删除
|
|
new_is_del = True if self.info_is_del == False else False
|
|
Info.update(info_is_del=new_is_del).where(Info.info_id == self.info_id).execute()
|
|
self.info_is_del = new_is_del
|
|
if self.info_is_del == False:
|
|
self.setText("删除")
|
|
else:
|
|
self.setText("恢复")
|
|
|
|
|
|
|
|
class PlaySoundBTN(QPushButton):
|
|
class PlaySoundThread(QtCore.QThread):
|
|
update_signal = Signal(str, bool)
|
|
|
|
# stop_thread_signal = Signal()
|
|
|
|
def __init__(self, wav_path, start_time, end_time):
|
|
super().__init__()
|
|
# self.stop_flag = False
|
|
# self.stop_thread_signal.connect(self.stop_thread)
|
|
self.wav_path = wav_path
|
|
self.start_time = start_time
|
|
self.end_time = end_time
|
|
|
|
def run(self):
|
|
self.update_signal.emit("播放中", False)
|
|
play_by_ffmpeg(self.wav_path, self.start_time, self.end_time)
|
|
self.update_signal.emit("试听", True)
|
|
|
|
# def stop_thread(self):
|
|
# self.stop_flag = True
|
|
# print("收到停止信号")
|
|
# self.wait()
|
|
|
|
def __init__(self, text, info_id, parent):
|
|
super().__init__(text, parent)
|
|
self.info_id = info_id
|
|
self.clicked.connect(self.play_or_stop_sound)
|
|
info = Info.get_by_id(self.info_id)
|
|
wav_path = info.info_raw_file_path
|
|
start_time = info.info_start_time
|
|
end_time = info.info_end_time
|
|
# self.thread1 = QThread(self) # 创建一个线程 不行 没用明白,先这样吧
|
|
self.play_thread = self.PlaySoundThread(wav_path, start_time, end_time) # 实例化线程类
|
|
# self.play_thread.moveToThread(self.thread1) # 将类移动到线程中运行
|
|
# self.thread1.started.connect(self.play_thread.run)
|
|
self.play_thread.update_signal.connect(lambda text, is_enabled: self.set_text(text, is_enabled))
|
|
|
|
def play_or_stop_sound(self):
|
|
# 多线程避免阻塞界面
|
|
if self.text() == "试听":
|
|
self.play_thread.start()
|
|
else:
|
|
# 终止播放失败
|
|
# self.play_thread.stop_thread_signal.emit()
|
|
# self.play_thread.exit()
|
|
# self.set_text("试听", True)
|
|
pass
|
|
|
|
def set_text(self, text, is_enabled):
|
|
self.setText(text)
|
|
# self.setEnabled(is_enabled)
|
|
|
|
|
|
class BianJiBTN(QPushButton):
|
|
on_clicked = Signal(int)
|
|
|
|
def __init__(self, text, info_id):
|
|
super().__init__(text=text)
|
|
self.info_id = info_id
|
|
self.clicked.connect(self.button_clicked)
|
|
|
|
def button_clicked(self):
|
|
self.on_clicked.emit(self.info_id)
|
|
|
|
|
|
class AudioButton(QPushButton):
|
|
def __init__(self, wav_path, start_time, end_time, parent=None):
|
|
super().__init__(parent)
|
|
self.setText("试听")
|
|
self.audio_thread = None
|
|
self.wav_path = wav_path
|
|
self.start_time = start_time
|
|
self.end_time = end_time
|
|
|
|
# 连接按钮点击事件的槽函数
|
|
self.clicked.connect(self.on_button_clicked)
|
|
|
|
def on_button_clicked(self):
|
|
if self.audio_thread is not None and self.audio_thread.is_playing:
|
|
# 如果音频正在播放,停止播放
|
|
# print("停止播放")
|
|
self.audio_thread.stop()
|
|
self.audio_thread.wait()
|
|
self.audio_thread = None
|
|
self.setText("试听")
|
|
else:
|
|
# 如果音频没有在播放,开始播放
|
|
self.audio_thread = AudioThread(self.wav_path, self.start_time, self.end_time)
|
|
self.audio_thread.finished.connect(self.on_audio_finished)
|
|
self.audio_thread.start()
|
|
self.setText("停止")
|
|
|
|
def on_audio_finished(self):
|
|
self.audio_thread = None
|
|
self.setText("试听")
|
|
|
|
|
|
# 自定义的音频播放线程
|
|
class AudioThread(QThread):
|
|
finished = Signal() # 定义一个信号,用于通知播放完成
|
|
|
|
def __init__(self, wav_path, start_time, end_time, parent=None):
|
|
super().__init__(parent)
|
|
self.is_playing = False
|
|
self.wav_path = wav_path
|
|
self.start_time = start_time
|
|
self.end_time = end_time
|
|
|
|
def run(self):
|
|
self.is_playing = True
|
|
|
|
# play_by_ffmpeg(self.wav_path, self.start_time, self.end_time)
|
|
# 如果用函数形式调用,执行self.audio_thread.terminate()的时候声音就会卡几秒才停,直接写代码就可以秒停,原因未知
|
|
wav_path = self.wav_path
|
|
start_time = self.start_time
|
|
end_time = self.end_time
|
|
|
|
duration = (end_time - start_time) / 1000
|
|
start_time = start_time / 1000
|
|
|
|
# 从长音频文件中提取指定时间段的音频
|
|
output = (
|
|
ffmpeg
|
|
.input(wav_path, ss=start_time, t=duration)
|
|
# .filter("loudnorm", I="-23", dual_mono="true") # 归一化
|
|
.output('pipe:', format='wav', ar=44100)
|
|
.run(capture_stdout=True)
|
|
)
|
|
|
|
# 播放输出的音频
|
|
self.process = subprocess.Popen(['ffplay', "-nodisp", "-autoexit", '-'], stdin=subprocess.PIPE)
|
|
self.process.communicate(output[0])
|
|
|
|
self.is_playing = False
|
|
self.finished.emit() # 发送播放完成的信号
|
|
|
|
def stop(self):
|
|
if self.process and self.process.poll() is None: # 检查子进程是否在运行
|
|
self.process.terminate() # 终止子进程
|
|
|
|
|
|
class AudioNowButton(AudioButton):
|
|
def __init__(self, wav_path, start_time, end_time, parent=None):
|
|
super().__init__(wav_path, start_time, end_time, parent)
|
|
self.clicked.disconnect(super().on_button_clicked)
|
|
|
|
def on_button_clicked_new(self, start_time, end_time):
|
|
self.start_time = int(start_time)
|
|
self.end_time = int(end_time)
|
|
|
|
self.on_button_clicked()
|