1

我正在使用 Qt 创建一个音频播放器,并且我正在实现它,当我加载一首歌曲时它会自动启动,但是当我调用启动歌曲的函数并计算持续时间时,歌曲不会开始。我使用了调试,当我到达播放功能时,调试在结束步进范围内停止。我也尝试过发出信号但无事可做,只有按下播放按钮时歌曲才会开始。

这里有代码

void AudioPlayer::loadClicked()
{
    QString filename = QFileDialog::getOpenFileName(this, "Select an audio file", "C:/Users/belli/Music" ,"File Mp3 (*.mp3)");

    if(!filename.isEmpty())
    {
        qDebug("%s", filename.toLatin1().constData());
        player.setMedia(QUrl::fromLocalFile(filename));
        this->volumeSliderMoved();
        QFileInfo fi(filename);
        QString name = fi.fileName();
        ui->label->setText(name);
        this->playClicked();
    }
}

void AudioPlayer::playClicked()
{
    player.play();
    songLength = player.duration();
    ui->horizontalSliderPosition->setRange(0, songLength);
}

void AudioPlayer::stopClicked()
{
    player.stop();
    ui->horizontalSliderPosition->setValue(0);
}

void AudioPlayer::playerPositionChanged(qint64 pos)
{
   ui->horizontalSliderPosition->setValue(pos);
   if(pos == songLength)
       this->stopClicked();
}

void AudioPlayer::volumeSliderMoved()
{
    player.setVolume(ui->horizontalSliderVolume->value());
}

void AudioPlayer::positionSliderMoved()
{
    player.setPosition((quint64) ui->horizontalSliderPosition->value());
}

和连接

ui(new Ui::AudioPlayer)
{
    ui->setupUi(this);
    connect(ui->pushButtonLoad, SIGNAL(clicked(bool)), SLOT(loadClicked()));
    connect(ui->pushButtonPlay, SIGNAL(clicked(bool)), SLOT(playClicked()));
    connect(ui->pushButtonStop, SIGNAL(clicked(bool)), SLOT(stopClicked()));
    connect(ui->horizontalSliderVolume, SIGNAL(valueChanged(int)), SLOT(volumeSliderMoved()));
    connect(ui->horizontalSliderPosition, SIGNAL(sliderReleased()), SLOT(positionSliderMoved()));

    connect(&player, SIGNAL(positionChanged(qint64)), SLOT(playerPositionChanged(qint64)));
}
4

1 回答 1

1

您缺少setMedia异步工作的功能。也就是说,它返回时不保证媒体文件已从docs加载:

此函数在录制指定的媒体源后立即返回。不等待媒体完成加载,也不检查错误。当媒体加载和加载过程中发生错误时,监听mediaStatusChanged()error()信号。

这意味着当您在调用this->playClicked();后调用player.setMedia(...);时,很有可能媒体文件尚未加载,并且调用player.duration()失败(它不会返回您尝试播放的媒体文件的实际持续时间) . 因此,您最终会看到持续时间滑块的范围为(0, 0),这会导致player.stop()稍后调用,因为您认为您已经到达媒体文件的末尾。. .

要解决这个问题,您需要遵循文档中的内容。playClicked除非您确保媒体文件已完全加载,否则请确保不要进入您的插槽。你可以通过替换你的来做到这一点:

this->playClicked();

像这样:

connect(&player, &QMediaPlayer::mediaStatusChanged,
        this, [&](QMediaPlayer::MediaStatus status){
    if(status == QMediaPlayer::LoadedMedia) playClicked();
});
于 2017-02-26T23:46:55.357 回答