00001 package i2bpro.playlist;
00002
00003 import i2bpro.layer.Dialogs.AlbumAuswahlDlg;
00004 import i2bpro.Exceptions.PlayListException;
00005 import i2bpro.layer.Dialogs.Utils;
00006 import i2bpro.layer.InfoMsg;
00007 import i2bpro.layer.Layer;
00008 import java.awt.Cursor;
00009 import java.io.BufferedReader;
00010 import java.io.File;
00011 import java.io.FileNotFoundException;
00012 import java.io.IOException;
00013 import java.io.InputStreamReader;
00014 import java.net.HttpURLConnection;
00015 import java.net.InetSocketAddress;
00016 import java.net.MalformedURLException;
00017 import java.net.Proxy;
00018 import java.net.SocketAddress;
00019 import java.net.URL;
00020 import java.net.UnknownHostException;
00021 import java.util.HashMap;
00022 import java.util.Scanner;
00023 import java.util.regex.Matcher;
00024 import java.util.regex.Pattern;
00025 import javax.media.ControllerEvent;
00026 import javax.media.Manager;
00027 import javax.media.NoPlayerException;
00028 import javax.media.PrefetchCompleteEvent;
00029 import javax.swing.table.AbstractTableModel;
00030 import org.jaudiotagger.audio.AudioFile;
00031 import org.jaudiotagger.audio.AudioFileIO;
00032 import org.jaudiotagger.audio.exceptions.CannotReadException;
00033 import org.jaudiotagger.audio.exceptions.CannotWriteException;
00034 import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
00035 import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
00036 import org.jaudiotagger.tag.TagException;
00037
00038
00039
00060 public final class PlayList extends AbstractTableModel
00061 {
00062
00063 private static final PlayList instance = new PlayList();
00064
00065
00066
00067 private String playlisttype = null;
00068
00069
00070 private HashMap<Integer, HashMap<String, String>> playlist
00071 = new HashMap<Integer, HashMap<String, String>>();
00072
00073 private M3U m3u = null;
00074 private CUE cue = null;
00075
00076
00077
00078 private String filename = null;
00079
00080
00081 private HashMap<Integer, String> keys = new HashMap<Integer, String>();
00082
00083
00084 private final int columns = 7;
00085
00086
00087 private final String adress = "http://freedb.freedb.org/~cddb/cddb.cgi";
00088
00089
00090 private boolean notPrefetched = true;
00091
00092
00093 private int rowSelected = -1;
00094
00095
00096
00105 private PlayList()
00106 {
00107 keys.put(0, null);
00108 keys.put(1, null);
00109 keys.put(2, "title");
00110 keys.put(3, "artist");
00111 keys.put(4, "album");
00112 keys.put(5, "genre");
00113 keys.put(6, "year");
00114 }
00115
00116
00117
00126 public static PlayList getInstance() { return instance; }
00127
00128
00129
00137 public int getRowCount() { return playlist.size(); }
00138
00139
00140
00148 public int getColumnCount() { return columns; }
00149
00150
00151
00164 public Object getValueAt(int rowIndex, int columnIndex)
00165 {
00166 if (columnIndex == 0)
00167 return null;
00168 else if (columnIndex == 1)
00169 return String.valueOf(rowIndex);
00170 return playlist.get(rowIndex).get(keys.get(columnIndex));
00171 }
00172
00173
00174
00184 @Override
00185 public String getColumnName(int columnIndex)
00186 {
00187 String columnName = null;
00188 switch(columnIndex)
00189 {
00190 case 0: columnName = ""; break;
00191 case 1: columnName = "Lfd.Nr."; break;
00192 case 2: columnName = "Titel"; break;
00193 case 3: columnName = "Artist"; break;
00194 case 4: columnName = "Album"; break;
00195 case 5: columnName = "Genre"; break;
00196 case 6: columnName = "Jahr"; break;
00197 }
00198 return columnName;
00199 }
00200
00201
00202
00213 @Override
00214 public Class getColumnClass(int columnIndex)
00215 {
00216 return String.class;
00217 }
00218
00219
00220
00232 @Override
00233 public boolean isCellEditable(int rowIndex, int columnIndex)
00234 {
00235
00236
00237 if (columnIndex > 1) return true;
00238 return false;
00239 }
00240
00241
00242
00256 @Override
00257 public void setValueAt(Object aValue, int rowIndex, int columnIndex)
00258 {
00259 if (columnIndex == 0)
00260 {
00261
00262
00263
00264
00265 rowSelected = (aValue == null) ? -1 : rowIndex;
00266 } else if (columnIndex > 1)
00267 {
00268
00269
00270 playlist.get(rowIndex).put(keys.get(columnIndex), (String) aValue);
00271 Layer.getInstance().setSave(true);
00272 }
00273 }
00274
00289 public void setPlayList(String file) throws PlayListException,
00290 FileNotFoundException, IOException, CannotReadException,
00291 TagException, ReadOnlyFileException, InvalidAudioFrameException
00292 {
00293
00294
00295
00296 String extension = Utils.getExtension(new File(file));
00297 if (extension.equals(Utils.m3u))
00298 {
00299
00300 Cursor old_cursor = Layer.getInstance().getCursor();
00301 Layer.getInstance().setCursor(new Cursor(Cursor.WAIT_CURSOR));
00302
00303
00304
00305 m3u = new M3U(file);
00306 playlist = m3u.getPlayList();
00307
00308
00309 playlisttype = m3u.getPlayListType();
00310
00311
00312 Layer.getInstance().setCursor(old_cursor);
00313 } else if (extension.equals(Utils.cue))
00314 {
00315
00316 Cursor old_cursor = Layer.getInstance().getCursor();
00317 Layer.getInstance().setCursor(new Cursor(Cursor.WAIT_CURSOR));
00318
00319
00320
00321 cue = new CUE(file);
00322 playlist = cue.getPlayList();
00323
00324
00325 playlisttype = cue.getPlayListType();
00326
00327
00328 Layer.getInstance().setCursor(old_cursor);
00329 }
00330
00331 filename = file;
00332
00333 }
00334
00335
00336
00345 public HashMap<Integer, HashMap<String, String>> getPlayList()
00346 {
00347 return playlist;
00348 }
00349
00350
00351
00377 public String getMeta(int id, String key)
00378 {
00379 String val = null;
00380 try { val = (String) playlist.get(id).get(key); }
00381 catch (NullPointerException ex) {}
00382 return val;
00383 }
00384
00385
00386
00397 public String getType() {return playlisttype;}
00398
00399
00400
00407 public String getFileName() {return filename;}
00408
00409
00410
00421 public void PlayListSave(String filename)
00422 throws PlayListException, IOException
00423 {
00424 if ((playlisttype.equals("m3u_1")) || (playlisttype.equals("m3u_2")))
00425 {
00426
00427
00428 m3u.SavePlayList(filename, playlisttype, playlist);
00429 Layer.getInstance().setSave(false);
00430 } else if (playlisttype.equals("cue"))
00431 {
00432 cue.savePlayList(playlist, filename);
00433 Layer.getInstance().setSave(false);
00434 } else {
00435
00436
00437 throw new PlayListException(201);
00438 }
00439 }
00440
00441
00442
00457 public void InsertMedia(File[] selectedFiles) throws CannotReadException,
00458 IOException, TagException, ReadOnlyFileException,
00459 InvalidAudioFrameException
00460 {
00461 if (playlisttype.equals("m3u_1") || playlisttype.equals("m3u_2"))
00462 {
00463
00464
00465 m3u.InsertMedia(selectedFiles);
00466
00467
00468 playlist = m3u.getPlayList();
00469
00470
00471 Layer.getInstance().PlayListChange();
00472
00473
00474
00475 Layer.getInstance().setSave(true);
00476 }
00477 }
00478
00479
00480
00489 public void DeleteMedia(int del_id)
00490 {
00491 if (playlisttype.equals("m3u_1") || playlisttype.equals("m3u_2"))
00492 {
00493
00494
00495 m3u.DeleteMedia(del_id);
00496
00497
00498 playlist = m3u.getPlayList();
00499
00500
00501 Layer.getInstance().PlayListChange();
00502
00503
00504
00505 Layer.getInstance().setSave(true);
00506 }
00507 }
00508
00509
00510
00529 public void getAlbumInfo() throws CannotReadException, IOException,
00530 TagException, ReadOnlyFileException, InvalidAudioFrameException,
00531 PlayListException, NoPlayerException, InterruptedException
00532 {
00533
00534 HashMap<Integer, Integer> times = new HashMap<Integer, Integer>();
00535 int duration = 2;
00536 int TrackLength = 0;
00537 int TrackBegin = 0;
00538 int Tracks = playlist.size();
00539 int i = 0;
00540
00541
00542
00543 for(i=0; i<Tracks; i++)
00544 {
00545 File file = new File((String) playlist.get(i).get("media"));
00546 try
00547 {
00548 AudioFile audiofile = AudioFileIO.read(file);
00549 TrackLength = audiofile.getAudioHeader().getTrackLength();
00550 }
00551 catch (CannotReadException ex)
00552 {
00553 notPrefetched = true;
00554 int counter = 30;
00555 javax.media.Player player;
00556 player = Manager.createPlayer(file.toURI().toURL());
00557 player.prefetch();
00558 while(notPrefetched && (counter > 0))
00559 {
00560 counter--;
00561 Thread.sleep(100);
00562 }
00563 TrackLength = (int)player.getDuration().getSeconds();
00564 }
00565 TrackBegin = 75 * (TrackLength + duration);
00566 times.put(i, TrackBegin);
00567 duration += TrackLength;
00568 }
00569
00570
00571 String query = "?cmd=discid+" + Tracks + "+150";
00572 for (i=0; i<Tracks-1; i++) query += "+" + times.get(i);
00573 query += "+" + duration + "&hello=test+abc+blah+1.0&proto=6";
00574 String result = null;
00575 try
00576 {
00577
00578 result = new Scanner(new URL(adress+query).openStream()).useDelimiter("\\Z").next();
00579 }
00580 catch (UnknownHostException ex)
00581 {
00582 System.err.println(ex);
00583 throw new PlayListException(202);
00584 }
00585 catch (Exception ex) {ex.printStackTrace();}
00586 System.out.println(result);
00587
00588
00589 int code = Integer.parseInt(result.substring(0, result.indexOf(" ")), 10);
00590 if (code != 200) InfoMsg.show(3); else
00591 {
00592 String discid = result.substring(result.lastIndexOf(" ")+1, result.length());
00593 query = "?cmd=cddb+query+" + discid + query.substring(11, query.length());
00594 result = new Scanner(new URL(adress+query).openStream()).useDelimiter("\\Z").next();
00595 System.out.println(result);
00596 code = Integer.parseInt(result.substring(0, result.indexOf(" ")), 10);
00597 if ((code > 199) && (code < 300))
00598 {
00599
00600
00601 AlbumAuswahlDlg dlg = new AlbumAuswahlDlg(result);
00602 dlg.run();
00603 } else {
00604
00605
00606 InfoMsg.show(4);
00607 }
00608 }
00609 }
00610
00611
00612
00637 public void setAlbumInfos(String album) throws MalformedURLException,
00638 IOException, CannotReadException, TagException,
00639 ReadOnlyFileException, InvalidAudioFrameException,
00640 CannotWriteException, PlayListException
00641 {
00642
00643 String query = "?cmd=cddb+read+" + album +
00644 "&hello=test+abc+blah+1.0&proto=6";
00645
00646
00647 String result = new Scanner(
00648 new URL(adress+query).openStream()).useDelimiter("\\Z").next();
00649
00650
00651 HashMap<String, String> daten = new HashMap<String, String>();
00652 daten.put("AlbumTitel", "");
00653 daten.put("AlbumArtist", "");
00654 daten.put("AlbumJahr", "");
00655 daten.put("Genre", "");
00656
00657
00658 Pattern pattern = Pattern.compile("DTITLE=");
00659 Matcher matcher = pattern.matcher(result);
00660 int pos = 0;
00661 if (matcher.find())
00662 {
00663 pos = matcher.end();
00664 String[] dtitle = result.substring(
00665 pos, result.indexOf("\n", pos)).split(" / ");
00666 daten.put("AlbumTitel", dtitle[1]);
00667 daten.put("AlbumArtist", dtitle[0]);
00668 }
00669
00670
00671 pattern = Pattern.compile("DYEAR=");
00672 matcher = pattern.matcher(result);
00673 if (matcher.find())
00674 {
00675 pos = matcher.end();
00676 daten.put("AlbumJahr", result.substring(
00677 pos, result.indexOf("\n", pos)));
00678 }
00679
00680
00681 pattern = Pattern.compile("DGENRE=");
00682 matcher = pattern.matcher(result);
00683 if (matcher.find())
00684 {
00685 pos = matcher.end();
00686 daten.put("Genre", result.substring(pos, result.indexOf("\n", pos)));
00687 }
00688
00689
00690
00691 for (int i=0; i<playlist.size(); i++)
00692 {
00693 pattern = Pattern.compile("TITLE" + i + "=");
00694 matcher = pattern.matcher(result);
00695 String title = "";
00696 if (matcher.find())
00697 {
00698 pos = matcher.end();
00699 title = result.substring(pos, result.indexOf("\n", pos));
00700 if (title == null) title = "";
00701 }
00702 setValueAt(title, i, 2);
00703 setValueAt(daten.get("AlbumTitel"), i, 4);
00704 setValueAt(daten.get("Genre"), i, 5);
00705 setValueAt(daten.get("AlbumJahr"),i, 6);
00706 }
00707
00708
00709 Layer.getInstance().PlayListChange();
00710 }
00711
00712
00713
00723 public void controllerUpdate(ControllerEvent ce)
00724 {
00725 if (ce instanceof PrefetchCompleteEvent) notPrefetched = false;
00726 }
00727
00728
00729
00739 public void changeSequence(int old_id, int new_id)
00740 {
00741 HashMap<Integer, HashMap<String, String>> tmpplaylist =
00742 new HashMap<Integer, HashMap<String, String>>();
00743 tmpplaylist.put(new_id, playlist.get(old_id));
00744 tmpplaylist.put(old_id, playlist.get(new_id));
00745 playlist.put(new_id, tmpplaylist.get(new_id));
00746 playlist.put(old_id, tmpplaylist.get(old_id));
00747 }
00748
00749
00750
00758 public void changePlayList(HashMap<Integer, HashMap<String, String>> playlist)
00759 {
00760 this.playlist = playlist;
00761 }
00762 }