001/* 002 * $Rev: 1393 $: Revision of last commit 003 * $Author: tgutwin $: Author of last commit 004 * $Date: 2020-10-10 19:22:00 -0700 (Sat, 10 Oct 2020) $: Date of last commit 005 * $URL: svn://fred.webarts.bc.ca/open/trunk/projects/WebARTS/ca/bc/webarts/tools/sockets/PirateTunesClientThread.java $ 006 */ 007/* 008 * 009 * Written by Tom Gutwin - WebARTS Design. 010 * Copyright (C) 2020 WebARTS Design, North Vancouver Canada 011 * http://www.webarts.bc.ca 012 * 013 * This program is free software; you can redistribute it and/or modify 014 * it under the terms of the GNU General Public License as published by 015 * the Free Software Foundation; either version 2 of the License, or 016 * (at your option) any later version. 017 * 018 * This program is distributed in the hope that it will be useful, 019 * but WITHOUT ANY WARRANTY; without_ even the implied warranty of 020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 021 * GNU General Public License for more details. 022 * 023 * You should have received a copy of the GNU General Public License 024 * along with this program; if not, write to the Free Software 025 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 026 */ 027 028package ca.bc.webarts.tools.sockets; 029 030import java.io.BufferedReader; 031import java.io.DataInputStream; 032import java.io.InputStreamReader; 033import java.io.PrintStream; 034import java.io.IOException; 035import java.net.Socket; 036import java.util.Arrays; 037import java.util.ArrayList; 038import java.util.Collections; 039import java.util.List; 040import java.util.Vector; 041 042import ca.bc.webarts.JOggPlayerListener; 043 044 045/** The ClientThread extension used by the {@link JOggPlayerSocketServer JOggPlayerSocketServer} ({@link TCPSocketServer TCPSocketServer}) to 046 * deal with playing tunes through the Pi PirateAudio shield. Each time a SocketConnection comes in, this client Thread is spawned to handle the request. 047 * It does all the Vorbis Ogg playing using the {@link ca.bc.webarts.JOggPlayerListener JOggPlayerListener} class. 048 * 049 **/ 050public class PirateTunesClientThread extends ClientThread 051{ 052 /** The root dir for all ogg content with Artist/Album subDirs. 053 * It gets pre-pended to ALL commadparms that represent tunes. 054 **/ 055 protected String piSndOggRootDir_ = "/mnt/nas/snd/ogg"; 056 057 /** DEPRECATED flag to use ogg123. **/ 058 @Deprecated 059 protected boolean useOgg123_ = false; 060 061 /** Class instance to the JOggPlayer. **/ 062 protected JOggPlayerListener player_ = JOggPlayerListener.getInstance(); 063 Thread playerThread_ = new Thread(player_, "JOggPlayerListener");; 064 Thread looperThread_ = null; 065 long currentPlayerThreadId_ = 0; 066 /** Any responses (if any) to send back to client. **/ 067 Vector <String> responses_ = new Vector <String> (); 068 /** Flags if the command will send a response. **/ 069 boolean responseExpected_ = false; 070 071 072 /** Contstructor that accepts the clientSocket to grab data /command from. 073 * 074 * @param clientSocket the clientSocket to grab data /command from 075 **/ 076 public PirateTunesClientThread(Socket clientSocket) 077 { 078 super(clientSocket); 079 debug_=2; // 0 is silent, 1 is error only; 2 is basic info, 3 is verbose, 4 is all 080 } 081 082 083 /** Pass the already instantiated JOggPlayerListener to this class. **/ 084 @Deprecated 085 public int setPlayer(ca.bc.webarts.JOggPlayerListener player) 086 { 087 int retVal = 1; 088 player_ = player; 089 playerThread_ = new Thread(player_, "JOggPlayerListener"); 090 091 return retVal; 092 } 093 094 095 /** DEPRECATED method to play tunes using ogg123. 096 * 097 * @param cmdArgs the command requests received over the socket 098 **/ 099 @Deprecated 100 protected int runWithOgg123(String[] cmdArgs) 101 { 102 int retVal = 1; 103 java.util.List<String> results = null; 104 int exitCode = 0; 105 106 String killer = "/usr/bin/killer"; 107 String ogg123 = "/usr/bin/ogg123"; 108 String ogginfo = "/usr/bin/ogginfo"; 109 110 List <String> stopCmdList = Collections.synchronizedList(new <String> ArrayList()); //Arrays.asList(cmdArgs); 111 stopCmdList.add(killer); 112 stopCmdList.add(ogg123); 113 114 List <String> cmdList = Collections.synchronizedList(new <String> ArrayList()); //Arrays.asList(cmdArgs); 115 cmdList.add(ogg123); 116 117 boolean stopCommand = false; 118 boolean validCommand = true; 119 120 String piTunePath = ""; 121 if(!"stop".equalsIgnoreCase(cmdArgs[0])) piTunePath = piSndOggRootDir_+"/"+cmdArgs[1]; 122 switch (cmdArgs[0]) 123 { 124 case "tune" : // tune songNamePath 125 cmdList.add("-q"); 126 cmdList.add(piTunePath); 127 break; 128 129 case "tunes" : // tunes dirNamePath 130 cmdList.add("-q"); 131 cmdList.add(piTunePath); 132 break; 133 134 case "shuffletunes" : // shuffleTunes dirNamePath 135 case "shuffleTunes" : // shuffleTunes dirNamePath 136 cmdList.add("-q"); 137 cmdList.add("-z"); 138 cmdList.add(piTunePath); 139 break; 140 141 case "repeatshuffletunes" : // shuffleTunes dirNamePath 142 case "repeatShuffleTunes" : // shuffleTunes dirNamePath 143 cmdList.add("-q"); 144 cmdList.add("-Z"); 145 cmdList.add(piTunePath); 146 break; 147 148 case "stop" : 149 stopCommand= true; 150 break; 151 152 default: 153 validCommand = false; 154 } 155 156 /* Execute the request. */ 157 if(validCommand) 158 { 159 synchronized (this) 160 { 161 162 // send a native command 163 if (debug_>1) System.out.print("Executing an audio command..."); 164 java.lang.Process procRet = null; 165 try 166 { 167 // ALWAYS Call a STOP first 168 java.lang.ProcessBuilder pb = new java.lang.ProcessBuilder(stopCmdList); 169 pb.directory(new java.io.File(piSndOggRootDir_)); //TEMP_DIR)); 170 procRet = pb.start(); 171 exitCode = procRet.waitFor(); 172 173 if(!stopCommand) 174 { 175 // Now the real command 176 pb = new java.lang.ProcessBuilder(cmdList); 177 procRet = pb.start(); 178 os.println("..."); 179 if (debug_>1) System.out.println(" !!"); 180 results = readOutput(procRet.getInputStream()); 181 exitCode = procRet.waitFor(); 182 } 183 } 184 catch (Exception ex) 185 { 186 ex.printStackTrace(); 187 procRet = null; 188 } 189 if(procRet!=null && procRet.exitValue()==0) 190 { 191 os.println(TCPSocketServer.SUCCESS); 192 if(results!=null) for(String s : results) os.println(s); 193 } 194 else 195 os.println(TCPSocketServer.ERROR); 196 197 os.println(TCPSocketServer.END); 198 199 } 200 retVal = 0; 201 } 202 else if (debug_>0) System.out.println(" INValid Command: "+cmdArgs[0]); 203 if (debug_>1) System.out.println(" >Closing ClientThread: "+ Thread.currentThread().getId()); 204 205 return retVal; 206 } 207 208 209 /** The primary method that parses the commad params and handles them by sending appropriate signals to JOggPlayerListener. 210 * 211 * @param cmdArgs the command requests received over the socket 212 **/ 213 protected int runWithJOggPlayer(String[] cmdArgs) 214 { 215 int retVal = 1; 216 player_ = JOggPlayerListener.getInstance(); 217 218 List <String> cmdList = Collections.synchronizedList(new <String> ArrayList()); //Arrays.asList(cmdArgs); 219 220 String piTunePath = ""; 221 if("tune".equalsIgnoreCase(cmdArgs[0]) || 222 "tunes".equalsIgnoreCase(cmdArgs[0])) 223 { 224 //this one always starts FRESHand Clean 225 player_.clearPlaylist(); 226 player_.clearStopSignal(); 227 228 piTunePath = piSndOggRootDir_+"/"+cmdArgs[1]; 229 if (cmdArgs.length >1) 230 { 231 for (int i = 1; i < cmdArgs.length; i++) 232 { 233 piTunePath = piSndOggRootDir_+"/"+cmdArgs[i]; 234 player_.addToPlaylist(piTunePath); 235 } 236 237 player_.signalStopPlay(); // needed to ensure ungarbled start to the songs 238 ca.bc.webarts.widgets.Util.sleep(200); // needed to ensure ungarbled start to the songs 239 240 // START Playing 241 player_.play_sound(); 242 currentPlayerThreadId_ = playerThread_.getId(); 243 retVal = 0; 244 } 245 } 246 else if("tunesDir".equalsIgnoreCase(cmdArgs[0]) || 247 "album".equalsIgnoreCase(cmdArgs[0])|| 248 "artist".equalsIgnoreCase(cmdArgs[0])) 249 { 250 //this one always starts FRESHand Clean 251 player_.clearPlaylist(); 252 player_.clearStopSignal(); 253 254 piTunePath = piSndOggRootDir_+"/"+cmdArgs[1]; 255 if (cmdArgs.length >1) 256 { 257 String [] piTunePaths = new String [ cmdArgs.length-1]; 258 for (int i = 1; i < cmdArgs.length; i++) 259 { 260 piTunePaths[i-1] = piSndOggRootDir_+"/"+cmdArgs[i]; 261 } 262 player_.addDirFilesToPlaylist(piTunePaths, true); 263 264 player_.signalStopPlay(); // needed to ensure ungarbled start to the songs 265 ca.bc.webarts.widgets.Util.sleep(200); // needed to ensure ungarbled start to the songs 266 267 // START Playing 268 player_.play_sound(); 269 currentPlayerThreadId_ = playerThread_.getId(); 270 retVal = 0; 271 } 272 } 273 274 /* add Add a single item */ 275 else if("add".equalsIgnoreCase(cmdArgs[0])) 276 { 277 piTunePath = piSndOggRootDir_+"/"+cmdArgs[1]; 278 if (cmdArgs.length >1) 279 { 280 String [] piTunePaths = new String [ cmdArgs.length-1]; 281 for (int i = 1; i < cmdArgs.length; i++) 282 { 283 piTunePaths[i-1] = piSndOggRootDir_+"/"+cmdArgs[i]; 284 piTunePath = piSndOggRootDir_+"/"+cmdArgs[i]; 285 player_.addToPlaylist(piTunePath); 286 } 287 //player_.addToPlaylist(piTunePath); 288 289 //player_.play_sound(); 290 currentPlayerThreadId_ = playerThread_.getId(); 291 retVal = 0; 292 } 293 } 294 295 /* addDir Adds all songs recursively */ 296 else if("addDir".equalsIgnoreCase(cmdArgs[0])) 297 { 298 piTunePath = piSndOggRootDir_+"/"+cmdArgs[1]; 299 if (cmdArgs.length >1) 300 { 301 String [] piTunePaths = new String [ cmdArgs.length-1]; 302 for (int i = 1; i < cmdArgs.length; i++) 303 { 304 piTunePaths[i-1] = piSndOggRootDir_+"/"+cmdArgs[i]; 305 } 306 player_.addDirFilesToPlaylist(piTunePaths, true); 307 308 //player_.play_sound(); 309 currentPlayerThreadId_ = playerThread_.getId(); 310 retVal = 0; 311 } 312 } 313 else if("playNum".equalsIgnoreCase(cmdArgs[0])) 314 { 315 if (cmdArgs.length >1) 316 { 317 try 318 { 319 int pNum = Integer.parseInt(cmdArgs[1]); 320 if(true || !player_.isStopped()) 321 { 322 player_.signalStopPlay(); 323 ca.bc.webarts.widgets.Util.sleep(200); 324 } 325 player_.play_sound(pNum); 326 currentPlayerThreadId_ = playerThread_.getId(); 327 retVal = 0; 328 } 329 catch(Exception ex) 330 { 331 if (debug_>0) System.out.println(" playNum requires an int as a second parameter:\n"+cmdArgs[1]+ "\n is NOT an int"); 332 } 333 } 334 else 335 if (debug_>0) System.out.println(" playNum requires an int as a second parameter"); 336 } 337 else if("clearPlaylist".equalsIgnoreCase(cmdArgs[0])) 338 { 339 player_.clearPlaylist(); 340 currentPlayerThreadId_ = playerThread_.getId(); 341 retVal = 0; 342 } 343 else if("getShuffling".equalsIgnoreCase(cmdArgs[0])) 344 { 345 responseExpected_ = true; 346 responses_.add(""+player_.getShuffling()); 347 currentPlayerThreadId_ = playerThread_.getId(); 348 retVal = 0; 349 } 350 else if("shufflePlay".equalsIgnoreCase(cmdArgs[0])) 351 { 352 if (debug_>1) System.out.print("\n >> ** PirateTunes shufflePlay linearPlay Request "); 353 player_.setShuffling(true); 354 currentPlayerThreadId_ = playerThread_.getId(); 355 responseExpected_ = true; 356 ca.bc.webarts.widgets.Util.sleep(200); 357 responses_.add("shuffle"); 358 retVal = 0; 359 } 360 else if("linearPlay".equalsIgnoreCase(cmdArgs[0])) 361 { 362 if (debug_>1) System.out.print("\n >> **PirateTunes linearPlay Request "); 363 player_.setShuffling(false); 364 currentPlayerThreadId_ = playerThread_.getId(); 365 responseExpected_ = true; 366 ca.bc.webarts.widgets.Util.sleep(200); 367 responses_.add("linear"); 368 retVal = 0; 369 } 370 else if("next".equalsIgnoreCase(cmdArgs[0])) 371 { 372 player_.signalNextInPlaylist(); 373 currentPlayerThreadId_ = playerThread_.getId(); 374 responseExpected_ = true; 375 ca.bc.webarts.widgets.Util.sleep(200); 376 responses_.add(player_.getTitle()); 377 retVal = 0; 378 } 379 else if("play".equalsIgnoreCase(cmdArgs[0])) 380 { 381 if(!player_.isStopped()) 382 { 383 player_.signalStopPlay(); 384 ca.bc.webarts.widgets.Util.sleep(200); 385 } 386 player_.play_current_sound(); 387 currentPlayerThreadId_ = playerThread_.getId(); 388 retVal = 0; 389 } 390 else if( "pause".equalsIgnoreCase(cmdArgs[0])|| 391 "unpause".equalsIgnoreCase(cmdArgs[0])|| 392 "togglepause".equalsIgnoreCase(cmdArgs[0])) 393 { 394 player_.signalLoopPaused(); 395 currentPlayerThreadId_ = playerThread_.getId(); 396 retVal = 0; 397 } 398 else if("previous".equalsIgnoreCase(cmdArgs[0]) || 399 "prev".equalsIgnoreCase(cmdArgs[0])) 400 { 401 player_.signalPreviousInPlaylist(); 402 currentPlayerThreadId_ = playerThread_.getId(); 403 responseExpected_ = true; 404 ca.bc.webarts.widgets.Util.sleep(200); 405 responses_.add(player_.getTitle()); 406 retVal = 0; 407 } 408 else if("stop".equalsIgnoreCase(cmdArgs[0])) 409 { 410 if (debug_>1) System.out.println(" threadID="+currentPlayerThreadId_+ " Stopping the current song..."); 411 player_.signalStopPlay(); 412 retVal = 0; 413 } 414 else if("getCurrentPlaylistIndex".equalsIgnoreCase(cmdArgs[0])) 415 { 416 responseExpected_ = true; 417 responses_.add(""+player_.getCurrentPlaylistIndex()); 418 currentPlayerThreadId_ = playerThread_.getId(); 419 retVal = 0; 420 } 421 else if("getPlaylistSize".equalsIgnoreCase(cmdArgs[0])) 422 { 423 responseExpected_ = true; 424 responses_.add(""+player_.getPlaylistSize()); 425 currentPlayerThreadId_ = playerThread_.getId(); 426 retVal = 0; 427 } 428 else if("getTitle".equalsIgnoreCase(cmdArgs[0])) 429 { 430 responseExpected_ = true; 431 responses_.add(player_.getTitle()); 432 currentPlayerThreadId_ = playerThread_.getId(); 433 retVal = 0; 434 } 435 else if("getFilename".equalsIgnoreCase(cmdArgs[0])) 436 { 437 responseExpected_ = true; 438 responses_.add(player_.getFilename()); 439 currentPlayerThreadId_ = playerThread_.getId(); 440 retVal = 0; 441 } 442 else if("getAlbumCoverURL".equalsIgnoreCase(cmdArgs[0])) 443 { 444 responseExpected_ = true; 445 responses_.add(player_.getAlbumCoverURL()); 446 currentPlayerThreadId_ = playerThread_.getId(); 447 retVal = 0; 448 } 449 else if("getArtistName".equalsIgnoreCase(cmdArgs[0])) 450 { 451 responseExpected_ = true; 452 responses_.add(player_.getArtistName()); 453 currentPlayerThreadId_ = playerThread_.getId(); 454 retVal = 0; 455 } 456 else if("getAlbumName".equalsIgnoreCase(cmdArgs[0])) 457 { 458 responseExpected_ = true; 459 responses_.add(player_.getAlbumName()); 460 currentPlayerThreadId_ = playerThread_.getId(); 461 retVal = 0; 462 } 463 else if("getSongName".equalsIgnoreCase(cmdArgs[0])) 464 { 465 responseExpected_ = true; 466 responses_.add(player_.getSongName() ); 467 currentPlayerThreadId_ = playerThread_.getId(); 468 retVal = 0; 469 } 470 else if("getSongComments".equalsIgnoreCase(cmdArgs[0])) 471 { 472 responseExpected_ = true; 473 responses_.addAll(player_.getSongComments() ); 474 currentPlayerThreadId_ = playerThread_.getId(); 475 retVal = 0; 476 } 477 else if("getAlbumTrackNum".equalsIgnoreCase(cmdArgs[0])) 478 { 479 responseExpected_ = true; 480 String numStr = "??"; 481 int pNum = player_.getAlbumTrackNum(); 482 if(pNum>0) numStr = ""+pNum; 483 responses_.add(numStr); 484 currentPlayerThreadId_ = playerThread_.getId(); 485 retVal = 0; 486 } 487 else if("getSongDuration".equalsIgnoreCase(cmdArgs[0])) 488 { 489 responseExpected_ = true; 490 String numStr = "??"; 491 int pNum = player_.retrieveSongDurationInMiliSeconds(); 492 if(pNum>0) numStr = ""+pNum; 493 responses_.add(numStr); 494 currentPlayerThreadId_ = playerThread_.getId(); 495 retVal = 0; 496 } 497 else if("getSongTimePlaying".equalsIgnoreCase(cmdArgs[0])) 498 { 499 responseExpected_ = true; 500 String numStr = "??"; 501 int pNum = player_.retrieveCurrentTunePlayTimeInMiliSeconds(); 502 if(pNum>0) numStr = ""+pNum; 503 responses_.add(numStr); 504 currentPlayerThreadId_ = playerThread_.getId(); 505 retVal = 0; 506 } 507 else if("getSongProgress".equalsIgnoreCase(cmdArgs[0])) 508 { 509 responseExpected_ = true; 510 String numStr = "??"; 511 int pNum = player_.retrieveTuneProgressRatio(); 512 if(pNum>0) numStr = ""+pNum; 513 responses_.add(numStr); 514 currentPlayerThreadId_ = playerThread_.getId(); 515 retVal = 0; 516 } 517 else if("getIndexedPlaylist".equalsIgnoreCase(cmdArgs[0])) 518 { 519 responseExpected_ = true; 520 responses_.addAll(player_.getIndexedPlaylistArtistAlbumSongnames(true)); 521 //for (int i=0; i< player_.getPlaylistSize();i++) 522 // responses_.add(i+" : "+player_.playlist_.get(i)); 523 currentPlayerThreadId_ = playerThread_.getId(); 524 retVal = 0; 525 } 526 else if("getPlaylist".equalsIgnoreCase(cmdArgs[0])) 527 { 528 responseExpected_ = true; 529 responses_.addAll(player_.getIndexedPlaylistArtistAlbumSongnames(false)); 530 //for (int i=0; i< player_.getPlaylistSize();i++) 531 // responses_.add(i+" : "+player_.playlist_.get(i)); 532 currentPlayerThreadId_ = playerThread_.getId(); 533 retVal = 0; 534 } 535 else if("isStopped".equalsIgnoreCase(cmdArgs[0])) 536 { 537 responseExpected_ = true; 538 String numStr = "??"; 539 boolean bVal = player_.isStopped(); 540 responses_.add(""+bVal); 541 currentPlayerThreadId_ = playerThread_.getId(); 542 retVal = 0; 543 } 544 else if("isSongPlaying".equalsIgnoreCase(cmdArgs[0])) 545 { 546 responseExpected_ = true; 547 String numStr = "??"; 548 boolean bVal = player_.isPlaying(); 549 responses_.add(""+bVal); 550 currentPlayerThreadId_ = playerThread_.getId(); 551 retVal = 0; 552 } 553 else if("isSongPaused".equalsIgnoreCase(cmdArgs[0])) 554 { 555 responseExpected_ = true; 556 String numStr = "??"; 557 boolean bVal = player_.isPaused(); 558 responses_.add(""+bVal); 559 currentPlayerThreadId_ = playerThread_.getId(); 560 retVal = 0; 561 } 562 else 563 { 564 if (debug_>0) System.out.println(" > PirateTunesClientThread.runWithJOggPlayer\n need a valid command [ commandList, stop, pause, resume... ]"); 565 responseExpected_ = true; 566 responses_.add(" > PirateTunesClientThread.runWithJOggPlayer\n "+cmdArgs[0]+"\n need a valid command [ commandList, stop, pause, resume... ]"); 567 currentPlayerThreadId_ = playerThread_.getId(); 568 retVal = 1; 569 } 570 571 return retVal; 572 } 573 574 575 /** The Overriden thread execution method. **/ 576 @Override 577 public void run() 578 { 579 String TEMP_DIR = System.getProperty("java.io.tmpdir"); 580 Thread me = Thread.currentThread(); 581 int retVal = 0; 582 try 583 { 584 /* 585 * Create input and output streams for this client. 586 */ 587 if (debug_>2) System.out.println(" >Starting PirateTunesClientThread: "+ me.getId()); 588 589 is = new DataInputStream(clientSocket.getInputStream()); // this uses a deprecated readline API, hence the BufferedReader 590 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 591 os = new PrintStream(clientSocket.getOutputStream()); //used to send responses 592 String clientRequest = ""; 593 594 //os.println("?"); 595 clientRequest = bufferedReader.readLine().trim(); // is.readLine().trim(); 596 if (debug_>1) System.out.print("\nNEW\n > PirateTunesClientRequest: "); 597 String[] cmdArgs = clientRequest.split("\\s"); 598 if (debug_>1) System.out.println(Arrays.toString(cmdArgs)); 599 600 if(cmdArgs!=null && cmdArgs.length>0 ) //&& !"stop".equalsIgnoreCase(cmdArgs[0])) 601 { 602 // 1st check for non-JOggPlayer requests 603 if("commandList".equalsIgnoreCase(cmdArgs[0])) 604 { 605 responseExpected_ = true; 606 responses_.addAll(getCommandList()); //addAll(Collection<? extends E> c) 607 currentPlayerThreadId_ = playerThread_.getId(); 608 } 609 else if(useOgg123_) 610 { 611 retVal = runWithOgg123(cmdArgs); 612 } 613 else 614 { 615 if (debug_>1) System.out.print(" > PirateTunesClientRequest passing control to JOggPlayer "); 616 retVal = runWithJOggPlayer(cmdArgs); 617 } 618 } 619 620 /* Check if response */ 621 if(responseExpected_) 622 { 623 if(os!=null ) 624 { 625 if(retVal==0) 626 { 627 os.println(TCPSocketServer.SUCCESS); 628 } 629 else 630 { 631 os.println(TCPSocketServer.ERROR); 632 } 633 if(responses_.size()>0) 634 for(String s : responses_ ) os.println(s); 635 636 os.println(TCPSocketServer.END); 637 638 } 639 } 640 641 if (debug_>2) System.out.println("\n > PirateTunesClientThread: "+ me.getId()+" CLEANUP"); 642 //while(!player_.isStopped()) 643 ca.bc.webarts.widgets.Util.sleep(1000); 644 /* 645 * Close the output stream, close the input stream, close the socket. 646 */ 647 is.close(); 648 os.close(); 649 clientSocket.close(); 650 playerThread_ = null; 651 player_=null; 652 } 653 catch (IOException e) 654 { 655 if (debug_>0) System.out.println(" IOException PirateTunesClientThread: "+ e.getMessage()); 656 657 } 658 if (debug_>2) System.out.println("\n <EXITING PirateTunesClientThread: "+ me.getId()); 659 } 660 661 662 public static Vector<String> getCommandList() 663 { 664 Vector<String> retVal = new Vector<String>(); 665 String[] cmds = { 666 "tune", 667 "tunes", 668 "tunesDir", 669 "album", 670 "artist", 671 "playNum", 672 "clearPlaylist", 673 "next", 674 "pause", 675 "previous", 676 "prev", 677 "play", 678 "stop", 679 "add", 680 "addDir", 681 "artistAlbumsList", 682 "getTitle", 683 "getAlbumCoverURL", 684 "getFilename", 685 "getArtistName", 686 "getAlbumName", 687 "getSongName", 688 "getAlbumTrackNum", 689 "getCurrentPlaylistIndex", 690 "getPlaylistSize", 691 "getPlaylist", 692 "getIndexedPlaylist", 693 "getSongComments", 694 "getSongDuration", 695 "getSongTimePlaying", 696 "getSongProgress", 697 "getPlaylist", 698 "isStopped", 699 "isSongPlaying", 700 "isSongPaused", 701 "shufflePlay", 702 "linearPlay", 703 "getShuffling", 704 "commandList" 705 }; 706 for(int i=0; i<cmds.length;i++) retVal.add(cmds[i]); 707 return retVal; 708 } 709 710 711 public static Vector<String> getCommandWithNoOptionsList() 712 { 713 Vector<String> retVal = new Vector<String>(); 714 String[] cmds = { 715 "clearPlaylist", 716 "next", 717 "pause", 718 "previous", 719 "prev", 720 "play", 721 "stop", 722 "artistAlbumsList", 723 "getTitle", 724 "getAlbumCoverURL", 725 "getFilename", 726 "getArtistName", 727 "getAlbumName", 728 "getSongName", 729 "getAlbumTrackNum", 730 "getCurrentPlaylistIndex", 731 "getPlaylistSize", 732 "getPlaylist", 733 "getIndexedPlaylist", 734 "getSongComments", 735 "getSongDuration", 736 "getSongTimePlaying", 737 "getSongProgress", 738 "getPlaylist", 739 "isStopped", 740 "isSongPlaying", 741 "isSongPaused", 742 "shufflePlay", 743 "linearPlay", 744 "getShuffling", 745 "commandList" 746 }; 747 for(int i=0; i<cmds.length;i++) retVal.add(cmds[i]); 748 return retVal; 749 } 750}