我正在编写一个程序(使用Qt 6.5.1,在M1 Mac上),需要播放多个mp3文件(一个接一个)。我使用以下代码遇到了错误:
void MainWindow::PlayMp3FileWithMediaPlayer(const QString &audio_file)
{
Q_ASSERT(audio_output_ != nullptr);
QMediaPlayer *player = new QMediaPlayer();
player->setAudioOutput(audio_output_);
connect(player, &QMediaPlayer::sourceChanged, this, [this, player]() {
player->play();
qDebug() << "Playing:" << player->source();
//QTimer::singleShot(player->duration(), this, [this]() { FinishWait(); });
});
connect(player, &QMediaPlayer::errorChanged, this, [this, player]() {
qDebug() << player->error() << player->errorString();
if (player->error() != QMediaPlayer::NoError)
{
FinishWait();
}
});
connect(player, &QMediaPlayer::mediaStatusChanged, this, [this, player](QMediaPlayer::MediaStatus status) {
qDebug() << status;
if (status == QMediaPlayer::EndOfMedia)
{
FinishWait();
}
});
QTimer::singleShot(0, this, [this, player, audio_file]() {
player->setSource(QUrl::fromLocalFile(audio_file));
});
qDebug() << "Going to play:" << audio_file;
StartWait();
// const int delay = 10000;
// QTimer::singleShot(delay, player, &QObject::deleteLater);
// QTimer::singleShot(delay, output, &QObject::deleteLater);
player->setAudioOutput(nullptr);
player->deleteLater();
}
当这个函数被调用(多次)时,经常会遇到
player
挂起并且不发出 mediaStatusChanged(QMediaPlayer::EndOfMedia) 信号的问题。 player
仍处于 playing
状态,但没有进展。计算机没有声音(出现故障后)。然后,如果我打开另一个播放声音的程序,我可以听到我的程序正在重复声音(它挂起的位置,可能是最后 100 毫秒)。
这是我的程序的一些输出,我们可以看到在
QMediaPlayer::BufferedMedia
之后,没有 QMediaPlayer::EndOfMedia
(预期,因为播放器挂起)。
Going to play: "/Users/huafeng/Documents/GitHub/chesstools/GameEditor/move_voices/7.mp3"
QMediaPlayer::LoadingMedia
QMediaPlayer::BufferedMedia
Playing: QUrl("file:///Users/huafeng/Documents/GitHub/chesstools/GameEditor/move_voices/7.mp3")
[mp3float @ 0x1370d45e0] Could not update timestamps for skipped samples.
[mp3float @ 0x1370d45e0] Could not update timestamps for discarded samples.
QMediaPlayer::EndOfMedia
Going to play: "/Users/huafeng/Documents/GitHub/chesstools/GameEditor/move_voices/Nbd4.mp3"
QMediaPlayer::LoadingMedia
QMediaPlayer::BufferedMedia
Playing: QUrl("file:///Users/huafeng/Documents/GitHub/chesstools/GameEditor/move_voices/Nbd4.mp3")
[mp3float @ 0x137158430] Could not update timestamps for skipped samples.
[mp3float @ 0x137158430] Could not update timestamps for discarded samples.
QMediaPlayer::EndOfMedia
Going to play: "/Users/huafeng/Documents/GitHub/chesstools/GameEditor/move_voices/8.mp3"
QMediaPlayer::LoadingMedia
QMediaPlayer::BufferedMedia
Playing: QUrl("file:///Users/huafeng/Documents/GitHub/chesstools/GameEditor/move_voices/8.mp3")
[mp3float @ 0x1370d57f0] Could not update timestamps for skipped samples.
我添加了代码来检查播放器状态并且它正在播放,但position() 没有改变。 我尝试避免新建/删除 QMediaPlayer、QAudioOutput,但没有成功。 或者,我使用以下代码用 python 播放 mp3 文件,一切都按预期工作。
void MainWindow::PlayAudioFile(const QString &unique_move_id, int sentence, const QString &audio_file)
{
PlayMp3FileWithMediaPlayer(audio_file);
//PlayMp3FileWithPython(audio_file);
}
void MainWindow::PlayMp3FileWithPython(const QString &audio_file)
{
QStringList arguments;
arguments << QString(_PROJECT_SRC_DIR_) + "/play_sound_file.py" << audio_file;
QProcess *python_process = new QProcess(this);
python_process->setProgram(python_program_);
python_process->setArguments(arguments);
connect(python_process, &QProcess::finished, this, &MainWindow::FinishWait);
QTimer::singleShot(0, this, [this, python_process]() { python_process->start(); });
StartWait();
python_process->deleteLater();
}
有什么想法吗?
而不是
connect(player, &QMediaPlayer::mediaStatusChanged, this, [this, player](QMediaPlayer::MediaStatus status) {
qDebug() << status;
if (status == QMediaPlayer::EndOfMedia)
{
FinishWait();
}
});
我用过
connect(player, &QMediaPlayer::mediaStatusChanged, player, [this](QMediaPlayer::MediaStatus status) {
qDebug() << status;
if (status == QMediaPlayer::EndOfMedia)
{
FinishWait();
}
});
这对我有用。 输出看起来像
QMediaPlayer::LoadingMedia
QMediaPlayer::BufferedMedia
QMediaPlayer::LoadedMedia
媒体播放完毕后,控制台显示如下
QMediaPlayer::EndOfMedia
Qt 6.5、Windows 11