1
2
3
4
5 """ Extends the base control point and adds basic Audio/Video functionality.
6 """
7
8 from brisa.core import log
9 from brisa.core.network import parse_url
10 from brisa.upnp.control_point.control_point import ControlPoint
11 from brisa.upnp.control_point.device import Device
12 from brisa.upnp.didl.didl_lite import Element
13
14
15 log = log.getLogger('control-point.control-point-av')
16
17
19 """ This class extends ControlPoint and add basic AV functionality.
20
21 Basic usage is to set a server and/or renderer device with
22 set_current_server() and/or set_current_renderer() to work on, then use
23 the available A/V methods which are listed below.
24
25 Media servers:
26 - browse() - performs browse
27 - search() - performs search
28 - get_search_capabilities() - returns the search capabilities
29 - get_sort_capabilities() - returns the sort capabilities
30
31 Media renderer:
32 - av_play(id, uri) - plays an item from a media server on a media
33 renderer. Must receive the item id on the media
34 server or the URL where it is available.
35 - av_stop() - stop playing
36 - av_pause() - pause
37 - av_next() - play next track
38 - av_previous() - play previous track
39 """
40
41 CDS_namespace = 'urn:schemas-upnp-org:service:ContentDirectory:1'
42 AVT_namespace = 'urn:schemas-upnp-org:service:AVTransport:1'
43 DMS_type = 'urn:schemas-upnp-org:device:MediaServer:'
44 DMR_type = 'urn:schemas-upnp-org:device:MediaRenderer:'
45 msg_invalid_server = 'server_device parameter must be a Device'
46 msg_invalid_renderer = 'renderer_device parameter must be a Device'
47 msg_select_server = 'media server not set. Set it with '\
48 'set_current_server().'
49 msg_select_renderer = 'media renderer not set. Set it with '\
50 'set_current_renderer().'
51
52 - def __init__(self, receive_notify=True):
53 """ Constructor for the ControlPointAV class.
54
55 @param receive_notify: if False, disables notify handling. This means
56 it will only listen for MSearch responses.
57 @type receive_notify: bool
58 """
59 ControlPoint.__init__(self, receive_notify)
60 self._current_server = None
61 self._current_renderer = None
62
64 """ Returns the current selected server.
65 """
66 return self._current_server
67
69 """ Sets the current server. Required before performing any action on
70 the Content Directory service.
71
72 @param server_device: server
73 @type server_device: Device
74 """
75 assert isinstance(server_device, Device), self.msg_invalid_server
76 self._current_server = server_device
77
79 """ Returns the current selected renderer.
80 """
81 return self._current_renderer
82
84 """ Sets the current renderer. Required before performing any action
85 on the AV Transport service.
86
87 @param renderer_device: renderer
88 @type renderer_device: Device
89 """
90 assert isinstance(renderer_device, Device), self.msg_invalid_renderer
91 self._current_renderer = renderer_device
92
99
106
107 - def browse(self, object_id, browse_flag, filter, starting_index,
108 requested_count, sort_criteria="dc:title"):
109 """ Browses media servers.
110
111 @param object_id: object id
112 @param browse_flag: BrowseDirectChildren or BrowseMetadata
113 @param filter: a filter to indicate which metadata properties
114 are to be returned. Usually "*".
115 @param starting_index: starting index to consider the requested count
116 @param requested_count: requested number of entries
117 @param sort_criteria: sorting criteria
118
119 @type object_id: string
120 @type browse_flag: string
121 @type filter: string
122 @type starting_index: int
123 @type requested_count: int
124 @type sort_criteria: string
125
126 @return: a list of containers and items
127 @rtype: list
128 """
129 service = self.get_cd_service()
130 browse_response = service.Browse(ObjectID=str(object_id),
131 BrowseFlag=browse_flag,
132 Filter=filter,
133 StartingIndex=starting_index,
134 RequestedCount=requested_count,
135 SortCriteria=sort_criteria)
136 elt = Element.from_string(browse_response['Result'])
137 browse_response['Result'] = elt.get_items()
138 return browse_response
139
140 - def search(self, container_id, search_criteria, filter, starting_index,
141 requested_count, sort_criteria):
142 """ Search items in Media Server.
143
144 This method search items with search_criteria key in the container_id
145 of current media server.
146
147 @param container_id: unique identifier of the container in which
148 to begin searching.
149 @param search_criteria: search criteria
150 @param filter: a filter to indicate which metadata properties
151 are to be returned.
152 @param starting_index: starting index to consider the requested
153 count
154 @param requested_count: requested number of entries under the
155 object specified by container_id
156 @param sort_criteria: sorting criteria
157
158 @type container_id: string
159 @type search_criteria: string
160 @type filter: string
161 @type starting_index: int
162 @type requested_count: int
163 @type sort_criteria: string
164
165 @return: search result
166 @rtype: dict
167 """
168 service = self.get_cd_service()
169 search_response = service.Search(ContainerID=container_id,
170 SearchCriteria=search_criteria,
171 Filter=filter,
172 StartingIndex=starting_index,
173 RequestedCount=requested_count,
174 SortCriteria=sort_criteria)
175 elt = Element.from_string(search_response['Result'])
176 return elt.get_items()
177
179 """ Return the fields supported by the server for searching.
180
181 @rtype: dict
182 """
183 return self.get_cd_service().GetSearchCapabilities()
184
186 """ Returns a list of fields supported by the server for sorting.
187
188 @rtype: dict
189 """
190 return self.get_cd_service().GetSortCapabilities()
191
193 """ Tells the selected media renderer to play an item given its id or
194 media URI.
195
196 @param id: id of the media on the media server
197 @param uri: URI where the media is available
198
199 @type id: string
200 @type uri: string
201 """
202 if not uri:
203 item = self.browse(id, 'BrowseMetadata', '*', 0, 1, '')
204 uri = item['Result'][0].resources[0].value
205 avt = self.get_avt_service()
206 avt.SetAVTransportURI(InstanceID=0,
207 CurrentURI=uri,
208 CurrentURIMetaData='')
209 avt.Play()
210
212 """ Stops the rendering.
213 """
214 avt = self.get_avt_service()
215 avt.Stop()
216
218 """ Pauses the rendering.
219 """
220 avt = self.get_avt_service()
221 avt.Pause()
222
224 """ Requests play on the next track.
225 """
226 avt = self.get_avt_service()
227 avt.Next()
228
230 """ Requests play on the previous track.
231 """
232 avt = self.get_avt_service()
233 avt.Previous()
234