[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [amarok] HACKING/architecture: Add architecture documentation as prep for Randa.
From:       Bart Cerneels <bart.cerneels () kde ! org>
Date:       2012-09-20 5:42:13
Message-ID: 20120920054213.7F743A6094 () git ! kde ! org
[Download RAW message or body]

Git commit e3a7e42bb93d902bdb5468b166da6281b3e805e3 by Bart Cerneels.
Committed on 13/09/2012 at 17:56.
Pushed by shanachie into branch 'master'.

Add architecture documentation as prep for Randa.

A  +86   -0    HACKING/architecture/Playlists.txt

http://commits.kde.org/amarok/e3a7e42bb93d902bdb5468b166da6281b3e805e3

diff --git a/HACKING/architecture/Playlists.txt b/HACKING/architecture/Play=
lists.txt
new file mode 100644
index 0000000..0647c7a
--- /dev/null
+++ b/HACKING/architecture/Playlists.txt
@@ -0,0 +1,86 @@
+Playlist architecture
+---------------------
+note: this is about the media sources playlist, *not* The Playlist as the =
playback queue has been called for historic reasons.
+
+A playlist is an ordered list of tracks. The creation method of this list =
determines the type (or category):
+* When created by the user themselves and manually editable it's a User Pl=
aylist.
+
+* A Dynamic Playlist is generated based on some statistical rules. It's an=
 amarok specific type that also reacts to changes made in the playback queu=
e by the user.
+
+* A Smart Playlist is the result of a query of the Collections. It doesn't=
 change unless it's being re-generated at startup or at the user's request.
+
+A Radio Channel has tracks that are not or only limited determined by the =
user but rather come in as a "stream" (high level). Implementation can be a=
 single HTTP/RTSP URL like icecast or a pre-selected list of stream-able UR=
Ls such as with last.fm. The implementations can allow some control over tr=
ack selection with functionality like last.fm's love/ban or tag selection l=
ike spotify.
+
+* Podcast Channels are also playlists that are generated by parsing a podc=
ast feed (RSS or atom). They only contain tracks of the PodcastEpisode type=
. In amarok they are displayed separately from the other playlists but inte=
rnally they use the same code such as the ItemModels, PlaylistManager and t=
he synchronization support.
+
+[note] The Playlist base class currently lives in the Playlists:: namespac=
e. It is to be move to Meta::.
+
+Asynchronous Track Loading
+--------------------------
+The tracks() method will return immediately, possibly with a list of track=
s that were already in memory. A call to the tracks() method might also do =
a triggerTrackLoad() which will start the asynchronous loading of tracks in=
 the background. PlaylistObserver::trackAdded() will be called for each tra=
ck that is added additionally to the playlist. trackRemoved() can also be c=
alled when the previous tracklist is affected.
+[note] automatic loading and async depends on the implementation.
+
+PlaylistProvider
+----------------
+The PlaylistProvider base class is registered with PlaylistManager so it c=
an act as a central point to distribute playlist to other Amarok components.
+Playlist loading can also be made asynchronous in the implementations. Pla=
ylistProvider::playlistCount() can return -1 to indicate a full load is req=
uired to calculate this. After calling playlists(), which can return an emp=
ty list, playlistAdded() signals might be emitted while the asynchronous lo=
ading is going on.
+PlaylistProviders can offer the UI QActions for the provider, a specific p=
laylist or a specific track in a playlist. Playlist also has these last 2 m=
ethods which in the default implementation call the provider's implementati=
ons. It's recommended to implement playlist and track actions in the provid=
er.
+
+Playlist Synchronization
+------------------------
+It's possible to set up a link between playlists of the same category but =
from different PlaylistProviders. PlaylistManager will try to bring those p=
laylists in the same state i.e. the same tracks in the same order.
+The synchronization logic is implemented in SyncedPlaylist, a virtual clas=
s created with a factory pattern so other syncing algorithms can be applied=
 at runtime. An example where this could be used: GPodderProvider's playlis=
ts are representations of the state of data on a web-service (gpodder.net).=
 It has certain restrictions but also features that go beyond regular playl=
ist synchronization. GPodderProvider can create a SyncedPlaylist class that=
 specifically handles podcasts and keeps the limitations of the service and=
 PodcastChannels in mind.
+[note] currently podcast synchronization uses the special function Playlis=
t::syncTrackStatus() which should be replaced by the above mechanism to avo=
id implementation-at-high-level-creep.
+
+A SynchronizedPlaylist will appear to the higher layers as one playlist wh=
ich exists on multiple PlaylistProviders. In order to display the multiple =
copies to the user a QItemProxyModel is used by the UI.
+
+The synchronization algorithm uses only those functions that are also need=
ed by the regular playlist use cases. In theory Playlist implementations do=
n't need to think about synchronization. In practice synchronization will o=
nly properly work with fully functional PlaylistProvider and Playlist imple=
mentations, which are desirable anyway.
+
+PlaylistBrowserModel
+--------------------
+PlaylistBrowserModel is the base class for ItemModels used to display the =
various playlist types. Although all playlist can be displayed using this b=
ase class all categories have their own specialized implementation to imple=
ment setData(), dropMimeData() and category specific actions (ex. PodcastMo=
del::refreshPodcasts()). Not that these are usually convenience version of =
Provider actions.
+PlaylistBrowser model requests playlist for it's category from PlaylistMan=
ager who gathers them from the providers and group Synchronized playlists t=
ogether in a SyncedPlaylist. PlaylistBrowserModel is a tree with playlist o=
n the first level and tracks as it's children. In order to have playlists g=
rouped by origin (i.e. PlaylistProvider) the PlaylistByProvider proxy.
+
+Playlist Tracking by PlaybackQueue
+----------------------------------
+The PlaybackQueue can be made to track a single playlist's state. In gener=
al this just means that all current tracks of the playlist are appended to =
the queue and that it will act on trackAdded() signals. However, because th=
e playback queue only has the upcoming tracks changes to tracks that have a=
lready been played are not possible. The distinction between a playlist and=
 the queue has to be clear to the user.
+Using playlist tracking it's possible to implement all modes of the old Pl=
aylist by creating categories implementing the behavior of the modes.
+
+User Playlists
+--------------
+File based: XSPFPlaylist, M3UPlaylist, PLSPlaylist
+Database based: SqlPlaylist
+
+These playlists will load tracks using MetaProxy::Track which will start a=
 worker thread to get a real track object using CollectionManager::trackFor=
Url(). It depends on the implementation and contents of the file which URL =
is used to resolve the track.
+M3U and PLS by specification require their contents to be playable URLs. F=
or most collections the playable URL and uidUrl won't match, so these track=
s won't be playable until their "real" track is resolved.
+XSPF does support storing of the uidUrl (identifier tag). Amarok always wr=
ites track's uidUrl to XSPF. The current playback queue state is also saved=
 with XSPF to a dedicated file ($KDEHOME/share/apps/amarok/current.xspf).
+The playlist implementation fills the proxy tracks with any tag informatio=
n it has stored. This way a recently loaded playlist has usable content whi=
le loading tracks is done asynchronously.
+If the playback queue is restored with invalid (empty) tracks, XSPFPlaylis=
t, MetaProxy and CollectionManager::trackForUrl() are to be investigated.
+
+Dynamic Playlists
+-----------------
+Using a custom UI the settings for selecting tracks are configured. Te Dyn=
amic Playlist will select tracks and make them available from the tracks() =
method. These tracks can be displayed to the user as a preview of the setti=
ngs but are mainly used in the playback queue.
+Using the Selector/Bias system other components and plugins can add track =
selection conditions or statistical bias options to the dynamic playlist ge=
nerator.
+[note] current implementation does not derive from Playlists::Playlist nor=
 does it use a PlaylistProvider. It's a mode of the playback queue, not a l=
oadable playlist.
+
+Smart Playlists
+---------------
+The basis of a Smart Playlist is a QueryMaker query and some additional li=
miters such as track count and total file size (useful to fill a media play=
er). The list of tracks is not kept between sessions so a smart playlist is=
 generated when first accessed. To avoid unneeded recalculation an active s=
mart playlist will only be regenerated when the user requests it or when th=
e synchronization of a playlist requires an up-to-date list.
+
+Podcast Channels
+----------------
+This type is used for both the local (SQL based) PodcastProvider, some med=
ia device implementations and the gpodder web service. In the local collect=
ion the utility class PodcastReader is used to parse a podcast feed and upd=
ate the PodcastChannel implementation. The base classes of PodcastMeta.cpp =
are used as intermediary data storage for new Channels and Episodes that ha=
ve not been saved in the PodcastProvider yet.
+
+Radio Channels
+--------------
+The most common form of a radio channel is a HTTP stream. This implementat=
ion listens to signals from EngineController/PlaybackController/Phonon whil=
e playing the stream and determines when a metadata change represents a rea=
l track change. It will then push append the a new track with that metadata=
 but the same url. This will not cause a real track change but rather a tra=
nsition in the PlaybackController to the new playing track. It's a seamless=
 progression in the PlaybackQueue as well.
+
+Services like last.fm and spotify also provider Radio Channels but it's im=
plementation in possible user interaction is implementation specific.
+
+Random/Shuffle Playlist
+-----------------------
+This is a very simple randomizing playlist that takes the current play que=
ue and shuffles the upcoming tracks at the start of a playing track. This w=
ay the user can seen the next upcoming track already and change or remove t=
hem if desired. This playlist will respect the manual changes made to the p=
layback order and not shuffle any of the tracks queued by the user.
+The shuffling of tracks should be a visual animation to make it clear what=
 is happening and be somewhat pleasing to watch.
+
+Old Playlist Queue Manager Behavior
+-----------------------------------
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic