如果我用它调用函数,QMediaPlayer.play() 不起作用
QMediaPlayer.play() doesn't work if I call a function with it
我正在用 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)));
}
你错过了 setMedia
works asynchronously. That is, it returns with no guarantee that the media file is loaded, from the docs:
This function returns immediately after recording the specified source
of the media. It does not wait for the media to finish loading and does not check for errors. Listen for the mediaStatusChanged()
and error()
signals to be notified when the media is loaded and when an error occurs during loading.
这意味着当你在调用player.setMedia(...);
之后调用this->playClicked();
时,很有可能媒体文件还没有加载,而调用player.duration()
失败(它不会 return 您尝试播放的媒体文件的实际持续时间)。因此,您最终的持续时间滑块的范围为 (0, 0)
,这会导致稍后调用 player.stop()
,因为您认为您已到达媒体文件的末尾。 . .
要解决这个问题,您需要按照文档中的说明进行操作。请确保不要前进到 playClicked
插槽,除非您确保您的媒体文件已完全加载。您可以通过更换您的:
this->playClicked();
像这样:
connect(&player, &QMediaPlayer::mediaStatusChanged,
this, [&](QMediaPlayer::MediaStatus status){
if(status == QMediaPlayer::LoadedMedia) playClicked();
});
我正在用 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)));
}
你错过了 setMedia
works asynchronously. That is, it returns with no guarantee that the media file is loaded, from the docs:
This function returns immediately after recording the specified source of the media. It does not wait for the media to finish loading and does not check for errors. Listen for the
mediaStatusChanged()
anderror()
signals to be notified when the media is loaded and when an error occurs during loading.
这意味着当你在调用player.setMedia(...);
之后调用this->playClicked();
时,很有可能媒体文件还没有加载,而调用player.duration()
失败(它不会 return 您尝试播放的媒体文件的实际持续时间)。因此,您最终的持续时间滑块的范围为 (0, 0)
,这会导致稍后调用 player.stop()
,因为您认为您已到达媒体文件的末尾。 . .
要解决这个问题,您需要按照文档中的说明进行操作。请确保不要前进到 playClicked
插槽,除非您确保您的媒体文件已完全加载。您可以通过更换您的:
this->playClicked();
像这样:
connect(&player, &QMediaPlayer::mediaStatusChanged,
this, [&](QMediaPlayer::MediaStatus status){
if(status == QMediaPlayer::LoadedMedia) playClicked();
});