The playback queue is now kept in sync with the playback queue of the
remote jellyfin instance the manager is controlling.
Some additional guards were added in place in the shuffle and playlist
algorithm, since the situation can occur where the now playing index
falls outside of the playing playlist. This happens because when the
an playlist update is received, we need to do another HTTP request
before we know which items are in the queue, while the now playing index
has been updated.
This is a not-optimal way to fix that, but it works well enough for now
and a better solution can be implemented later. (Hello, person in the
future reading the git blame output!)
The PlaybackManager was a giant class that handled UI bindings, fetching
stream URLS, playback logic.
It now has been split up into:
- ViewModel::PlaybackManager, which handles UI interfacing and allowing
to swap out the Model::Playback implementation on the fly.
- Model::PlaybackManager, which is an interface for what a
PlaybackManager must do, handling queues/playlists, and controlling a
player.
- Model::LocalPlaybackManager, which is an Model::PlaybackManager
implementation for playing back Jellyfin media within the application.
- Model::PlaybackReporter, which reports the current playback state to
the Jellyfin server, for keeping track of played items.
- Model::Player, which handles playing back media from an URL and
the usual play/pause et cetera.
In a future commit, this would allow for introducing a
Model::RemoteJellyfinPlaybackManager, to control other Jellyfin
instances.
It previously modified the limit for some template instances. That
obviously does not work.
Additionally, setRequestStartIndex and setRequestLimit have been
implemented for GetNextUpParams.
Fixes #19
On startup, the DeviceProfile would not be serialized properly to a false
assumption that QJsonValue.toString() returns the JSON representation of
the given value. This now has been fixed by creating a QJsonDocument
converting it to a string.
There were some constructors in the DTOs which allowed construction of
DTO which weren't fully initialized. These constructors have been made
private, as they are still used in the 'fromJson' methods. Additionally,
a constructor with all required parameters to fully initialize the
class has been added.
Additionally, the Loader class has been modified, since it no longer can
assume it is able to default construct the parameter type. The parameter
is now stored as an optional.
Closes #15
The following bugs should have been fixed:
* The PlaybackManager no longer starts playing again after
PlaybackManager.stop() has been called.
* The PlaybackManager will no longer get into an invalid state when
next() is called many times fast.
* The PlaybackManager now exposes its error information when the
PlaybackUrl could not be fetched.
* The PlaybackManager will keep a playbackState of Playing as long
as it is not stopped and while in a playlist. Previously, it would
stop and start everytime the next item got loaded.
* Show the now playing cover when playing an item, otherwise show the
collection cover.
* ItemModelLoaders now correctly expose list properties of non-built-in
Qt objects
* toString is now implemented for lists, fixing some query
construction code.
* PlaybackManager now clears the playlist when playing a single item to
prevent weird behaviour.
* The covers are slightly updated.
Due to some errors within DeviceProfile and how nullables were
serialized, an invalid request was made and the
/Sessions/Capabilities/Full would give an 400 response back.
Besides that, ApiClient would generate a DeviceProfile before all
properties from QML were read. This has been fixed by implementing
QQmlParserStatus and only generating the device profile after all
properties are set.
* PlaybackManager has been updated to workaround limitiations in
QtMultimedia
* PlaybackManager now sends the DeviceProfile to the server when
determining the playback url. This makes the Jellyfin server send
information back about transcoding.
* The DeviceProfile type has been changed from an QJsonObject into the
DTO generated by the OpenAPI descripton.
* A settings page has been added on SailfishOS that allows the user to
configure the PlaybackManager to their whishes.
* The DebugInfo page on SailfishOS now persists its settings (closes #8)
ApiClient was refractored to use PIMPL. This is mainly done to reduce
compile times whenever the implementation of ApiClient itself changes,
since a lot of files include it.
The loaders have gained support for body parameters, this was somehow
omitted before.
This settingsframework uses mlite5 on SailfishOS and other platforms
with the mlite library present, because I believe DConf is neat. For
platforms that do not have DConf and mlite present, it falls back to a
quickly put together implementation that uses QSettings as a backend.
Implementing an settings item is simply done by subclassing the
Jellyfin::QObjectSettingsWrapper.
Besides MPRIS support, this also adds support for hasPrevious() and
hasNext() in several parts to determine whether the
player/playlist/shuffler has a previous or next item.
* Properly keep track of the current offset and total recourd count in
models.
* Catch exceptions and store them in errorString properties wherever
applicable in loaders.
THe idea behind the switching was to provide gapless playback, but it
made the code too complicated and to intertwined with QtMultiMedia.
I might attempt to implement it later, but I probably will put the code
in a separate class to make it easier to swap the QtMultiMedia
implementation with a multimedia implementation for a player with better
support for gappless playback.
Loading logic should be extracted from the model, to make
loading the data from other sources, such as a local database for
synchronised items, possible.