Trigger playback ended on:
- stream changed
- EOS
- stop via stream changed events
Old behavior was to manually trigger on:
- next
- prev
- play with other track and old state != STOPPED
- stop
When about to finish gets called we are running in some GStreamer thread. Our
audio code then calls the shim core callback which is responsible for
transferring our execution to the core actor thread and waiting for the
response. From this point we do normal actor calls to the backend(s) which in
turn call into the audio actor. Since the initial audio code that was called is
outside the actor this should never deadlock due to this loop.
The original MPD server starts at 1. upmpdcli has issues with Mopidy
starting at 0 instead, as 0 is special in its context.
As noone should care exactly what core's TLIDs are, I opted to start
counting both core TLID and MPD songid from 1, instead of just
increasing TLID with 1 in the MPD frontend to get a valid songid. This
also keeps it easier to debug across the MPD/core boundary.
This moves all the deprecation warnings messages to a central place so that it
is easy to match against them without having to redefine the same regex all
over the place.
Each message has been given a message id which is more or less
module.func:extra-info. This is not intended to be parsed, just used in tests
when using the ignore helper.
This change has us checking the return value of change_track when deciding if
the play call was a success or if the track is unplayable. Which ensures that
the following can no longer happen: 1) play stream 2) play stream that fails
change_track 3) stream 1) continues playing. Correct behavior being the next
stream playing instead.
While trying to remove traces of stop calls in core to get gapless working I
found we had no way to switch to switch tracks without triggering a play. This
change fixes this by changing the backends playback provider API.
- play() now _only_ starts playback and does not take any arguments.
- prepare_change() has been added, this could have been avoided with a kwarg to
change_track(track), but that would break more backends.
- core has been updated to call prepare_change+change_track+play as needed.
- tests have been updated to handle this change.
Longer term I hope to completely rework the playback API in backends, as 99% of
our backends only use change_track(track) to translate URIs. So we should make
simple case simple, and handle mopidy-spotify / appsrc in some other way.
Cherry picked from the WIP gapless branch.
Instead of changing the signature to add(uri, name) I opted for
renaming it to _add_track(track).
Since it's internal we may change it whenever we like to. Since you need
different logic for extracting an interesting name from a track and from
a ref or a stream title, it makes sense to add another method for adding
refs/stream titles to the history when that time comes.
Fixes#1056
- Pending track should only be triggered by stream_changed if there is one.
- Tracklist changed was incorrectly calling stop breaking tests and gapless
- Tests have been updated to capture and replay audio events. This should avoid
test deadlocks while still using the audio fakes.
Seeks will now fail when the duration is None, this is an approximation to if
the track is seekable or not. This check is need as otherwise seeking a radio
stream will trigger the next track.
If the track truly isn't seekable despite having a duration we should still
fail as GStreamer will reject the seek.
The API I really want for this to support regular tracks, stream updates and
dynamic playlists is still unclear to me. As such I'm taking the KISS approach
and reducing this to just the stream title and nothing else.
If all goes as planed this will be replaced by playback_track_changed(tlid, ref)
style events and other improvements in a later version.
- Adds tests for new behaviors in core.
- Adds stream name to MPD format (fixes#944)
- Adds 'stream_changed' core event (needs a new name/event)
- Adds 'get_stream_reference' (which I'm also unsure about)
The bits I'm unsure about are mostly with respect to #270, but I'm going ahead
with this commit so we can discuss the details in PR with this code as an
example.
The warnings appear as warning level log messages if running Python on
the mopidy/ directory like this:
python -W all mopidy -v
or:
python -W all mopidy -o loglevels/py.warnings=warning
We don't suppress warnings when Pykka is the caller in general, but just
when Pykka is looking at all properties to create its actor proxies.
When a deprecated property is used from another Pykka actor, only the
stack for the current actor thread is available for inspection, so the
warning cannot show where the actual call site in the other actor thread
is. Though, if the warnings are made exceptions with:
python -W error mopidy
then the stack traces will include the frames from all involved actor
threads, showing where the original call site is.
- Adds stream changed handler to core
- Moves playback started trigger to stream changed
- Made about to finish store next track in _pending_tl_track
- Set the pending track as current in stream changed
- Adds tests for all of this and fixes existing tests
There is still quite a bit to be done is this area:
- We need to start tracking pending tracks as there is time window when we are
decoding a new track but still playing the old one
- Currently this breaks seek, next, prev during this time window
- The old on_end_of_track code needs to die.
- Stream changes need to trigger playing events and switch the pending track to
current.