当我在 simpleaudio 中停止音乐时,Linux 终端立即显示“分段错误(内存映像刷新到磁盘)”,并且程序崩溃。
我的程序:
from PyQt5.QtWidgets import QApplication, QMainWindow, QSlider, QPushButton, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt, QTimer
import sys
from threading import Thread
from time import sleep as wait
import simpleaudio as sa
from pydub import AudioSegment
class Program():
def __init__(self):
self.playing = False
self.pos = 0
self.length = 100000 # пока что оставим длину 100 секунд
self.audio_file_path = "/home/nikkonst/Музыка/F-777 - Cosmic Blaster - 05 Hey Man.mp3"
def play_level(self):
self.playing = True
Thread(target=self.play_level_thread, daemon=True).start()
def play_level_thread(self):
self.play_audio(self.audio_file_path)
while self.playing and self.pos < self.length:
self.pos += 10
editor.update_timeline()
wait(0.1)
def play_audio(self, path):
audio = AudioSegment.from_file(path)
wav_file_path = "temp.wav"
audio.export(wav_file_path, format="wav")
wave_obj = sa.WaveObject.from_wave_file(wav_file_path)
play_obj = wave_obj.play()
def stop_audio(self):
self.playing = False
sa.stop_all() # ошибка здесь
class LevelEditor(QMainWindow):
def __init__(self):
super().__init__()
self.program = Program()
self.setWindowTitle("2D Level Editor")
self.setGeometry(100, 100, 800, 600)
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
layout = QVBoxLayout()
self.timeline_slider = QSlider(Qt.Horizontal)
self.timeline_slider.setMaximum(1000)
layout.addWidget(self.timeline_slider)
self.play_button = QPushButton("Играть")
self.play_button.clicked.connect(self.toggle_playback)
layout.addWidget(self.play_button)
self.stop_button = QPushButton("Остановить")
self.stop_button.clicked.connect(self.stop_playback)
layout.addWidget(self.stop_button)
self.central_widget.setLayout(layout)
def toggle_playback(self):
self.timeline_slider.setMaximum(self.program.length)
if not self.program.playing:
print("playing")
self.program.play_level()
self.play_button.setText("Пауза")
else:
print("pause")
self.program.stop_audio() # stop_audio будет стоять здесь недолго. вместо нее потом будет функция для паузы превью уровня
self.play_button.setText("Играть")
def stop_playback(self):
print("stopping")
if self.program.playing:
self.program.stop_audio() # stop_audio будет стоять здесь недолго. вместо нее потом будет функция для остановки превью уровня
self.timeline_slider.setValue(0)
self.play_button.setText("Играть")
def update_timeline(self):
self.timeline_slider.setValue(self.program.pos)
if __name__ == "__main__":
app = QApplication(sys.argv)
editor = LevelEditor()
editor.show()
sys.exit(app.exec_())
使用 python 不可能导致分段错误。您链接到的用 C 或 C++ 编写的库之一存在错误。您可以将崩溃时转储到磁盘的应用程序内存映像加载到调试器中,并找出哪个模块出现故障。然后找到该模块的源代码和调试信息...并向模块的作者发送修复错误的建议..但您必须学习编写包含错误的模块的语言。
作为临时的解决方法,尝试使用 Qt 进行音频播放,它看起来很可靠。 https://doc.qt.io/qtforpython-5/overviews/multimediaoverview.html 示例: https: //github.com/baoboa/pyqt5/blob/master/examples/multimediawidgets/player.py