I have verified in numerous desktop environments and window managers
that the workaround does not work with Qt5.
Let us disable it in Qt5 builds to prevent potential issues
and eliminate the small performance overhead.
* 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.
This change substantially reduces audio player configuration code
complexity. The single remaining bool option - useInternalPlayer -
is enough for the binary audio player implementation choice.
Removing the useExternalPlayer option doesn't change the application GUI
behavior except for minor differences in one or two corner cases, which
could be classified as bugs fixed by this commit. For example, before
this commit, if the configuration file contained the following lines
<useExternalPlayer>0</useExternalPlayer>
<useInternalPlayer>0</useInternalPlayer>
an external player would be actually used for audio playback, but
neither of the two audio radio buttons would be checked in
Preferences GUI, and audioPlaybackProgram line edit would be disabled.
Whereas, after this commit, an external player is still used for
audio playback, but useExternalPlayer radio button is checked
in Preferences GUI, and the audioPlaybackProgram line edit is enabled.
External and internal audio players work similarly now. Fixes #950.
* inherit a new ExternalAudioPlayer class from AudioPlayerInterface;
* use an existing ExternalViewer class to implement ExternalAudioPlayer;
* take (const char *, int) instead of std::vector<char> in
ExternalViewer constructor to fit into AudioPlayerInterface;
* extend ExternalViewer API to let ExternalAudioPlayer stop superseded
audio player processes;
* make AudioPlayerInterface::play() return an error message string to
allow reporting immediate failures from derived classes;
* Document AudioPlayerInterface API;
* Document AudioPlayerFactory::player();
* use the common audio interface exclusively in ArticleView.
* add a new interface class AudioPlayerInterface;
* inherit a new proxy class Ffmpeg::AudioPlayer from it;
* partially switch ArlticleView to using the interface;
* expose MainWindow's AudioPlayerInterface instance to all ArticleView
instances;
* add a new AudioPlayerFactory class responsible for creating instances
of concrete classes derived from AudioPlayerInterface depending on
relevant Config::Preferences values;
* increase minimum supported Qt version from 4.5 to 4.6 in README
in order to use QScopedPointer introduced in Qt 4.6.
The result of a downcast to a wrong dynamic type is undefined according
to the C++ standard.
Wrong casts were detected at goldendict start by GCC's
-fsanitize=undefined option. This commit fixes #974.