1 package org.rpi.providers;
2
3 import java.util.Observable;
4 import java.util.Observer;
5
6 import org.apache.log4j.Logger;
7 import org.openhome.net.device.DvDevice;
8 import org.openhome.net.device.IDvInvocation;
9 import org.openhome.net.device.providers.DvProviderUpnpOrgAVTransport1;
10 import org.rpi.player.PlayManager;
11 import org.rpi.player.events.EventBase;
12 import org.rpi.player.events.EventStatusChanged;
13 import org.rpi.player.events.EventTimeUpdate;
14 import org.rpi.player.events.EventTrackChanged;
15 import org.rpi.player.events.EventUpdateTrackInfo;
16 import org.rpi.playlist.CustomTrack;
17 import org.rpi.utils.Utils;
18
19 public class PrvAVTransport extends DvProviderUpnpOrgAVTransport1 implements Observer {
20
21 private Logger log = Logger.getLogger(PrvAVTransport.class);
22 private String track_uri = "";
23 private String track_metadata_html = "";
24 private String track_metadata = "";
25 private String track_time = "00:00:00";
26 private String track_duration = "00:00:00";
27 private String mStatus = "STOPPED";
28
29 public PrvAVTransport(DvDevice iDevice) {
30 super(iDevice);
31 log.debug("Creating AvTransport");
32 enablePropertyLastChange();
33
34 createEvent();
35 enableActionSetAVTransportURI();
36 enableActionSetNextAVTransportURI();
37 enableActionSetPlayMode();
38 enableActionSetRecordQualityMode();
39
40 enableActionGetCurrentTransportActions();
41 enableActionGetDeviceCapabilities();
42 enableActionGetMediaInfo();
43 enableActionGetPositionInfo();
44 enableActionGetTransportInfo();
45 enableActionGetTransportSettings();
46 enableActionSeek();
47 enableActionGetCurrentTransportActions();
48
49 enableActionNext();
50 enableActionPause();
51 enableActionPlay();
52 enableActionPrevious();
53
54
55
56 enableActionStop();
57 PlayManager.getInstance().observInfoEvents(this);
58 PlayManager.getInstance().observTimeEvents(this);
59 PlayManager.getInstance().observPlayListEvents(this);
60 PlayManager.getInstance().observAVEvnts(this);
61
62 }
63
64 private void createEventState() {
65 StringBuilder sb = new StringBuilder();
66 sb.append("<Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/AVT/\">");
67 sb.append("<InstanceID val=\"0\">");
68 sb.append("<TransportState val=\"" + mStatus.toUpperCase() + "\"/>");
69 sb.append("</InstanceID>");
70 sb.append("</Event>");
71 setPropertyLastChange(sb.toString());
72 }
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 private void createEvent() {
108 StringBuilder sb = new StringBuilder();
109 sb.append("<Event xmlns=\"urn:schemas-upnp-org:metadata-1-0/AVT/\">");
110 sb.append("<InstanceID val=\"0\">");
111 sb.append("<CurrentPlayMode val=\"NORMAL\" />");
112 sb.append("<RecordStorageMedium val=\"NOT_IMPLEMENTED\" />");
113
114 sb.append("<CurrentTrackURI val=\"" + track_uri + "\" />");
115 sb.append("<CurrentTrackDuration val=\"" + track_duration + "\" />");
116 sb.append("<CurrentRecordQualityMode val=\"NOT_IMPLEMENTED\" />");
117 sb.append("<CurrentMediaDuration val=\"00:00:00\" />");
118 sb.append("<AVTransportURI val=\"\" />");
119 sb.append("<TransportState val=\"" + mStatus.toUpperCase() + "\" />");
120
121 sb.append("<CurrentTrackMetaData val=\"" + track_metadata_html + "\" />");
122 sb.append("<NextAVTransportURI val=\"NOT_IMPLEMENTED\" />");
123 sb.append("<PossibleRecordQualityModes val=\"NOT_IMPLEMENTED\" />");
124 sb.append("<CurrentTrack val=\"0\" />");
125 sb.append("<NextAVTransportURIMetaData val=\"NOT_IMPLEMENTED\" />");
126 sb.append("<PlaybackStorageMedium val=\"NONE\" />");
127 sb.append("<CurrentTransportActions val=\"Play,Pause,Stop,Seek,Next,Previous\" />");
128 sb.append("<RecordMediumWriteStatus val=\"NOT_IMPLEMENTED\" />");
129 sb.append("<PossiblePlaybackStorageMedia val=\"NONE,NETWORK,HDD,CD-DA,UNKNOWN\" />");
130 sb.append("<AVTransportURIMetaData val=\"\" />");
131 sb.append("<NumberOfTracks val=\"1\" />");
132 sb.append("<PossibleRecordStorageMedia val=\"NOT_IMPLEMENTED\" />");
133 sb.append("<TransportStatus val=\"OK\" />");
134 sb.append("<TransportPlaySpeed val=\"1\" />");
135 sb.append("</InstanceID>");
136 sb.append("</Event>");
137 setPropertyLastChange(sb.toString());
138 }
139
140 @Override
141 protected String getCurrentTransportActions(IDvInvocation paramIDvInvocation, long paramLong) {
142 log.debug("Transport Actions" + Utils.getLogText(paramIDvInvocation));
143 return "Play,Pause,Stop,Seek,Next,Previous";
144
145 }
146
147 @Override
148 protected GetDeviceCapabilities getDeviceCapabilities(IDvInvocation paramIDvInvocation, long paramLong) {
149 log.debug("GetDevice Capabilities" + Utils.getLogText(paramIDvInvocation));
150 String cap = "vendor-defined ,NOT_IMPLEMENTED,NONE,NETWORK,MICRO-MV,HDD,LD,DAT,DVD-AUDIO,DVD-RAM,DVD-RW,DVD+RW,DVD-R,DVD-VIDEO,DVD-ROM,MD-PICTURE,MD-AUDIO,SACD,VIDEO-CD,CD-RW,CD-R,CD-DA,CD-ROM,HI8,VIDEO8,VHSC,D-VHS,S-VHS,W-VHS,VHS,MINI-DV,DV,UNKNOWN";
151 String rec = " vendor-defined ,NOT_IMPLEMENTED,2:HIGH,1:MEDIUM,0:BASIC,2:SP,1:LP,0:EP";
152
153
154
155 GetDeviceCapabilities dev = new GetDeviceCapabilities(cap, cap, rec);
156 return dev;
157
158 }
159
160 @Override
161 protected GetMediaInfo getMediaInfo(IDvInvocation paramIDvInvocation, long paramLong) {
162 log.debug("GetMediaInfo" + Utils.getLogText(paramIDvInvocation));
163
164 GetMediaInfo info = new GetMediaInfo(0, track_duration, track_uri, track_metadata, "", "", "UNKNOWN", "UNKNOWN", "UNKNOWN");
165
166
167 return info;
168 }
169
170 @Override
171 protected GetPositionInfo getPositionInfo(IDvInvocation paramIDvInvocation, long paramLong) {
172 log.debug("Get Position Info" + Utils.getLogText(paramIDvInvocation));
173 GetPositionInfo info = new GetPositionInfo(0, track_duration, track_metadata, track_uri, track_time, "00:00:00", 2147483647, 2147483647);
174
175
176 return info;
177 }
178
179 @Override
180 protected GetTransportInfo getTransportInfo(IDvInvocation paramIDvInvocation, long paramLong) {
181 log.debug("GetTransport Info" + Utils.getLogText(paramIDvInvocation));
182
183 GetTransportInfo info = new GetTransportInfo(mStatus.toUpperCase(), "OK", "1");
184 return info;
185 }
186
187 @Override
188 protected GetTransportSettings getTransportSettings(IDvInvocation paramIDvInvocation, long paramLong) {
189 log.debug("GetTransportSettings" + Utils.getLogText(paramIDvInvocation));
190 GetTransportSettings settings = new GetTransportSettings("NORMAL", "0:BASIC");
191 return settings;
192 }
193
194 @Override
195 protected void next(IDvInvocation paramIDvInvocation, long paramLong) {
196 log.debug("Next: " + paramLong + Utils.getLogText(paramIDvInvocation));
197 PlayManager.getInstance().nextTrack();
198 }
199
200 @Override
201 protected void pause(IDvInvocation paramIDvInvocation, long paramLong) {
202 log.debug("Pause" + paramLong + Utils.getLogText(paramIDvInvocation));
203 PlayManager.getInstance().pause();
204 }
205
206 @Override
207 protected void play(IDvInvocation paramIDvInvocation, long paramLong, String paramString) {
208 log.debug("Play: " + paramString + Utils.getLogText(paramIDvInvocation));
209 if (!track_uri.equalsIgnoreCase("")) {
210 if (mStatus.equalsIgnoreCase("PAUSED_PLAYBACK")) {
211 PlayManager.getInstance().play();
212 } else {
213 CustomTrack c = new CustomTrack(track_uri, track_metadata, 0);
214 PlayManager.getInstance().playAV(c);
215 }
216 } else {
217 if (mStatus.equalsIgnoreCase("PAUSED_PLAYBACK")) {
218 PlayManager.getInstance().play();
219 }
220 }
221
222 }
223
224 @Override
225 protected void previous(IDvInvocation paramIDvInvocation, long paramLong) {
226 log.debug("Previous: " + paramLong + Utils.getLogText(paramIDvInvocation));
227 PlayManager.getInstance().previousTrack();
228 }
229
230 @Override
231 protected void record(IDvInvocation paramIDvInvocation, long paramLong) {
232 log.debug("Record");
233 }
234
235 @Override
236 protected void seek(IDvInvocation paramIDvInvocation, long paramLong, String paramString1, String paramString2) {
237 log.debug("Seek: " + paramString2 + Utils.getLogText(paramIDvInvocation));
238 PlayManager.getInstance().seekAbsolute(getSeconds(paramString2));
239 }
240
241 private long getSeconds(String t) {
242
243 int duration = 0;
244 try {
245 String[] tokens = t.split(":");
246 int hours = Integer.parseInt(tokens[0]);
247 int minutes = Integer.parseInt(tokens[1]);
248 int seconds = Integer.parseInt(tokens[2]);
249 duration = 3600 * hours + 60 * minutes + seconds;
250 } catch (Exception e) {
251
252 }
253 return (long) duration;
254 }
255
256 @Override
257 protected void setAVTransportURI(IDvInvocation paramIDvInvocation, long paramLong, String url, String meta_data) {
258 log.debug("SetAVTransport: " + paramLong + " URL: " + url + " MetaData: " + meta_data + Utils.getLogText(paramIDvInvocation));
259 track_uri = url;
260 track_metadata = meta_data;
261 }
262
263 @Override
264 protected void setNextAVTransportURI(IDvInvocation paramIDvInvocation, long paramLong, String paramString1, String paramString2) {
265 log.debug("SetNexAVTransport: " + paramLong + " " + paramString1 + " " + paramString2 + Utils.getLogText(paramIDvInvocation));
266 }
267
268 @Override
269 protected void setPlayMode(IDvInvocation paramIDvInvocation, long paramLong, String paramString) {
270 log.debug("SetPlayMode: " + paramLong + " " + paramString + Utils.getLogText(paramIDvInvocation));
271 }
272
273 @Override
274 protected void setRecordQualityMode(IDvInvocation paramIDvInvocation, long paramLong, String paramString) {
275 log.debug("SetRecordQuality: " + paramLong + " " + paramString + Utils.getLogText(paramIDvInvocation));
276 }
277
278 @Override
279 protected void stop(IDvInvocation paramIDvInvocation, long paramLong) {
280 log.debug("Stop: " + paramLong + Utils.getLogText(paramIDvInvocation));
281 PlayManager.getInstance().stop();
282 }
283
284 @Override
285 public void update(Observable arg0, Object ev) {
286 EventBase e = (EventBase) ev;
287 switch (e.getType()) {
288 case EVENTTRACKCHANGED:
289 EventTrackChanged ec = (EventTrackChanged) e;
290 CustomTrack track = ec.getTrack();
291 String m_uri = "";
292 String m_metadata = "";
293 if (track != null) {
294 m_uri = track.getUri();
295 m_metadata = track.getMetadata();
296 if (!(m_uri.equalsIgnoreCase(track_uri)) || (!m_metadata.equalsIgnoreCase(track_metadata))) {
297 track_uri = m_uri;
298 track_metadata = m_metadata;
299 track_metadata_html = stringToHTMLString(m_metadata);
300 createEvent();
301 }
302 } else {
303
304
305 }
306
307 break;
308 case EVENTTIMEUPDATED:
309 EventTimeUpdate etime = (EventTimeUpdate) e;
310 track_time = ConvertTime(etime.getTime());
311
312 break;
313 case EVENTUPDATETRACKINFO:
314 EventUpdateTrackInfo eti = (EventUpdateTrackInfo) e;
315 track_duration = ConvertTime(eti.getTrackInfo().getDuration());
316 createEvent();
317 break;
318
319
320
321
322
323
324
325
326
327
328
329
330 case EVENTSTATUSCHANGED:
331 EventStatusChanged esc = (EventStatusChanged) e;
332 String statuss = esc.getStatus();
333 log.debug("Status: " + statuss);
334 if (statuss != null) {
335 if (statuss.equalsIgnoreCase("PAUSED")) {
336 statuss = "PAUSED_PLAYBACK";
337 }
338 if (statuss.equalsIgnoreCase("BUFFERING")) {
339 statuss = "TRANSITIONING";
340 }
341 if (!mStatus.equalsIgnoreCase(statuss)) {
342 mStatus = statuss;
343 createEvent();
344 }
345 }
346 default:
347 }
348 }
349
350
351
352
353
354
355
356 private String ConvertTime(long lTime) {
357 int seconds = (int) lTime;
358 int hours = seconds / 3600;
359 int minutes = (seconds % 3600) / 60;
360 seconds = seconds % 60;
361
362 return twoDigitString(hours) + ":" + twoDigitString(minutes) + ":" + twoDigitString(seconds);
363 }
364
365 private String twoDigitString(int number) {
366
367 if (number < 0) {
368 number = 0;
369 }
370 if (number == 0) {
371 return "00";
372 }
373
374 if (number / 10 == 0) {
375 return "0" + number;
376 }
377
378 return String.valueOf(number);
379 }
380
381 public static String stringToHTMLString(String string) {
382 StringBuffer sb = new StringBuffer(string.length());
383
384 boolean lastWasBlankChar = false;
385 int len = string.length();
386 char c;
387
388 for (int i = 0; i < len; i++) {
389 c = string.charAt(i);
390 if (c == ' ') {
391
392
393
394
395 if (lastWasBlankChar) {
396 lastWasBlankChar = false;
397 sb.append(" ");
398 } else {
399 lastWasBlankChar = true;
400 sb.append(' ');
401 }
402 } else {
403 lastWasBlankChar = false;
404
405
406 if (c == '"')
407 sb.append(""");
408 else if (c == '&')
409 sb.append("&");
410 else if (c == '<')
411 sb.append("<");
412 else if (c == '>')
413 sb.append(">");
414 else if (c == '\n')
415
416 sb.append("<br/>");
417 else {
418 int ci = 0xffff & c;
419 if (ci < 160)
420
421 sb.append(c);
422 else {
423
424 sb.append("&#");
425 sb.append(new Integer(ci).toString());
426 sb.append(';');
427 }
428 }
429 }
430 }
431 return sb.toString();
432 }
433
434 }