From 426950fc1031b02a88893e84d294e4d7f7adfec6 Mon Sep 17 00:00:00 2001 From: xiaoyifang <105986+xiaoyifang@users.noreply.github.com> Date: Wed, 23 Oct 2024 20:14:11 +0800 Subject: [PATCH] opt: optimize the audio auto pronounciation logic (#1846) * opt: optimize the audio play logic --- src/ui/articleview.cc | 69 +++++++++++++++++++++++++++++++++++++++++++ src/ui/articleview.hh | 2 ++ src/ui/mainwindow.cc | 2 +- src/ui/scanpopup.cc | 3 +- 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/ui/articleview.cc b/src/ui/articleview.cc index 376c84f8..a211eac3 100644 --- a/src/ui/articleview.cc +++ b/src/ui/articleview.cc @@ -1141,6 +1141,53 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const & } } + +void ArticleView::playAudio( QUrl const & url ) +{ + audioPlayer->stop(); + qDebug() << "play audio,the link url:" << url; + + if ( url.scheme() == "bres" || url.scheme() == "gdau" || url.scheme() == "gdvideo" + || Utils::Url::isAudioUrl( url ) ) { + // Download it + + if ( Utils::Url::isWebAudioUrl( url ) ) { + sptr< Dictionary::DataRequest > req = std::make_shared< Dictionary::WebMultimediaDownload >( url, articleNetMgr ); + + connect( req.get(), &Dictionary::Request::finished, this, [ req, this ]() { + audioDownloadFinished( req ); + } ); + } + else if ( url.scheme() == "gdau" ) { + // Since searches should be limited to current group, we just do them + // here ourselves since otherwise we'd need to pass group id to netmgr + // and it should've been having knowledge of the current groups, too. + + sptr< Dictionary::Class > dict = dictionaryGroup->getDictionaryById( url.host().toStdString() ); + + if ( dict ) { + try { + sptr< Dictionary::DataRequest > req = dict->getResource( url.path().mid( 1 ).toUtf8().data() ); + + if ( !req->isFinished() ) { + // Queued loading + connect( req.get(), &Dictionary::Request::finished, this, [ req, this ]() { + audioDownloadFinished( req ); + } ); + } + else { + // Immediate loading + audioDownloadFinished( req ); + } + } + catch ( std::exception & e ) { + emit statusBarMessage( tr( "ERROR: %1" ).arg( e.what() ), 10000, QPixmap( ":/icons/error.svg" ) ); + } + } + } + } +} + ResourceToSaveHandler * ArticleView::saveResource( const QUrl & url, const QString & fileName ) { ResourceToSaveHandler * handler = new ResourceToSaveHandler( this, fileName ); @@ -1787,6 +1834,28 @@ void ArticleView::resourceDownloadFinished() } } + +void ArticleView::audioDownloadFinished( const sptr< Dictionary::DataRequest > & req ) +{ + if ( req->dataSize() >= 0 ) { + // Ok, got one finished, all others are irrelevant now + qDebug() << "audio download finished. Playing..."; + vector< char > const & data = req->getFullData(); + + // Audio data + audioPlayer->stop(); + connect( audioPlayer.data(), + &AudioPlayerInterface::error, + this, + &ArticleView::audioPlayerError, + Qt::UniqueConnection ); + QString errorMessage = audioPlayer->play( data.data(), data.size() ); + if ( !errorMessage.isEmpty() ) { + QMessageBox::critical( this, "GoldenDict", tr( "Failed to play sound file: %1" ).arg( errorMessage ) ); + } + } +} + void ArticleView::audioPlayerError( QString const & message ) { emit statusBarMessage( tr( "WARNING: Audio Player: %1" ).arg( message ), 10000, QPixmap( ":/icons/error.svg" ) ); diff --git a/src/ui/articleview.hh b/src/ui/articleview.hh index fd25f8a3..ca74cfd9 100644 --- a/src/ui/articleview.hh +++ b/src/ui/articleview.hh @@ -152,6 +152,8 @@ public: QUrl const & referrer, QString const & scrollTo = QString(), Contexts const & contexts = Contexts() ); + void playAudio( QUrl const & url ); + void audioDownloadFinished( const sptr< Dictionary::DataRequest > & req ); /// Called when the state of dictionary bar changes and the view is active. /// The function reloads content if the change affects it. diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc index 78689ba7..9d66c742 100644 --- a/src/ui/mainwindow.cc +++ b/src/ui/mainwindow.cc @@ -723,7 +723,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ): auto view = getCurrentArticleView(); if ( ( cfg.preferences.pronounceOnLoadMain ) && view != nullptr ) { - view->openLink( QUrl::fromEncoded( audioUrl.toUtf8() ), {} ); + view->playAudio( QUrl::fromEncoded( audioUrl.toUtf8() ) ); } } ); applyProxySettings(); diff --git a/src/ui/scanpopup.cc b/src/ui/scanpopup.cc index 95a90f58..b7f2d332 100644 --- a/src/ui/scanpopup.cc +++ b/src/ui/scanpopup.cc @@ -169,8 +169,7 @@ ScanPopup::ScanPopup( QWidget * parent, return; } if ( cfg.preferences.pronounceOnLoadPopup ) { - - definition->openLink( QUrl::fromEncoded( audioUrl.toUtf8() ), {} ); + definition->playAudio( QUrl::fromEncoded( audioUrl.toUtf8() ) ); } } ); pinnedGeometry = cfg.popupWindowGeometry;