mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-24 08:34:08 +00:00
9aa3c44d4e
* add config and GUI support for internal player back end switching; * make FFmpeg player disabling option consistent with other similar qmake options by using CONFIG; * add a new qmake option that disables Qt Multimedia player. This is useful for GNU/Linux distributions where Qt WebKit and Qt Multimedia packages depend on different GStreamer versions and don't work correctly when combined in one application. The existing FFmpeg+libao internal player back end has a relatively low-level implementation, which is difficult to understand and improve. There are at least 3 open internal player issues: 1) many GNU/Linux users have to edit their libao configuration file to make Goldendict's internal player work (issue #412); 2) libao's pulseaudio plugin does not support 32-bit audio, which means that many MediaWiki pronunciations don't work with the most popular GNU/Linux audio driver (issue #949); 3) Ffmpeg::DecoderContext uses deprecated FFmpeg APIs, which causes compiler warnings and means that this internal player back end may not compile with a future FFmpeg library version (issue #978). The Qt Multimedia back end implementation uses the highest-level Qt audio API and is very simple. This new back end works flawlessly on my GNU/Linux machine. I'm not making it the default back end because I don't know how well it will work on other platforms with different configurations.
85 lines
2.6 KiB
C++
85 lines
2.6 KiB
C++
/* This file is (c) 2018 Igor Kushnir <igorkuo@gmail.com>
|
|
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
|
|
|
#include <QScopedPointer>
|
|
#include <QObject>
|
|
#include "audioplayerfactory.hh"
|
|
#include "ffmpegaudioplayer.hh"
|
|
#include "multimediaaudioplayer.hh"
|
|
#include "externalaudioplayer.hh"
|
|
#include "gddebug.hh"
|
|
|
|
AudioPlayerFactory::AudioPlayerFactory( Config::Preferences const & p ) :
|
|
useInternalPlayer( p.useInternalPlayer ),
|
|
internalPlayerBackend( p.internalPlayerBackend ),
|
|
audioPlaybackProgram( p.audioPlaybackProgram )
|
|
{
|
|
reset();
|
|
}
|
|
|
|
void AudioPlayerFactory::setPreferences( Config::Preferences const & p )
|
|
{
|
|
if( p.useInternalPlayer != useInternalPlayer )
|
|
{
|
|
useInternalPlayer = p.useInternalPlayer;
|
|
internalPlayerBackend = p.internalPlayerBackend;
|
|
audioPlaybackProgram = p.audioPlaybackProgram;
|
|
reset();
|
|
}
|
|
else
|
|
if( useInternalPlayer && p.internalPlayerBackend != internalPlayerBackend )
|
|
{
|
|
internalPlayerBackend = p.internalPlayerBackend;
|
|
reset();
|
|
}
|
|
else
|
|
if( !useInternalPlayer && p.audioPlaybackProgram != audioPlaybackProgram )
|
|
{
|
|
audioPlaybackProgram = p.audioPlaybackProgram;
|
|
ExternalAudioPlayer * const externalPlayer =
|
|
qobject_cast< ExternalAudioPlayer * >( playerPtr.data() );
|
|
if( externalPlayer )
|
|
setAudioPlaybackProgram( *externalPlayer );
|
|
else
|
|
gdWarning( "External player was expected, but it does not exist.\n" );
|
|
}
|
|
}
|
|
|
|
void AudioPlayerFactory::reset()
|
|
{
|
|
if( useInternalPlayer )
|
|
{
|
|
// qobject_cast checks below account for the case when an unsupported backend
|
|
// is stored in config. After this backend is replaced with the default one
|
|
// upon preferences saving, the code below does not reset playerPtr with
|
|
// another object of the same type.
|
|
|
|
#ifdef MAKE_FFMPEG_PLAYER
|
|
Q_ASSERT( Config::InternalPlayerBackend::defaultBackend().isFfmpeg()
|
|
&& "Adjust the code below after changing the default backend." );
|
|
|
|
if( !internalPlayerBackend.isQtmultimedia() )
|
|
{
|
|
if( qobject_cast< Ffmpeg::AudioPlayer * >( playerPtr.data() ) == 0 )
|
|
playerPtr.reset( new Ffmpeg::AudioPlayer );
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
#ifdef MAKE_QTMULTIMEDIA_PLAYER
|
|
if( qobject_cast< MultimediaAudioPlayer * >( playerPtr.data() ) == 0 )
|
|
playerPtr.reset( new MultimediaAudioPlayer );
|
|
return;
|
|
#endif
|
|
}
|
|
|
|
QScopedPointer< ExternalAudioPlayer > externalPlayer( new ExternalAudioPlayer );
|
|
setAudioPlaybackProgram( *externalPlayer );
|
|
playerPtr.reset( externalPlayer.take() );
|
|
}
|
|
|
|
void AudioPlayerFactory::setAudioPlaybackProgram( ExternalAudioPlayer & externalPlayer )
|
|
{
|
|
externalPlayer.setPlayerCommandLine( audioPlaybackProgram.trimmed() );
|
|
}
|