[vlc-devel] [PATCH 4/4] Qt: add fingerprinting ui
Francois Cartegnie
fcvlcdev at free.fr
Tue Feb 26 13:51:50 CET 2013
---
modules/gui/qt4/Modules.am | 8 ++
modules/gui/qt4/adapters/chromaprint.cpp | 77 ++++++++++++++
modules/gui/qt4/adapters/chromaprint.hpp | 55 ++++++++++
modules/gui/qt4/components/info_panels.cpp | 30 +++++-
modules/gui/qt4/components/info_panels.hpp | 5 +
modules/gui/qt4/dialogs/fingerprintdialog.cpp | 115 ++++++++++++++++++++
modules/gui/qt4/dialogs/fingerprintdialog.hpp | 61 +++++++++++
modules/gui/qt4/ui/fingerprintdialog.ui | 138 +++++++++++++++++++++++++
8 files changed, 487 insertions(+), 2 deletions(-)
create mode 100644 modules/gui/qt4/adapters/chromaprint.cpp
create mode 100644 modules/gui/qt4/adapters/chromaprint.hpp
create mode 100644 modules/gui/qt4/dialogs/fingerprintdialog.cpp
create mode 100644 modules/gui/qt4/dialogs/fingerprintdialog.hpp
create mode 100644 modules/gui/qt4/ui/fingerprintdialog.ui
diff --git a/modules/gui/qt4/Modules.am b/modules/gui/qt4/Modules.am
index 0fce86c..a3a3cc4 100644
--- a/modules/gui/qt4/Modules.am
+++ b/modules/gui/qt4/Modules.am
@@ -23,6 +23,7 @@ nodist_SOURCES_qt4 = \
extensions_manager.moc.cpp \
recents.moc.cpp \
adapters/seekpoints.moc.cpp \
+ adapters/chromaprint.moc.cpp \
variables.moc.cpp \
dialogs/playlist.moc.cpp \
dialogs/bookmarks.moc.cpp \
@@ -45,6 +46,7 @@ nodist_SOURCES_qt4 = \
dialogs/vlm.moc.cpp \
dialogs/firstrun.moc.cpp \
dialogs/extensions.moc.cpp \
+ dialogs/fingerprintdialog.moc.cpp \
components/extended_panels.moc.cpp \
components/info_panels.moc.cpp \
components/preferences_widgets.moc.cpp \
@@ -96,6 +98,7 @@ nodist_SOURCES_qt4 = \
ui/messages_panel.h \
ui/about.h \
ui/update.h \
+ ui/fingerprintdialog.h \
styles/seekstyle.moc.cpp \
dialogs/ml_configuration.moc.cpp \
components/playlist/ml_model.moc.cpp \
@@ -277,6 +280,7 @@ SOURCES_qt4 = qt4.cpp \
extensions_manager.cpp \
recents.cpp \
adapters/seekpoints.cpp \
+ adapters/chromaprint.cpp \
variables.cpp \
dialogs/playlist.cpp \
dialogs/bookmarks.cpp \
@@ -300,6 +304,7 @@ SOURCES_qt4 = qt4.cpp \
dialogs/firstrun.cpp \
dialogs/podcast_configuration.cpp \
dialogs/extensions.cpp \
+ dialogs/fingerprintdialog.cpp \
components/extended_panels.cpp \
components/info_panels.cpp \
components/preferences_widgets.cpp \
@@ -352,6 +357,7 @@ noinst_HEADERS = \
extensions_manager.hpp \
recents.hpp \
adapters/seekpoints.hpp \
+ adapters/chromaprint.hpp \
variables.hpp \
dialogs/playlist.hpp \
dialogs/bookmarks.hpp \
@@ -375,6 +381,7 @@ noinst_HEADERS = \
dialogs/firstrun.hpp \
dialogs/podcast_configuration.hpp \
dialogs/extensions.hpp \
+ dialogs/fingerprintdialog.hpp \
components/extended_panels.hpp \
components/info_panels.hpp \
components/preferences_widgets.hpp \
@@ -441,5 +448,6 @@ EXTRA_DIST += \
ui/update.ui \
ui/sout.ui \
ui/vlm.ui \
+ ui/fingerprintdialog.ui \
$(DEPS_res)
diff --git a/modules/gui/qt4/adapters/chromaprint.cpp b/modules/gui/qt4/adapters/chromaprint.cpp
new file mode 100644
index 0000000..f4b19c4
--- /dev/null
+++ b/modules/gui/qt4/adapters/chromaprint.cpp
@@ -0,0 +1,77 @@
+/*****************************************************************************
+ * chromaprint.cpp: Fingerprinter helper class
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "chromaprint.hpp"
+#include <vlc_fingerprinter.h>
+#include <vlc_modules.h>
+
+Chromaprint::Chromaprint( intf_thread_t *_p_intf ) : p_intf( _p_intf )
+{
+ Q_ASSERT( p_intf );
+ p_fingerprinter = fingerprinter_Create( VLC_OBJECT( p_intf ) );
+ if ( p_fingerprinter )
+ var_AddCallback( p_fingerprinter, "results-available", results_available, this );
+}
+
+int Chromaprint::results_available( vlc_object_t *, const char *, vlc_value_t, vlc_value_t , void *param )
+{
+ Chromaprint *me = (Chromaprint *) param;
+ me->finish();
+ return 0;
+}
+
+fingerprint_request_t * Chromaprint::fetchResults()
+{
+ return p_fingerprinter->pf_getresults( p_fingerprinter );
+}
+
+void Chromaprint::apply( fingerprint_request_t *p_r, int i_id )
+{
+ p_fingerprinter->pf_apply( p_r, i_id );
+}
+
+bool Chromaprint::enqueue( input_item_t *p_item )
+{
+ if ( ! p_fingerprinter ) return false;
+ fingerprint_request_t *p_r = fingerprint_request_New( p_item );
+ if ( ! p_r ) return false;
+ mtime_t t = input_item_GetDuration( p_item );
+ if ( t ) p_r->i_duration = (unsigned int) ( t / 1000000 );
+ p_fingerprinter->pf_enqueue( p_fingerprinter, p_r );
+ return true;
+}
+
+bool Chromaprint::isSupported( QString uri )
+{
+ if ( !module_exists( "stream_out_chromaprint" ) )
+ return false;
+ else
+ return ( uri.startsWith( "file://" ) || uri.startsWith( "/" ) );
+}
+
+Chromaprint::~Chromaprint()
+{
+ if ( p_fingerprinter )
+ fingerprinter_Destroy( p_fingerprinter );
+}
diff --git a/modules/gui/qt4/adapters/chromaprint.hpp b/modules/gui/qt4/adapters/chromaprint.hpp
new file mode 100644
index 0000000..af159d6
--- /dev/null
+++ b/modules/gui/qt4/adapters/chromaprint.hpp
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * chromaprint.hpp: Fingerprinter helper class
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef CHROMAPRINT_HPP
+#define CHROMAPRINT_HPP
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <QObject>
+#include <QString>
+#include <vlc_fingerprinter.h>
+#include <vlc_interface.h>
+
+class Chromaprint : public QObject
+{
+ Q_OBJECT
+
+public:
+ Chromaprint( intf_thread_t *p_intf = NULL );
+ virtual ~Chromaprint();
+ bool enqueue( input_item_t *p_item );
+ static int results_available( vlc_object_t *p_this, const char *,
+ vlc_value_t, vlc_value_t newval, void *param );
+ fingerprint_request_t * fetchResults();
+ void apply( fingerprint_request_t *, int i_id );
+ static bool isSupported( QString uri );
+
+signals:
+ void finished();
+
+private:
+ void finish() { emit finished(); }
+ intf_thread_t *p_intf;
+ fingerprinter_thread_t *p_fingerprinter;
+};
+
+#endif // CHROMAPRINT_HPP
diff --git a/modules/gui/qt4/components/info_panels.cpp b/modules/gui/qt4/components/info_panels.cpp
index 0b051d4..13e8706 100644
--- a/modules/gui/qt4/components/info_panels.cpp
+++ b/modules/gui/qt4/components/info_panels.cpp
@@ -33,6 +33,8 @@
#include "qt4.hpp"
#include "components/info_panels.hpp"
#include "components/interface_widgets.hpp"
+#include "dialogs/fingerprintdialog.hpp"
+#include "adapters/chromaprint.hpp"
#include <assert.h>
#include <vlc_url.h>
@@ -128,7 +130,15 @@ MetaPanel::MetaPanel( QWidget *parent,
/* Language on the same line */
ADD_META( VLC_META_LANGUAGE, language_text, 7, -1 ); line++;
- ADD_META( VLC_META_PUBLISHER, publisher_text, 0, 7 ); line++;
+ ADD_META( VLC_META_PUBLISHER, publisher_text, 0, 7 );
+
+ fingerprintButton = new QPushButton( qtr("&Fingerprint") );
+ fingerprintButton->setToolTip( qtr( "Find meta data using audio fingerprinting" ) );
+ fingerprintButton->setVisible( false );
+ metaLayout->addWidget( fingerprintButton, line, 7 , 3, -1 );
+ CONNECT( fingerprintButton, clicked(), this, fingerprint() );
+
+ line++;
lblURL = new QLabel;
lblURL->setOpenExternalLinks( true );
@@ -211,7 +221,8 @@ void MetaPanel::update( input_item_t *p_item )
/* URL / URI */
psz_meta = input_item_GetURI( p_item );
if( !EMPTY_STR( psz_meta ) )
- emit uriSet( qfu( psz_meta ) );
+ emit uriSet( qfu( psz_meta ) );
+ fingerprintButton->setVisible( Chromaprint::isSupported( QString( psz_meta ) ) );
free( psz_meta );
/* Other classic though */
@@ -336,11 +347,26 @@ void MetaPanel::clear()
publisher_text->clear();
encodedby_text->clear();
art_cover->clear();
+ fingerprintButton->setVisible( false );
setEditMode( false );
emit uriSet( "" );
}
+void MetaPanel::fingerprint()
+{
+ FingerprintDialog *dialog = new FingerprintDialog( this, p_intf, p_input );
+ CONNECT( dialog, metaApplied( input_item_t * ), this, fingerprintUpdate( input_item_t * ) );
+ dialog->setAttribute( Qt::WA_DeleteOnClose, true );
+ dialog->show();
+}
+
+void MetaPanel::fingerprintUpdate( input_item_t *p_item )
+{
+ update( p_item );
+ setEditMode( true );
+}
+
/**
* Second Panel - Shows the extra metadata in a tree, non editable.
**/
diff --git a/modules/gui/qt4/components/info_panels.hpp b/modules/gui/qt4/components/info_panels.hpp
index ce30edf..3f938e0 100644
--- a/modules/gui/qt4/components/info_panels.hpp
+++ b/modules/gui/qt4/components/info_panels.hpp
@@ -51,6 +51,7 @@ class QLineEdit;
class CoverArtLabel;
class QTextEdit;
class QLabel;
+class QPushButton;
class MetaPanel: public QWidget
{
@@ -87,9 +88,13 @@ private:
QLabel *lblURL;
QString currentURL;
+ QPushButton *fingerprintButton;
+
public slots:
void update( input_item_t * );
void clear();
+ void fingerprint();
+ void fingerprintUpdate( input_item_t * );
private slots:
void enterEditMode();
diff --git a/modules/gui/qt4/dialogs/fingerprintdialog.cpp b/modules/gui/qt4/dialogs/fingerprintdialog.cpp
new file mode 100644
index 0000000..23525ee
--- /dev/null
+++ b/modules/gui/qt4/dialogs/fingerprintdialog.cpp
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * fingerprintdialog.cpp: Fingerprinter Dialog
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include "fingerprintdialog.hpp"
+#include "ui/fingerprintdialog.h"
+
+#include "adapters/chromaprint.hpp"
+#include <vlc_url.h>
+
+#include <QLabel>
+#include <QListWidgetItem>
+
+FingerprintDialog::FingerprintDialog(QWidget *parent, intf_thread_t *p_intf,
+ input_item_t *p_item ) :
+ QDialog(parent),
+ ui(new Ui::FingerprintDialog), p_r( NULL )
+{
+ ui->setupUi(this);
+
+ ui->stackedWidget->setCurrentWidget( ui->wait );
+
+ ui->buttonBox->addButton( "&Close",
+ QDialogButtonBox::RejectRole );
+
+ ui->buttonsBox->addButton( "&Apply this identity to the file",
+ QDialogButtonBox::AcceptRole );
+
+ ui->buttonsBox->addButton( "&Discard all identities",
+ QDialogButtonBox::RejectRole );
+
+ CONNECT( ui->buttonsBox, accepted(), this, applyIdentity() );
+ CONNECT( ui->buttonBox, rejected(), this, close() );
+ CONNECT( ui->buttonsBox, rejected(), this, close() );
+
+ t = new Chromaprint( p_intf );
+ if ( t )
+ {
+ CONNECT( t, finished(), this, handleResults() );
+ t->enqueue( p_item );
+ }
+}
+
+void FingerprintDialog::applyIdentity()
+{
+ Q_ASSERT( p_r );
+ if ( ui->recordsList->currentIndex().isValid() )
+ t->apply( p_r, ui->recordsList->currentIndex().row() );
+ emit metaApplied( p_r->p_item );
+ close();
+}
+
+void FingerprintDialog::handleResults()
+{
+ p_r = t->fetchResults();
+
+ if ( ! p_r )
+ {
+ ui->stackedWidget->setCurrentWidget( ui->error );
+ return;
+ }
+
+ if ( vlc_array_count( & p_r->results.metas_array ) == 0 )
+ {
+ fingerprint_request_Delete( p_r );
+ ui->stackedWidget->setCurrentWidget( ui->error );
+ return;
+ }
+
+ ui->stackedWidget->setCurrentWidget( ui->results );
+
+ for ( int i=0; i< vlc_array_count( & p_r->results.metas_array ) ; i++ )
+ {
+ vlc_meta_t *p_meta =
+ (vlc_meta_t *) vlc_array_item_at_index( & p_r->results.metas_array, i );
+ QListWidgetItem *item = new QListWidgetItem();
+ ui->recordsList->addItem( item );
+ QString mb_id( vlc_meta_GetExtra( p_meta, "musicbrainz-id" ) );
+ QLabel *label = new QLabel(
+ QString( "<h3 style=\"margin: 0\"><a style=\"text-decoration:none\" href=\"%1\">%2</a></h3>"
+ "<span style=\"padding-left:20px\">%3</span>" )
+ .arg( QString( "http://mb.videolan.org/recording/%1" ).arg( mb_id ) )
+ .arg( qfu( vlc_meta_Get( p_meta, vlc_meta_Title ) ) )
+ .arg( qfu( vlc_meta_Get( p_meta, vlc_meta_Artist ) ) )
+ );
+ label->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
+ label->setOpenExternalLinks( true );
+ item->setSizeHint( label->sizeHint() );
+ ui->recordsList->setItemWidget( item, label );
+ }
+ ui->recordsList->setCurrentIndex( ui->recordsList->model()->index( 0, 0 ) );
+}
+
+FingerprintDialog::~FingerprintDialog()
+{
+ if ( t ) delete t;
+ if ( p_r ) fingerprint_request_Delete( p_r );
+ delete ui;
+}
diff --git a/modules/gui/qt4/dialogs/fingerprintdialog.hpp b/modules/gui/qt4/dialogs/fingerprintdialog.hpp
new file mode 100644
index 0000000..d4bd070
--- /dev/null
+++ b/modules/gui/qt4/dialogs/fingerprintdialog.hpp
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * fingerprintdialog.hpp: Fingerprinter Dialog
+ *****************************************************************************
+ * Copyright (C) 2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef FINGERPRINTDIALOG_HPP
+#define FINGERPRINTDIALOG_HPP
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "qt4.hpp"
+
+#include <QDialog>
+#include <vlc_interface.h>
+#include <vlc_fingerprinter.h>
+
+namespace Ui {
+class FingerprintDialog;
+}
+
+class Chromaprint;
+
+class FingerprintDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ FingerprintDialog( QWidget *parent, intf_thread_t *p_intf,
+ input_item_t *p_item );
+ ~FingerprintDialog();
+
+private:
+ Ui::FingerprintDialog *ui;
+ Chromaprint *t;
+ fingerprint_request_t *p_r;
+
+private slots:
+ void handleResults();
+ void applyIdentity();
+
+signals:
+ void metaApplied( input_item_t * );
+};
+
+#endif // FINGERPRINTDIALOG_HPP
diff --git a/modules/gui/qt4/ui/fingerprintdialog.ui b/modules/gui/qt4/ui/fingerprintdialog.ui
new file mode 100644
index 0000000..acc8269
--- /dev/null
+++ b/modules/gui/qt4/ui/fingerprintdialog.ui
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>FingerprintDialog</class>
+ <widget class="QDialog" name="FingerprintDialog">
+ <property name="windowModality">
+ <enum>Qt::WindowModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>499</width>
+ <height>257</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Audio Fingerprinting</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="results">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Select a matching identity</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="recordsList"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonsBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::NoButton</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="error">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>No fingerprint has been found</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::NoButton</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="wait">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Fingerprinting track...</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--
1.7.9
More information about the vlc-devel
mailing list