1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-09-06 20:20:41 +02:00

Compare commits

...

21 Commits

Author SHA1 Message Date
Dominik Schmidt
93bc06615d Fix Zeroconf with recent Qt5 2016-02-23 12:21:44 +01:00
Christian Muehlhaeuser
3bcf854a4f Updated ChangeLog. 2016-02-22 22:32:54 +01:00
Christian Muehlhaeuser
61a15cafac Speed up drag & drop moves over sidebar. 2016-02-22 22:31:34 +01:00
Christian Muehlhaeuser
2d141ccb5e Style fix in SoureTreeView. 2016-02-22 22:31:34 +01:00
Christian Muehlhaeuser
4c023b7d2f Style fix in XspfUpdater. 2016-02-22 22:31:34 +01:00
Christian Muehlhaeuser
ceb5dc6aa4 Style fix in main.cpp. 2016-02-22 22:31:34 +01:00
Christian Muehlhaeuser
13fa9c7c53 Merge pull request #448 from tomahawk-player/vlc-volume-fix
Fix #441: Handle VLC volume and muted state properly
2016-02-22 22:31:04 +01:00
Dominik Schmidt
4c946b304c Fix #451: Can't select crash ID in the crash report UI 2016-02-22 22:02:54 +01:00
Dominik Schmidt
5075c9ddbf Fix compilation with libvlc < 2.2.2 2016-02-22 16:10:47 +01:00
Dominik Schmidt
8b3a916aa6 Update VLC for Windows 2016-02-22 16:10:47 +01:00
Dominik Schmidt
cd412add8f Persist muted state accross restarts 2016-02-22 16:10:47 +01:00
Dominik Schmidt
68851843f5 Unmute AudioOutput on start up 2016-02-22 16:10:47 +01:00
Dominik Schmidt
af8811af30 Fix volume on external (un)muting 2016-02-22 16:10:47 +01:00
Dominik Schmidt
fa38ed5e91 Sync muted state as well 2016-02-22 16:10:47 +01:00
Dominik Schmidt
b7ff630808 Sync audio volume if it's changed externally in vlc 2016-02-22 16:10:47 +01:00
Dominik Schmidt
196256d77b Fix startup volume for good 2016-02-22 16:10:47 +01:00
Dominik Schmidt
79cd3a7f0a Revert "Fix startup volume for good"
This reverts commit 86cd7c1be0.
2016-02-22 16:10:20 +01:00
Dominik Schmidt
f0f45673b1 Fix #419: Fix HLS streams on Windows (e.g. Amazon Prime Music) 2016-02-22 16:09:11 +01:00
Dominik Schmidt
86cd7c1be0 Fix startup volume for good 2016-02-22 00:10:17 +01:00
Dominik Schmidt
f74c6ae429 Fix #446: Fix compilation with Qt4 2016-02-21 18:06:14 +01:00
Dominik Schmidt
015b24479c Fix crash in context menu 2016-02-21 11:12:17 +01:00
19 changed files with 175 additions and 34 deletions

View File

@@ -1,6 +1,7 @@
Version 0.9.0:
* Resolved various playback issues by switching to a new audio engine.
* Fixed collection sorting.
* Fixed volume/mute state not being reset correctly on startup.
Version 0.8.4:
* Fixed drag & drop issues on sidebar.

View File

@@ -9,19 +9,20 @@ fi
rm -rvf vlc/
VLC_TARBALL="vlc-2.2.3.tar.bz2"
echo "Download phonon archive..."
# wget -c "http://downloads.sourceforge.net/project/vlc/1.1.9/win32/vlc-1.1.9-win32.7z?r=http%3A%2F%2Fwww.videolan.org%2Fvlc%2Fdownload-windows.html&ts=1306272584&use_mirror=leaseweb"
# wget -c "http://download.tomahawk-player.org/tomahawk-vlc-0.1.zip"
# wget -c http://people.videolan.org/~jb/phonon/phonon-vlc-last.7z
# wget -c http://people.videolan.org/~jb/phonon/phonon_phonon-vlc_20111128.7z
wget -c http://download.tomahawk-player.org/test/vlc.tar.bz2
wget -c "http://download.tomahawk-player.org/test/$VLC_TARBALL"
echo "Extract binary..."
# 7z x phonon*.7z
# mv -v vlc-*/ vlc/
# unzip tomahawk-vlc-0.1.zip
tar xvjf vlc.tar.bz2
tar xvjf "$VLC_TARBALL"
# echo "Download phonon_vlc_no_video.dll..."
# wget -c http://people.videolan.org/~jb/phonon/phonon_vlc_no_video.dll
@@ -72,7 +73,9 @@ rm -rvf \
**/libi420* \
**/libi422* \
mux/ \
stream_filter/ \
stream_filter/*dash* \
stream_filter/*smooth* \
stream_filter/*record* \
**/libtheora_plugin* \
**/liblibbluray_plugin* \
**/libdtv_plugin* \

BIN
data/sounds/silence.ogg Normal file

Binary file not shown.

View File

@@ -170,5 +170,6 @@
<file>data/images/downloadbutton.svg</file>
<file>data/images/nav-back.svg</file>
<file>data/images/nav-forward.svg</file>
<file>data/sounds/silence.ogg</file>
</qresource>
</RCC>

View File

@@ -223,8 +223,10 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
m_sigmap->setMapping( addAction( tr( "&Copy Track Link" ) ), ActionCopyLink );
}
if ( m_supportedActions & ActionOpenFileManager && queries.length() == 1 &&
if ( m_supportedActions & ActionOpenFileManager &&
queries.length() == 1 &&
queries.first()->numResults() &&
queries.first()->results().first()->resolvedByCollection() &&
queries.first()->results().first()->resolvedByCollection()->isLocal() )
{
m_sigmap->setMapping( addAction( ImageRegistry::instance()->icon( RESPATH "images/folder.svg" ),

View File

@@ -929,6 +929,20 @@ TomahawkSettings::setVolume( unsigned int volume )
}
bool
TomahawkSettings::muted() const
{
return value( "audio/muted" ).toBool();
}
void
TomahawkSettings::setMuted( bool muted )
{
setValue( "audio/muted", muted );
}
QString
TomahawkSettings::proxyHost() const
{

View File

@@ -107,6 +107,9 @@ public:
unsigned int volume() const;
void setVolume( unsigned int volume );
bool muted() const;
void setMuted( bool muted );
/// Playlist stuff
QByteArray playlistColumnSizes( const QString& playlistid ) const;
void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state );

View File

@@ -167,10 +167,17 @@ AudioEngine::AudioEngine()
d->audioOutput = new AudioOutput( this );
connect( d->audioOutput, SIGNAL( initialized() ), this, SIGNAL( initialized() ) );
connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d_func(), SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) );
connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) );
connect( d->audioOutput, SIGNAL( positionChanged( float ) ), SLOT( onPositionChanged( float ) ) );
connect( d->audioOutput, SIGNAL( volumeChanged( qreal ) ), SLOT( onVolumeChanged( qreal ) ) );
connect( d->audioOutput, SIGNAL( mutedChanged( bool ) ), SIGNAL( mutedChanged( bool ) ) );
if ( TomahawkSettings::instance()->muted() )
{
mute();
}
setVolume( TomahawkSettings::instance()->volume() );
qRegisterMetaType< AudioErrorCode >("AudioErrorCode");
@@ -183,6 +190,7 @@ AudioEngine::~AudioEngine()
tDebug() << Q_FUNC_INFO;
TomahawkSettings::instance()->setVolume( volume() );
TomahawkSettings::instance()->setMuted( isMuted() );
delete d_ptr;
}
@@ -289,8 +297,11 @@ AudioEngine::stop( AudioErrorCode errorCode )
if ( d->waitingOnNewTrack )
sendWaitingNotification();
Tomahawk::InfoSystem::InfoPushData pushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant(), Tomahawk::InfoSystem::PushNoFlag );
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
if ( d->audioOutput->isInitialized() )
{
Tomahawk::InfoSystem::InfoPushData pushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant(), Tomahawk::InfoSystem::PushNoFlag );
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
}
}
@@ -566,6 +577,12 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
Q_D( AudioEngine );
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() );
if ( !d->audioOutput->isInitialized() )
{
return;
}
if ( !result )
{
stop();

View File

@@ -149,6 +149,8 @@ public slots:
void setShuffled( bool enabled );
signals:
void initialized();
void loading( const Tomahawk::result_ptr track );
void started( const Tomahawk::result_ptr track );
void finished( const Tomahawk::result_ptr track );

View File

@@ -25,11 +25,13 @@
#include "audio/MediaStream.h"
#include "utils/Logger.h"
#include "utils/TomahawkUtils.h"
#include <QApplication>
#include <QVarLengthArray>
#include <QFile>
#include <QDir>
#include <QTimer>
#include <vlc/libvlc.h>
#include <vlc/libvlc_media.h>
@@ -58,6 +60,7 @@ AudioOutput::AudioOutput( QObject* parent )
, m_currentTime( 0 )
, m_totalTime( 0 )
, m_justSeeked( false )
, m_initialized( false )
, dspPluginCallback( nullptr )
, m_vlcInstance( nullptr )
, m_vlcPlayer( nullptr )
@@ -120,6 +123,11 @@ AudioOutput::AudioOutput( QObject* parent )
libvlc_MediaPlayerTitleChanged,
libvlc_MediaPlayerSnapshotTaken,
//libvlc_MediaPlayerLengthChanged,
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
libvlc_MediaPlayerAudioVolume,
libvlc_MediaPlayerMuted,
libvlc_MediaPlayerUnmuted,
#endif
libvlc_MediaPlayerVout
};
const int eventCount = sizeof(events) / sizeof( *events );
@@ -128,8 +136,24 @@ AudioOutput::AudioOutput( QObject* parent )
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
}
m_muted = isMuted();
tDebug() << Q_FUNC_INFO << "Init OK";
// HACK: play silent ogg file and set volume on that to workaround vlc not allowing to set volume before a file is played
m_silenceFile.setFileName( RESPATH "sounds/silence.ogg" );
Q_ASSERT( m_silenceFile.exists() );
Q_ASSERT( m_silenceFile.open( QIODevice::ReadOnly ) );
setCurrentSource( new MediaStream( &m_silenceFile, true ) );
libvlc_media_player_play( m_vlcPlayer );
#if QT_VERSION >= QT_VERSION_CHECK(5,4,0)
// if the silence file did not play for 15 secs, we pretend the AudioOutput is initialized, to allow proper error reporting
QTimer::singleShot( 15000, [&]()
{
if ( !m_initialized ) {
m_initialized = true;
emit initialized();
}
} );
#endif
}
@@ -155,6 +179,28 @@ AudioOutput::~AudioOutput()
}
void
AudioOutput::onInitVlcEvent( const libvlc_event_t* event )
{
switch ( event->type )
{
case libvlc_MediaPlayerTimeChanged:
setVolume( volume() );
setMuted( isMuted() );
m_initialized = true;
m_silenceFile.close();
tDebug() << Q_FUNC_INFO << "Init OK";
emit initialized();
break;
default:
break;
}
}
void
AudioOutput::setAutoDelete( bool ad )
{
@@ -303,6 +349,13 @@ AudioOutput::setCurrentSource( MediaStream* stream )
}
bool
AudioOutput::isInitialized() const
{
return m_initialized;
}
AudioOutput::AudioState
AudioOutput::state() const
{
@@ -457,7 +510,7 @@ AudioOutput::isSeekable() const
bool
AudioOutput::isMuted() const
{
return libvlc_audio_get_mute( m_vlcPlayer );
return m_muted;
}
@@ -530,6 +583,20 @@ AudioOutput::onVlcEvent( const libvlc_event_t* event )
// Don't call stop() here - it will deadlock libvlc
setState( Error );
break;
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
case libvlc_MediaPlayerAudioVolume:
m_volume = event->u.media_player_audio_volume.volume;
emit volumeChanged( volume() );
break;
case libvlc_MediaPlayerMuted:
m_muted = true;
emit mutedChanged( true );
break;
case libvlc_MediaPlayerUnmuted:
m_muted = false;
emit mutedChanged( false );
break;
#endif
case libvlc_MediaPlayerNothingSpecial:
case libvlc_MediaPlayerOpening:
case libvlc_MediaPlayerBuffering:
@@ -555,7 +622,14 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque )
AudioOutput* that = reinterpret_cast < AudioOutput * > ( opaque );
Q_ASSERT( that );
that->onVlcEvent( event );
if ( !that->isInitialized() )
{
that->onInitVlcEvent( event );
}
else
{
that->onVlcEvent( event );
}
}

View File

@@ -25,6 +25,8 @@
#include "DllMacro.h"
#include "Typedefs.h"
#include <QFile>
#include <functional>
struct libvlc_instance_t;
@@ -44,6 +46,7 @@ public:
explicit AudioOutput( QObject* parent = nullptr );
~AudioOutput();
bool isInitialized() const;
AudioState state() const;
void setCurrentSource( const QUrl& stream );
@@ -72,11 +75,16 @@ public:
public slots:
signals:
void initialized();
void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState );
void tick( qint64 );
void positionChanged( float );
void volumeChanged( qreal volume );
void mutedChanged( bool );
private:
void onInitVlcEvent( const libvlc_event_t* event );
void setState( AudioState state );
void setCurrentTime( qint64 time );
void setCurrentPosition( float position );
@@ -99,6 +107,9 @@ private:
qint64 m_totalTime;
bool m_justSeeked;
bool m_initialized;
QFile m_silenceFile;
std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback;
libvlc_instance_t* m_vlcInstance;

View File

@@ -41,12 +41,16 @@ MediaStream::MediaStream( const QUrl &url )
}
MediaStream::MediaStream( QIODevice* device )
MediaStream::MediaStream( QIODevice* device, bool bufferingFinished )
: QObject( nullptr )
, m_type( IODevice )
, m_ioDevice ( device )
, m_bufferingFinished( bufferingFinished )
{
QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) );
if ( !bufferingFinished )
{
QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) );
}
}

View File

@@ -42,7 +42,7 @@ public:
MediaStream( QObject* parent = nullptr );
explicit MediaStream( const QUrl &url );
explicit MediaStream( QIODevice* device );
explicit MediaStream( QIODevice* device, bool bufferingFinished = false );
virtual ~MediaStream();
MediaType type() const;

View File

@@ -1371,7 +1371,10 @@ Servent::isIPWhitelisted( QHostAddress ip )
}
}
#if QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
// Did something change in Qt 5? In Qt 5.5 Zeroconf does not work with this code ifdef'ed out
// @xhochy can you shed some light on this?
// #if QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
// Qt4 cannot cope correctly with IPv4 addresses mapped into the IPv6
// address space
if ( ip.protocol() == QAbstractSocket::IPv6Protocol )
@@ -1397,7 +1400,7 @@ Servent::isIPWhitelisted( QHostAddress ip )
return isIPWhitelisted( addr );
}
}
#endif
// #endif
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "failure";
return false;

View File

@@ -156,6 +156,7 @@ XspfUpdater::setAutoUpdate( bool autoUpdate )
emit changed();
}
void
XspfUpdater::setInterval( int intervalMsecs )
{

View File

@@ -412,7 +412,7 @@ SettingsDialog::onCustomContextMenu( const QPoint& point )
void
SettingsDialog::onShowDebuggerForSelectedAccount()
{
ResolverAccount* account = m_accountProxy->data( m_accountsWidgetUi->accountsView->currentIndex(), AccountModel::AccountData ).value< ResolverAccount* >();
ResolverAccount* account = qobject_cast< ResolverAccount* >( m_accountProxy->data( m_accountsWidgetUi->accountsView->currentIndex(), AccountModel::AccountData ).value< Tomahawk::Accounts::Account* >() );
Tomahawk::JSResolver* jsResolver = qobject_cast< Tomahawk::JSResolver* >( account->resolver() );
jsResolver->scriptAccount()->showDebugger();
}

View File

@@ -167,7 +167,7 @@ main( int argc, char *argv[] )
QCA::Initializer init;
Q_UNUSED( init )
#ifdef Q_OS_MAC
#ifdef Q_OS_MAC
// Do Mac specific startup to get media keys working.
// This must go before QApplication initialisation.
Tomahawk::macMain();
@@ -253,11 +253,11 @@ main( int argc, char *argv[] )
#ifdef Q_OS_MAC
#ifdef Q_OS_MAC64
#ifdef Q_OS_MAC64
static pascal OSErr appleEventHandler( const AppleEvent* e, AppleEvent*, void* )
#elif defined Q_OS_MAC32
#elif defined Q_OS_MAC32
static pascal OSErr appleEventHandler( const AppleEvent* e, AppleEvent*, long )
#endif //Q_OS_MAC64/32
#endif //Q_OS_MAC64/32
{
OSType id = typeWildCard;
AEGetAttributePtr( e, keyEventIDAttr, typeType, 0, &id, sizeof( id ), 0 );

View File

@@ -447,7 +447,6 @@ SourceTreeView::deletePlaylist( const QModelIndex& idxIn )
m_popupDialog.data()->move( rightCenter.x() - m_popupDialog.data()->offset(), rightCenter.y() - m_popupDialog.data()->sizeHint().height() / 2. );
m_popupDialog.data()->show();
}
@@ -797,20 +796,21 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
{
QTreeView::dragMoveEvent( event );
bool accept = false;
if ( DropJob::isDropType( DropJob::Playlist, event->mimeData() ) )
{
// Don't highlight the drop for a playlist, as it won't get added to the playlist but created generally
event->setDropAction( Qt::CopyAction );
event->accept();
accept = true;
}
else if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Track, DropJob::Append ) )
{
bool accept = false;
setDirtyRegion( m_dropRect );
const QPoint pos = event->pos();
const QModelIndex index = indexAt( pos );
dataChanged( m_dropIndex, m_dropIndex );
m_dropIndex = QPersistentModelIndex( index );
if ( index != m_dropIndex )
dataChanged( m_dropIndex, m_dropIndex );
if ( index.isValid() )
{
@@ -829,7 +829,8 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
case SourcesModel::CategoryAdd:
case SourcesModel::Source: //drop to send tracks to peers
m_delegate->hovered( index, event->mimeData() );
dataChanged( index, index );
if ( index != m_dropIndex )
dataChanged( index, index );
break;
default:
@@ -845,24 +846,28 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
m_dropRect = QRect();
}
if ( accept || DropJob::isDropType( DropJob::Playlist, event->mimeData() ) )
if ( accept )
{
// Playlists are accepted always since they can be dropped anywhere
//tDebug() << Q_FUNC_INFO << "Accepting";
event->setDropAction( Qt::CopyAction );
event->accept();
}
else
{
// tDebug() << Q_FUNC_INFO << "Ignoring";
event->ignore();
}
m_dropIndex = QPersistentModelIndex( index );
}
else if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Playlist | DropJob::Artist | DropJob::Album, DropJob::Create ) )
{
event->setDropAction( Qt::CopyAction );
accept = true;
}
if ( accept )
{
event->accept();
}
else
{
event->ignore();
}
setDirtyRegion( m_dropRect );
}