1 /*****************************************************************
2 |
3 | Platinum - Miccro Media Controller
4 |
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
6 | All rights reserved.
7 | http://www.plutinosoft.com
8 |
9 | This program is free software; you can redistribute it and/or
10 | modify it under the terms of the GNU General Public License
11 | as published by the Free Software Foundation; either version 2
12 | of the License, or (at your option) any later version.
13 |
14 | OEMs, ISVs, VARs and other distributors that combine and
15 | distribute commercially licensed software with Platinum software
16 | and do not wish to distribute the source code for the commercially
17 | licensed software under version 2, or (at your option) any later
18 | version, of the GNU General Public License (the "GPL") must enter
19 | into a commercial license agreement with Plutinosoft, LLC.
20 | licensing@plutinosoft.com
21 |
22 | This program is distributed in the hope that it will be useful,
23 | but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | GNU General Public License for more details.
26 |
27 | You should have received a copy of the GNU General Public License
28 | along with this program; see the file LICENSE.txt. If not, write to
29 | the Free Software Foundation, Inc.,
30 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 | http://www.gnu.org/licenses/gpl-2.0.html
32 |
33 ****************************************************************/
34
35 /*----------------------------------------------------------------------
36 | includes
37 +---------------------------------------------------------------------*/
38 #include "PltMicroMediaController.h"
39 #include "PltLeaks.h"
40 #include "PltDownloader.h"
41
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45
46 //NPT_SET_LOCAL_LOGGER("platinum.tests.micromediacontroller")
47
48 /*----------------------------------------------------------------------
49 | PLT_MicroMediaController::PLT_MicroMediaController
50 +---------------------------------------------------------------------*/
PLT_MicroMediaController(PLT_CtrlPointReference & ctrlPoint)51 PLT_MicroMediaController::PLT_MicroMediaController(PLT_CtrlPointReference& ctrlPoint) :
52 PLT_SyncMediaBrowser(ctrlPoint),
53 PLT_MediaController(ctrlPoint)
54 {
55 // create the stack that will be the directory where the
56 // user is currently browsing.
57 // push the root directory onto the directory stack.
58 m_CurBrowseDirectoryStack.Push("0");
59
60 PLT_MediaController::SetDelegate(this);
61 }
62
63 /*----------------------------------------------------------------------
64 | PLT_MicroMediaController::PLT_MicroMediaController
65 +---------------------------------------------------------------------*/
~PLT_MicroMediaController()66 PLT_MicroMediaController::~PLT_MicroMediaController()
67 {
68 }
69
70 /*
71 * Remove trailing white space from a string
72 */
strchomp(char * str)73 static void strchomp(char* str)
74 {
75 if (!str) return;
76 char* e = str+NPT_StringLength(str)-1;
77
78 while (e >= str && *e) {
79 if ((*e != ' ') &&
80 (*e != '\t') &&
81 (*e != '\r') &&
82 (*e != '\n'))
83 {
84 *(e+1) = '\0';
85 break;
86 }
87 --e;
88 }
89 }
90
91 /*----------------------------------------------------------------------
92 | PLT_MicroMediaController::ChooseIDFromTable
93 +---------------------------------------------------------------------*/
94 /*
95 * Presents a list to the user, allows the user to choose one item.
96 *
97 * Parameters:
98 * PLT_StringMap: A map that contains the set of items from
99 * which the user should choose. The key should be a unique ID,
100 * and the value should be a string describing the item.
101 * returns a NPT_String with the unique ID.
102 */
103 const char*
ChooseIDFromTable(PLT_StringMap & table)104 PLT_MicroMediaController::ChooseIDFromTable(PLT_StringMap& table)
105 {
106 printf("Select one of the following:\n");
107
108 NPT_List<PLT_StringMapEntry*> entries = table.GetEntries();
109 if (entries.GetItemCount() == 0) {
110 printf("None available\n");
111 } else {
112 // display the list of entries
113 NPT_List<PLT_StringMapEntry*>::Iterator entry = entries.GetFirstItem();
114 int count = 0;
115 while (entry) {
116 printf("%d)\t%s (%s)\n", ++count, (const char*)(*entry)->GetValue(), (const char*)(*entry)->GetKey());
117 ++entry;
118 }
119
120 int index, watchdog = 3;
121 char buffer[1024];
122
123 // wait for input
124 while (watchdog > 0) {
125 fgets(buffer, 1024, stdin);
126 strchomp(buffer);
127
128 if (1 != sscanf(buffer, "%d", &index)) {
129 printf("Please enter a number\n");
130 } else if (index < 0 || index > count) {
131 printf("Please choose one of the above, or 0 for none\n");
132 watchdog--;
133 index = 0;
134 } else {
135 watchdog = 0;
136 }
137 }
138
139 // find the entry back
140 if (index != 0) {
141 entry = entries.GetFirstItem();
142 while (entry && --index) {
143 ++entry;
144 }
145 if (entry) {
146 return (*entry)->GetKey();
147 }
148 }
149 }
150
151 return NULL;
152 }
153
154 /*----------------------------------------------------------------------
155 | PLT_MicroMediaController::PopDirectoryStackToRoot
156 +---------------------------------------------------------------------*/
157 void
PopDirectoryStackToRoot(void)158 PLT_MicroMediaController::PopDirectoryStackToRoot(void)
159 {
160 NPT_String val;
161 while (NPT_SUCCEEDED(m_CurBrowseDirectoryStack.Peek(val)) && val.Compare("0")) {
162 m_CurBrowseDirectoryStack.Pop(val);
163 }
164 }
165
166 /*----------------------------------------------------------------------
167 | PLT_MicroMediaController::OnMSAdded
168 +---------------------------------------------------------------------*/
169 bool
OnMSAdded(PLT_DeviceDataReference & device)170 PLT_MicroMediaController::OnMSAdded(PLT_DeviceDataReference& device)
171 {
172 // Issue special action upon discovering MediaConnect server
173 PLT_Service* service;
174 if (NPT_SUCCEEDED(device->FindServiceByType("urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:*", service))) {
175 PLT_ActionReference action;
176 PLT_SyncMediaBrowser::m_CtrlPoint->CreateAction(
177 device,
178 "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1",
179 "IsAuthorized",
180 action);
181 if (!action.IsNull()) {
182 action->SetArgumentValue("DeviceID", "");
183 PLT_SyncMediaBrowser::m_CtrlPoint->InvokeAction(action, 0);
184 }
185
186 PLT_SyncMediaBrowser::m_CtrlPoint->CreateAction(
187 device,
188 "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1",
189 "IsValidated",
190 action);
191 if (!action.IsNull()) {
192 action->SetArgumentValue("DeviceID", "");
193 PLT_SyncMediaBrowser::m_CtrlPoint->InvokeAction(action, 0);
194 }
195 }
196
197 return true;
198 }
199
200 /*----------------------------------------------------------------------
201 | PLT_MicroMediaController::OnMRAdded
202 +---------------------------------------------------------------------*/
203 bool
OnMRAdded(PLT_DeviceDataReference & device)204 PLT_MicroMediaController::OnMRAdded(PLT_DeviceDataReference& device)
205 {
206 NPT_String uuid = device->GetUUID();
207
208 // test if it's a media renderer
209 PLT_Service* service;
210 if (NPT_SUCCEEDED(device->FindServiceByType("urn:schemas-upnp-org:service:AVTransport:*", service))) {
211 NPT_AutoLock lock(m_MediaRenderers);
212 m_MediaRenderers.Put(uuid, device);
213 }
214
215 return true;
216 }
217
218 /*----------------------------------------------------------------------
219 | PLT_MicroMediaController::OnMRRemoved
220 +---------------------------------------------------------------------*/
221 void
OnMRRemoved(PLT_DeviceDataReference & device)222 PLT_MicroMediaController::OnMRRemoved(PLT_DeviceDataReference& device)
223 {
224 NPT_String uuid = device->GetUUID();
225
226 {
227 NPT_AutoLock lock(m_MediaRenderers);
228 m_MediaRenderers.Erase(uuid);
229 }
230
231 {
232 NPT_AutoLock lock(m_CurMediaRendererLock);
233
234 // if it's the currently selected one, we have to get rid of it
235 if (!m_CurMediaRenderer.IsNull() && m_CurMediaRenderer == device) {
236 m_CurMediaRenderer = NULL;
237 }
238 }
239 }
240
241 /*----------------------------------------------------------------------
242 | PLT_MicroMediaController::OnMRStateVariablesChanged
243 +---------------------------------------------------------------------*/
244 void
OnMRStateVariablesChanged(PLT_Service * service,NPT_List<PLT_StateVariable * > * vars)245 PLT_MicroMediaController::OnMRStateVariablesChanged(PLT_Service* service,
246 NPT_List<PLT_StateVariable*>* vars)
247 {
248 NPT_String uuid = service->GetDevice()->GetUUID();
249 NPT_List<PLT_StateVariable*>::Iterator var = vars->GetFirstItem();
250 while (var) {
251 printf("Received state var \"%s:%s:%s\" changes: \"%s\"\n",
252 (const char*)uuid,
253 (const char*)service->GetServiceID(),
254 (const char*)(*var)->GetName(),
255 (const char*)(*var)->GetValue());
256 ++var;
257 }
258 }
259
260 /*----------------------------------------------------------------------
261 | PLT_MicroMediaController::ChooseIDGetCurMediaServerFromTable
262 +---------------------------------------------------------------------*/
263 void
GetCurMediaServer(PLT_DeviceDataReference & server)264 PLT_MicroMediaController::GetCurMediaServer(PLT_DeviceDataReference& server)
265 {
266 NPT_AutoLock lock(m_CurMediaServerLock);
267
268 if (m_CurMediaServer.IsNull()) {
269 printf("No server selected, select one with setms\n");
270 } else {
271 server = m_CurMediaServer;
272 }
273 }
274
275 /*----------------------------------------------------------------------
276 | PLT_MicroMediaController::GetCurMediaRenderer
277 +---------------------------------------------------------------------*/
278 void
GetCurMediaRenderer(PLT_DeviceDataReference & renderer)279 PLT_MicroMediaController::GetCurMediaRenderer(PLT_DeviceDataReference& renderer)
280 {
281 NPT_AutoLock lock(m_CurMediaRendererLock);
282
283 if (m_CurMediaRenderer.IsNull()) {
284 printf("No renderer selected, select one with setmr\n");
285 } else {
286 renderer = m_CurMediaRenderer;
287 }
288 }
289
290 /*----------------------------------------------------------------------
291 | PLT_MicroMediaController::DoBrowse
292 +---------------------------------------------------------------------*/
293 NPT_Result
DoBrowse(const char * object_id,bool metadata)294 PLT_MicroMediaController::DoBrowse(const char* object_id, /* = NULL */
295 bool metadata /* = false */)
296 {
297 NPT_Result res = NPT_FAILURE;
298 PLT_DeviceDataReference device;
299
300 GetCurMediaServer(device);
301 if (!device.IsNull()) {
302 NPT_String cur_object_id;
303 m_CurBrowseDirectoryStack.Peek(cur_object_id);
304
305 // send off the browse packet and block
306 res = BrowseSync(
307 device,
308 object_id?object_id:(const char*)cur_object_id,
309 m_MostRecentBrowseResults,
310 metadata);
311 }
312
313 return res;
314 }
315
316 /*----------------------------------------------------------------------
317 | PLT_MicroMediaController::HandleCmd_getms
318 +---------------------------------------------------------------------*/
319 void
HandleCmd_getms()320 PLT_MicroMediaController::HandleCmd_getms()
321 {
322 PLT_DeviceDataReference device;
323 GetCurMediaServer(device);
324 if (!device.IsNull()) {
325 printf("Current media server: %s\n", (const char*)device->GetFriendlyName());
326 } else {
327 // this output is taken care of by the GetCurMediaServer call
328 }
329 }
330
331 /*----------------------------------------------------------------------
332 | PLT_MicroMediaController::HandleCmd_getmr
333 +---------------------------------------------------------------------*/
334 void
HandleCmd_getmr()335 PLT_MicroMediaController::HandleCmd_getmr()
336 {
337 PLT_DeviceDataReference device;
338 GetCurMediaRenderer(device);
339 if (!device.IsNull()) {
340 printf("Current media renderer: %s\n", (const char*)device->GetFriendlyName());
341 } else {
342 // this output is taken care of by the GetCurMediaRenderer call
343 }
344 }
345
346 /*----------------------------------------------------------------------
347 | PLT_MicroMediaController::ChooseDevice
348 +---------------------------------------------------------------------*/
349 PLT_DeviceDataReference
ChooseDevice(const NPT_Lock<PLT_DeviceMap> & deviceList)350 PLT_MicroMediaController::ChooseDevice(const NPT_Lock<PLT_DeviceMap>& deviceList)
351 {
352 PLT_StringMap namesTable;
353 PLT_DeviceDataReference* result = NULL;
354 NPT_String chosenUUID;
355 NPT_AutoLock lock(m_MediaServers);
356
357 // create a map with the device UDN -> device Name
358 const NPT_List<PLT_DeviceMapEntry*>& entries = deviceList.GetEntries();
359 NPT_List<PLT_DeviceMapEntry*>::Iterator entry = entries.GetFirstItem();
360 while (entry) {
361 PLT_DeviceDataReference device = (*entry)->GetValue();
362 NPT_String name = device->GetFriendlyName();
363 namesTable.Put((*entry)->GetKey(), name);
364
365 ++entry;
366 }
367
368 // ask user to choose
369 chosenUUID = ChooseIDFromTable(namesTable);
370 if (chosenUUID.GetLength()) {
371 deviceList.Get(chosenUUID, result);
372 }
373
374 return result?*result:PLT_DeviceDataReference(); // return empty reference if not device was selected
375 }
376
377 /*----------------------------------------------------------------------
378 | PLT_MicroMediaController::HandleCmd_setms
379 +---------------------------------------------------------------------*/
380 void
HandleCmd_setms()381 PLT_MicroMediaController::HandleCmd_setms()
382 {
383 NPT_AutoLock lock(m_CurMediaServerLock);
384
385 PopDirectoryStackToRoot();
386 m_CurMediaServer = ChooseDevice(GetMediaServersMap());
387 }
388
389 /*----------------------------------------------------------------------
390 | PLT_MicroMediaController::HandleCmd_setmr
391 +---------------------------------------------------------------------*/
392 void
HandleCmd_setmr()393 PLT_MicroMediaController::HandleCmd_setmr()
394 {
395 NPT_AutoLock lock(m_CurMediaRendererLock);
396
397 m_CurMediaRenderer = ChooseDevice(m_MediaRenderers);
398 }
399
400 /*----------------------------------------------------------------------
401 | PLT_MicroMediaController::HandleCmd_ls
402 +---------------------------------------------------------------------*/
403 void
HandleCmd_ls()404 PLT_MicroMediaController::HandleCmd_ls()
405 {
406 DoBrowse();
407
408 if (!m_MostRecentBrowseResults.IsNull()) {
409 printf("There were %d results\n", m_MostRecentBrowseResults->GetItemCount());
410
411 NPT_List<PLT_MediaObject*>::Iterator item = m_MostRecentBrowseResults->GetFirstItem();
412 while (item) {
413 if ((*item)->IsContainer()) {
414 printf("Container: %s (%s)\n", (*item)->m_Title.GetChars(), (*item)->m_ObjectID.GetChars());
415 } else {
416 printf("Item: %s (%s)\n", (*item)->m_Title.GetChars(), (*item)->m_ObjectID.GetChars());
417 }
418 ++item;
419 }
420
421 m_MostRecentBrowseResults = NULL;
422 }
423 }
424
425 /*----------------------------------------------------------------------
426 | PLT_MicroMediaController::HandleCmd_info
427 +---------------------------------------------------------------------*/
428 void
HandleCmd_info()429 PLT_MicroMediaController::HandleCmd_info()
430 {
431 NPT_String object_id;
432 PLT_StringMap tracks;
433 PLT_DeviceDataReference device;
434
435 // issue a browse
436 DoBrowse();
437
438 if (!m_MostRecentBrowseResults.IsNull()) {
439 // create a map item id -> item title
440 NPT_List<PLT_MediaObject*>::Iterator item = m_MostRecentBrowseResults->GetFirstItem();
441 while (item) {
442 if (!(*item)->IsContainer()) {
443 tracks.Put((*item)->m_ObjectID, (*item)->m_Title);
444 }
445 ++item;
446 }
447
448 // let the user choose which one
449 object_id = ChooseIDFromTable(tracks);
450
451 if (object_id.GetLength()) {
452 // issue a browse with metadata
453 DoBrowse(object_id, true);
454
455 // look back for the PLT_MediaItem in the results
456 PLT_MediaObject* track = NULL;
457 if (!m_MostRecentBrowseResults.IsNull() &&
458 NPT_SUCCEEDED(NPT_ContainerFind(*m_MostRecentBrowseResults, PLT_MediaItemIDFinder(object_id), track))) {
459
460 // display info
461 printf("Title: %s \n", track->m_Title.GetChars());
462 printf("OjbectID: %s\n", track->m_ObjectID.GetChars());
463 printf("Class: %s\n", track->m_ObjectClass.type.GetChars());
464 printf("Creator: %s\n", track->m_Creator.GetChars());
465 printf("Date: %s\n", track->m_Date.GetChars());
466 for (NPT_List<PLT_AlbumArtInfo>::Iterator iter = track->m_ExtraInfo.album_arts.GetFirstItem();
467 iter;
468 iter++) {
469 printf("Art Uri: %s\n", (*iter).uri.GetChars());
470 printf("Art Uri DLNA Profile: %s\n", (*iter).dlna_profile.GetChars());
471 }
472 for (NPT_Cardinal i=0;i<track->m_Resources.GetItemCount(); i++) {
473 printf("\tResource[%d].uri: %s\n", i, track->m_Resources[i].m_Uri.GetChars());
474 printf("\tResource[%d].profile: %s\n", i, track->m_Resources[i].m_ProtocolInfo.ToString().GetChars());
475 printf("\tResource[%d].duration: %d\n", i, track->m_Resources[i].m_Duration);
476 printf("\tResource[%d].size: %d\n", i, (int)track->m_Resources[i].m_Size);
477 printf("\n");
478 }
479 printf("Didl: %s\n", (const char*)track->m_Didl);
480 } else {
481 printf("Couldn't find the track\n");
482 }
483 }
484
485 m_MostRecentBrowseResults = NULL;
486 }
487 }
488
489 /*----------------------------------------------------------------------
490 | PLT_MicroMediaController::HandleCmd_download
491 +---------------------------------------------------------------------*/
492 void
HandleCmd_download()493 PLT_MicroMediaController::HandleCmd_download()
494 {
495 NPT_String object_id;
496 PLT_StringMap tracks;
497 PLT_DeviceDataReference device;
498
499 // issue a browse
500 DoBrowse();
501
502 if (!m_MostRecentBrowseResults.IsNull()) {
503 // create a map item id -> item title
504 NPT_List<PLT_MediaObject*>::Iterator item = m_MostRecentBrowseResults->GetFirstItem();
505 while (item) {
506 if (!(*item)->IsContainer()) {
507 tracks.Put((*item)->m_ObjectID, (*item)->m_Title);
508 }
509 ++item;
510 }
511
512 // let the user choose which one
513 object_id = ChooseIDFromTable(tracks);
514
515 if (object_id.GetLength()) {
516 // issue a browse with metadata
517 DoBrowse(object_id, true);
518
519 // look back for the PLT_MediaItem in the results
520 PLT_MediaObject* track = NULL;
521 if (!m_MostRecentBrowseResults.IsNull() &&
522 NPT_SUCCEEDED(NPT_ContainerFind(*m_MostRecentBrowseResults, PLT_MediaItemIDFinder(object_id), track))) {
523
524 if (track->m_Resources.GetItemCount() > 0) {
525 printf("\tResource[0].uri: %s\n", track->m_Resources[0].m_Uri.GetChars());
526 printf("\n");
527 NPT_HttpUrl url(track->m_Resources[0].m_Uri.GetChars());
528 if (url.IsValid()) {
529 // Extract filename from URL
530 NPT_String filename = NPT_FilePath::BaseName(url.GetPath(true).GetChars(), false);
531 NPT_String extension = NPT_FilePath::FileExtension(url.GetPath(true).GetChars());
532 printf("Downloading %s%s\n", filename.GetChars(), extension.GetChars());
533
534 for (int i=0; i<3; i++) {
535 NPT_String filepath = NPT_String::Format("%s_%d%s", filename.GetChars(), i, extension.GetChars());
536
537 // Open file for writing
538 NPT_File file(filepath);
539 file.Open(NPT_FILE_OPEN_MODE_WRITE | NPT_FILE_OPEN_MODE_CREATE | NPT_FILE_OPEN_MODE_TRUNCATE);
540 NPT_OutputStreamReference output;
541 file.GetOutputStream(output);
542
543 // trigger 3 download
544 PLT_Downloader* downloader = new PLT_Downloader(url, output);
545 NPT_TimeInterval delay(5.);
546 m_DownloadTaskManager.StartTask(downloader, &delay);
547 }
548 }
549 } else {
550 printf("No resources found");
551 }
552 } else {
553 printf("Couldn't find the track\n");
554 }
555 }
556
557 m_MostRecentBrowseResults = NULL;
558 }
559 }
560
561 /*----------------------------------------------------------------------
562 | PLT_MicroMediaController::HandleCmd_cd
563 +---------------------------------------------------------------------*/
564 void
HandleCmd_cd(const char * command)565 PLT_MicroMediaController::HandleCmd_cd(const char* command)
566 {
567 NPT_String newobject_id;
568 PLT_StringMap containers;
569
570 // if command has parameter, push it to stack and return
571 NPT_String id = command;
572 NPT_List<NPT_String> args = id.Split(" ");
573 if (args.GetItemCount() >= 2) {
574 args.Erase(args.GetFirstItem());
575 id = NPT_String::Join(args, " ");
576 m_CurBrowseDirectoryStack.Push(id);
577 return;
578 }
579
580 // list current directory to let user choose
581 DoBrowse();
582
583 if (!m_MostRecentBrowseResults.IsNull()) {
584 NPT_List<PLT_MediaObject*>::Iterator item = m_MostRecentBrowseResults->GetFirstItem();
585 while (item) {
586 if ((*item)->IsContainer()) {
587 containers.Put((*item)->m_ObjectID, (*item)->m_Title);
588 }
589 ++item;
590 }
591
592 newobject_id = ChooseIDFromTable(containers);
593 if (newobject_id.GetLength()) {
594 m_CurBrowseDirectoryStack.Push(newobject_id);
595 }
596
597 m_MostRecentBrowseResults = NULL;
598 }
599 }
600
601 /*----------------------------------------------------------------------
602 | PLT_MicroMediaController::HandleCmd_cdup
603 +---------------------------------------------------------------------*/
604 void
HandleCmd_cdup()605 PLT_MicroMediaController::HandleCmd_cdup()
606 {
607 // we don't want to pop the root off now....
608 NPT_String val;
609 m_CurBrowseDirectoryStack.Peek(val);
610 if (val.Compare("0")) {
611 m_CurBrowseDirectoryStack.Pop(val);
612 } else {
613 printf("Already at root\n");
614 }
615 }
616
617 /*----------------------------------------------------------------------
618 | PLT_MicroMediaController::HandleCmd_pwd
619 +---------------------------------------------------------------------*/
620 void
HandleCmd_pwd()621 PLT_MicroMediaController::HandleCmd_pwd()
622 {
623 NPT_Stack<NPT_String> tempStack;
624 NPT_String val;
625
626 while (NPT_SUCCEEDED(m_CurBrowseDirectoryStack.Peek(val))) {
627 m_CurBrowseDirectoryStack.Pop(val);
628 tempStack.Push(val);
629 }
630
631 while (NPT_SUCCEEDED(tempStack.Peek(val))) {
632 tempStack.Pop(val);
633 printf("%s/", (const char*)val);
634 m_CurBrowseDirectoryStack.Push(val);
635 }
636 printf("\n");
637 }
638
639 /*----------------------------------------------------------------------
640 | PLT_MicroMediaController::HandleCmd_open
641 +---------------------------------------------------------------------*/
642 void
HandleCmd_open()643 PLT_MicroMediaController::HandleCmd_open()
644 {
645 NPT_String object_id;
646 PLT_StringMap tracks;
647 PLT_DeviceDataReference device;
648
649 GetCurMediaRenderer(device);
650 if (!device.IsNull()) {
651 // get the protocol info to try to see in advance if a track would play on the device
652
653 // issue a browse
654 DoBrowse();
655
656 if (!m_MostRecentBrowseResults.IsNull()) {
657 // create a map item id -> item title
658 NPT_List<PLT_MediaObject*>::Iterator item = m_MostRecentBrowseResults->GetFirstItem();
659 while (item) {
660 if (!(*item)->IsContainer()) {
661 tracks.Put((*item)->m_ObjectID, (*item)->m_Title);
662 }
663 ++item;
664 }
665
666 // let the user choose which one
667 object_id = ChooseIDFromTable(tracks);
668 if (object_id.GetLength()) {
669 // look back for the PLT_MediaItem in the results
670 PLT_MediaObject* track = NULL;
671 if (NPT_SUCCEEDED(NPT_ContainerFind(*m_MostRecentBrowseResults, PLT_MediaItemIDFinder(object_id), track))) {
672 if (track->m_Resources.GetItemCount() > 0) {
673 // look for best resource to use by matching each resource to a sink advertised by renderer
674 NPT_Cardinal resource_index = 0;
675 if (NPT_FAILED(FindBestResource(device, *track, resource_index))) {
676 printf("No matching resource\n");
677 return;
678 }
679
680 // invoke the setUri
681 printf("Issuing SetAVTransportURI with url=%s & didl=%s",
682 (const char*)track->m_Resources[resource_index].m_Uri,
683 (const char*)track->m_Didl);
684 SetAVTransportURI(device, 0, track->m_Resources[resource_index].m_Uri, track->m_Didl, NULL);
685 } else {
686 printf("Couldn't find the proper resource\n");
687 }
688
689 } else {
690 printf("Couldn't find the track\n");
691 }
692 }
693
694 m_MostRecentBrowseResults = NULL;
695 }
696 }
697 }
698
699 /*----------------------------------------------------------------------
700 | PLT_MicroMediaController::HandleCmd_play
701 +---------------------------------------------------------------------*/
702 void
HandleCmd_play()703 PLT_MicroMediaController::HandleCmd_play()
704 {
705 PLT_DeviceDataReference device;
706 GetCurMediaRenderer(device);
707 if (!device.IsNull()) {
708 Play(device, 0, "1", NULL);
709 }
710 }
711
712 /*----------------------------------------------------------------------
713 | PLT_MicroMediaController::HandleCmd_seek
714 +---------------------------------------------------------------------*/
715 void
HandleCmd_seek(const char * command)716 PLT_MicroMediaController::HandleCmd_seek(const char* command)
717 {
718 PLT_DeviceDataReference device;
719 GetCurMediaRenderer(device);
720 if (!device.IsNull()) {
721 // remove first part of command ("seek")
722 NPT_String target = command;
723 NPT_List<NPT_String> args = target.Split(" ");
724 if (args.GetItemCount() < 2) return;
725
726 args.Erase(args.GetFirstItem());
727 target = NPT_String::Join(args, " ");
728
729 Seek(device, 0, (target.Find(":")!=-1)?"REL_TIME":"X_DLNA_REL_BYTE", target, NULL);
730 }
731 }
732
733 /*----------------------------------------------------------------------
734 | PLT_MicroMediaController::HandleCmd_stop
735 +---------------------------------------------------------------------*/
736 void
HandleCmd_stop()737 PLT_MicroMediaController::HandleCmd_stop()
738 {
739 PLT_DeviceDataReference device;
740 GetCurMediaRenderer(device);
741 if (!device.IsNull()) {
742 Stop(device, 0, NULL);
743 }
744 }
745
746 /*----------------------------------------------------------------------
747 | PLT_MicroMediaController::HandleCmd_mute
748 +---------------------------------------------------------------------*/
749 void
HandleCmd_mute()750 PLT_MicroMediaController::HandleCmd_mute()
751 {
752 PLT_DeviceDataReference device;
753 GetCurMediaRenderer(device);
754 if (!device.IsNull()) {
755 SetMute(device, 0, "Master", true, NULL);
756 }
757 }
758
759 /*----------------------------------------------------------------------
760 | PLT_MicroMediaController::HandleCmd_unmute
761 +---------------------------------------------------------------------*/
762 void
HandleCmd_unmute()763 PLT_MicroMediaController::HandleCmd_unmute()
764 {
765 PLT_DeviceDataReference device;
766 GetCurMediaRenderer(device);
767 if (!device.IsNull()) {
768 SetMute(device, 0, "Master", false, NULL);
769 }
770 }
771
772 /*----------------------------------------------------------------------
773 | PLT_MicroMediaController::HandleCmd_help
774 +---------------------------------------------------------------------*/
775 void
HandleCmd_help()776 PLT_MicroMediaController::HandleCmd_help()
777 {
778 printf("\n\nNone of the commands take arguments. The commands with a * \n");
779 printf("signify ones that will prompt the user for more information once\n");
780 printf("the command is called\n\n");
781 printf("The available commands are:\n\n");
782 printf(" quit - shutdown the Control Point\n");
783 printf(" exit - same as quit\n");
784
785 printf(" setms - * select a media server to become the active media server\n");
786 printf(" getms - print the friendly name of the active media server\n");
787 printf(" ls - list the contents of the current directory on the active \n");
788 printf(" media server\n");
789 printf(" info - display media info\n");
790 printf(" down - download media to current directory\n");
791 printf(" cd - * traverse down one level in the content tree on the active\n");
792 printf(" media server\n");
793 printf(" cd .. - traverse up one level in the content tree on the active\n");
794 printf(" media server\n");
795 printf(" pwd - print the path from the root to your current position in the \n");
796 printf(" content tree on the active media server\n");
797 printf(" setmr - * select a media renderer to become the active media renderer\n");
798 printf(" getmr - print the friendly name of the active media renderer\n");
799 printf(" open - set the uri on the active media renderer\n");
800 printf(" play - play the active uri on the active media renderer\n");
801 printf(" stop - stop the active uri on the active media renderer\n");
802 printf(" seek - issue a seek command\n");
803 printf(" mute - mute the active media renderer\n");
804 printf(" unmute - unmute the active media renderer\n");
805
806 printf(" help - print this help message\n\n");
807 }
808
809 /*----------------------------------------------------------------------
810 | PLT_MicroMediaController::ProcessCommandLoop
811 +---------------------------------------------------------------------*/
812 void
ProcessCommandLoop()813 PLT_MicroMediaController::ProcessCommandLoop()
814 {
815 char command[2048];
816 bool abort = false;
817
818 command[0] = '\0';
819 while (!abort) {
820 printf("command> ");
821 fflush(stdout);
822 fgets(command, 2048, stdin);
823 strchomp(command);
824
825 if (0 == strcmp(command, "quit") || 0 == strcmp(command, "exit")) {
826 abort = true;
827 } else if (0 == strcmp(command, "setms")) {
828 HandleCmd_setms();
829 } else if (0 == strcmp(command, "getms")) {
830 HandleCmd_getms();
831 } else if (0 == strncmp(command, "ls", 2)) {
832 HandleCmd_ls();
833 } else if (0 == strcmp(command, "info")) {
834 HandleCmd_info();
835 } else if (0 == strcmp(command, "down")) {
836 HandleCmd_download();
837 } else if (0 == strcmp(command, "cd")) {
838 HandleCmd_cd(command);
839 } else if (0 == strcmp(command, "cd ..")) {
840 HandleCmd_cdup();
841 } else if (0 == strcmp(command, "pwd")) {
842 HandleCmd_pwd();
843 } else if (0 == strcmp(command, "setmr")) {
844 HandleCmd_setmr();
845 } else if (0 == strcmp(command, "getmr")) {
846 HandleCmd_getmr();
847 } else if (0 == strcmp(command, "open")) {
848 HandleCmd_open();
849 } else if (0 == strcmp(command, "play")) {
850 HandleCmd_play();
851 } else if (0 == strcmp(command, "stop")) {
852 HandleCmd_stop();
853 } else if (0 == strncmp(command, "seek", 4)) {
854 HandleCmd_seek(command);
855 } else if (0 == strcmp(command, "mute")) {
856 HandleCmd_mute();
857 } else if (0 == strcmp(command, "unmute")) {
858 HandleCmd_mute();
859 } else if (0 == strcmp(command, "help")) {
860 HandleCmd_help();
861 } else if (0 == strcmp(command, "")) {
862 // just prompt again
863 } else {
864 printf("Unrecognized command: %s\n", command);
865 HandleCmd_help();
866 }
867 }
868 }
869
870