Commit 1e80fd26 authored by Francois Cartegnie's avatar Francois Cartegnie

Qt: add fingerprinting ui

parent 0248a7fc
......@@ -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/info_widgets.moc.cpp \
......@@ -98,6 +100,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 \
......@@ -282,6 +285,7 @@ SOURCES_qt4 = qt4.cpp \
extensions_manager.cpp \
recents.cpp \
adapters/seekpoints.cpp \
adapters/chromaprint.cpp \
variables.cpp \
dialogs/playlist.cpp \
dialogs/bookmarks.cpp \
......@@ -305,6 +309,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/info_widgets.cpp \
......@@ -359,6 +364,7 @@ noinst_HEADERS = \
extensions_manager.hpp \
recents.hpp \
adapters/seekpoints.hpp \
adapters/chromaprint.hpp \
variables.hpp \
dialogs/playlist.hpp \
dialogs/bookmarks.hpp \
......@@ -382,6 +388,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/info_widgets.hpp \
......@@ -450,4 +457,5 @@ EXTRA_DIST += \
ui/update.ui \
ui/sout.ui \
ui/vlm.ui \
ui/fingerprintdialog.ui \
$(DEPS_res)
/*****************************************************************************
* 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 );
}
/*****************************************************************************
* 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
......@@ -34,6 +34,8 @@
#include "components/info_panels.hpp"
#include "components/interface_widgets.hpp"
#include "info_widgets.hpp"
#include "dialogs/fingerprintdialog.hpp"
#include "adapters/chromaprint.hpp"
#include <assert.h>
#include <vlc_url.h>
......@@ -129,7 +131,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 );
......@@ -212,7 +222,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 */
......@@ -337,11 +348,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.
**/
......
......@@ -52,6 +52,7 @@ class CoverArtLabel;
class QTextEdit;
class QLabel;
class VLCStatsView;
class QPushButton;
class MetaPanel: public QWidget
{
......@@ -88,9 +89,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();
......
/*****************************************************************************
* 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 );
p_r = NULL;
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;
}
/*****************************************************************************
* 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
<?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>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment