1# -*- coding: utf-8 -*-
2#
3# gPodder - A media aggregator and podcast client
4# Copyright (c) 2005-2018 The gPodder Team
5#
6# gPodder is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3 of the License, or
9# (at your option) any later version.
10#
11# gPodder is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18#
19
20#
21# gpodder.player - Podcatcher implementation of the Media Player D-Bus API
22# Thomas Perl <thp@gpodder.org>; 2010-04-25
23#
24
25#
26# This API specification aims at providing a documented, easy-to-use API for
27# getting and setting the media player position via D-Bus. This should allow
28# media players (such as Panucci) and podcast aggregators (such as gPodder) to
29# work together and synchronize the playback position of media files.
30#
31# == Interface: org.gpodder.player ==
32#
33# - PlaybackStarted(uint32 position, string file_uri)
34#
35#   Emitted when the media player starts playback of a given file at file_uri
36#   at the position position.
37#
38#
39# - PlaybackStopped(uint32 start_position, uint32 end_position,
40#                   uint32 total_time, string file_uri)
41#
42#   Emitted when the user stops/pauses playback, when the playback ends or the
43#   player is closed. The file URI is in file_uri, the start time of the
44#   segment that has just been played is in start_position, the stop time in
45#   end_position and the (detected) total time of the file is in total_time.
46#
47#   Seeking in the file should also emit a PlaybackStopped signal (at the
48#   position where the seek is initialized) and a PlaybackStarted signal (at
49#   the position to which the seek jumps).
50#
51
52
53import urllib.error
54import urllib.parse
55import urllib.request
56
57import gpodder
58
59
60class MediaPlayerDBusReceiver(object):
61    INTERFACE = 'org.gpodder.player'
62    SIGNAL_STARTED = 'PlaybackStarted'
63    SIGNAL_STOPPED = 'PlaybackStopped'
64
65    def __init__(self, on_play_event):
66        self.on_play_event = on_play_event
67
68        self.bus = gpodder.dbus_session_bus
69        self.bus.add_signal_receiver(self.on_playback_started,
70                                     self.SIGNAL_STARTED,
71                                     self.INTERFACE,
72                                     None,
73                                     None)
74        self.bus.add_signal_receiver(self.on_playback_stopped,
75                                     self.SIGNAL_STOPPED,
76                                     self.INTERFACE,
77                                     None,
78                                     None)
79
80    def on_playback_started(self, position, file_uri):
81        pass
82
83    def on_playback_stopped(self, start, end, total, file_uri):
84        if file_uri.startswith('/'):
85            file_uri = 'file://' + urllib.parse.quote(file_uri)
86        self.on_play_event(start, end, total, file_uri)
87