001: /*
002:
003: * MpegInfo.
004:
005: *
006:
007: * JavaZOOM : jlgui@javazoom.net http://www.javazoom.net
008:
009: *
010:
011: * ----------------------------------------------------------------------- This
012:
013: * program is free software; you can redistribute it and/or modify it under the
014:
015: * terms of the GNU Library General Public License as published by the Free
016:
017: * Software Foundation; either version 2 of the License, or (at your option) any
018:
019: * later version.
020:
021: *
022:
023: * This program is distributed in the hope that it will be useful, but WITHOUT
024:
025: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
026:
027: * FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
028:
029: * details.
030:
031: *
032:
033: * You should have received a copy of the GNU Library General Public License
034:
035: * along with this program; if not, write to the Free Software Foundation, Inc.,
036:
037: * 675 Mass Ave, Cambridge, MA 02139, USA.
038:
039: * ----------------------------------------------------------------------
040:
041: */
042:
043: package de.teamskill.lius.index.audio;
044:
045: import java.io.File;
046: import java.io.IOException;
047: import java.io.InputStream;
048: import java.net.URL;
049: import java.util.Iterator;
050: import java.util.Map;
051: import java.util.Vector;
052:
053: import javax.sound.sampled.AudioFileFormat;
054: import javax.sound.sampled.AudioSystem;
055: import javax.sound.sampled.UnsupportedAudioFileException;
056:
057: import org.tritonus.share.sampled.file.TAudioFileFormat;
058:
059: /**
060: *
061: * This class gives information (audio format and comments) about MPEG file or
062: *
063: * URL.
064: *
065: */
066:
067: public class MpegInfo implements TagInfo {
068:
069: protected int channels = -1;
070:
071: protected String channelsMode = null;
072:
073: protected String version = null;
074:
075: protected int rate = 0;
076:
077: protected String layer = null;
078:
079: protected String emphasis = null;
080:
081: protected int nominalbitrate = 0;
082:
083: protected long total = 0;
084:
085: protected String vendor = null;
086:
087: protected String location = null;
088:
089: protected long size = 0;
090:
091: protected boolean copyright = false;
092:
093: protected boolean crc = false;
094:
095: protected boolean original = false;
096:
097: protected boolean priv = false;
098:
099: protected boolean vbr = false;
100:
101: protected int track = -1;
102:
103: protected String year = null;
104:
105: protected String genre = null;
106:
107: protected String title = null;
108:
109: protected String artist = null;
110:
111: protected String album = null;
112:
113: protected Vector comments = null;
114:
115: /**
116: *
117: * Constructor.
118: *
119: */
120:
121: public MpegInfo() {
122:
123: super ();
124:
125: }
126:
127: /**
128: *
129: * Load and parse MPEG info from File.
130: *
131: *
132: *
133: * @param input
134: *
135: * @throws IOException
136: *
137: */
138:
139: public void load(File input) throws IOException,
140:
141: UnsupportedAudioFileException {
142:
143: size = input.length();
144:
145: location = input.getPath();
146:
147: loadInfo(input);
148:
149: }
150:
151: /**
152: *
153: * Load and parse MPEG info from URL.
154: *
155: *
156: *
157: * @param input
158: *
159: * @throws IOException
160: *
161: * @throws UnsupportedAudioFileException
162: *
163: */
164:
165: public void load(URL input) throws IOException,
166:
167: UnsupportedAudioFileException {
168:
169: location = input.toString();
170:
171: loadInfo(input);
172:
173: }
174:
175: /**
176: *
177: * Load and parse MPEG info from InputStream.
178: *
179: *
180: *
181: * @param input
182: *
183: * @throws IOException
184: *
185: * @throws UnsupportedAudioFileException
186: *
187: */
188:
189: public void load(InputStream input) throws IOException,
190:
191: UnsupportedAudioFileException {
192:
193: loadInfo(input);
194:
195: }
196:
197: /**
198: *
199: * Load info from input stream.
200: *
201: *
202: *
203: * @param input
204: *
205: * @throws IOException
206: *
207: * @throws UnsupportedAudioFileException
208: *
209: */
210:
211: protected void loadInfo(InputStream input) throws IOException,
212:
213: UnsupportedAudioFileException {
214:
215: AudioFileFormat aff = AudioSystem.getAudioFileFormat(input);
216:
217: loadInfo(aff);
218:
219: }
220:
221: /**
222: *
223: * Load MP3 info from file.
224: *
225: *
226: *
227: * @param file
228: *
229: * @throws IOException
230: *
231: * @throws UnsupportedAudioFileException
232: *
233: */
234:
235: protected void loadInfo(File file) throws IOException,
236:
237: UnsupportedAudioFileException {
238:
239: AudioFileFormat aff = AudioSystem.getAudioFileFormat(file);
240:
241: loadInfo(aff);
242:
243: }
244:
245: /**
246: *
247: * Load info from AudioFileFormat.
248: *
249: *
250: *
251: * @param aff
252: *
253: */
254:
255: protected void loadInfo(AudioFileFormat aff)
256:
257: throws UnsupportedAudioFileException {
258:
259: String type = aff.getType().toString();
260:
261: if (!type.equalsIgnoreCase("mp3"))
262:
263: throw new UnsupportedAudioFileException(
264: "Not MP3 audio format");
265:
266: if (aff instanceof TAudioFileFormat) {
267:
268: Map props = ((TAudioFileFormat) aff).properties();
269:
270: if (props.containsKey("mp3.channels"))
271:
272: channels = ((Integer) props.get("mp3.channels"))
273: .intValue();
274:
275: if (props.containsKey("mp3.frequency.hz"))
276:
277: rate = ((Integer) props.get("mp3.frequency.hz"))
278: .intValue();
279:
280: if (props.containsKey("mp3.bitrate.nominal.bps"))
281:
282: nominalbitrate = ((Integer) props
283:
284: .get("mp3.bitrate.nominal.bps")).intValue();
285:
286: if (props.containsKey("mp3.version.layer"))
287:
288: layer = "Layer "
289: + (String) props.get("mp3.version.layer");
290:
291: if (props.containsKey("mp3.version.mpeg")) {
292:
293: version = (String) props.get("mp3.version.mpeg");
294:
295: if (version.equals("1"))
296:
297: version = "MPEG1";
298:
299: else if (version.equals("2"))
300:
301: version = "MPEG2-LSF";
302:
303: else if (version.equals("2.5"))
304:
305: version = "MPEG2.5-LSF";
306:
307: }
308:
309: if (props.containsKey("mp3.mode")) {
310:
311: int mode = ((Integer) props.get("mp3.mode")).intValue();
312:
313: if (mode == 0)
314:
315: channelsMode = "Stereo";
316:
317: else if (mode == 1)
318:
319: channelsMode = "Joint Stereo";
320:
321: else if (mode == 2)
322:
323: channelsMode = "Dual Channel";
324:
325: else if (mode == 3)
326:
327: channelsMode = "Single Channel";
328:
329: }
330:
331: if (props.containsKey("mp3.crc"))
332:
333: crc = ((Boolean) props.get("mp3.crc")).booleanValue();
334:
335: if (props.containsKey("mp3.vbr"))
336:
337: vbr = ((Boolean) props.get("mp3.vbr")).booleanValue();
338:
339: if (props.containsKey("mp3.copyright"))
340:
341: copyright = ((Boolean) props.get("mp3.copyright"))
342:
343: .booleanValue();
344:
345: if (props.containsKey("mp3.original"))
346:
347: original = ((Boolean) props.get("mp3.original"))
348:
349: .booleanValue();
350:
351: emphasis = "none";
352:
353: if (props.containsKey("title"))
354:
355: title = (String) props.get("title");
356:
357: if (props.containsKey("author"))
358:
359: artist = (String) props.get("author");
360:
361: if (props.containsKey("album"))
362:
363: album = (String) props.get("album");
364:
365: if (props.containsKey("date"))
366:
367: year = (String) props.get("date");
368:
369: if (props.containsKey("duration"))
370:
371: total = (long) Math.round((((Long) props
372: .get("duration"))
373:
374: .longValue()) / 1000000);
375:
376: if (props.containsKey("mp3.id3tag.genre"))
377:
378: genre = (String) props.get("mp3.id3tag.genre");
379:
380: if (props.containsKey("mp3.id3tag.track")) {
381:
382: try {
383:
384: track = Integer.parseInt((String) props
385:
386: .get("mp3.id3tag.track"));
387:
388: } catch (NumberFormatException e1) {
389:
390: // Not a number
391:
392: }
393:
394: }
395:
396: }
397:
398: }
399:
400: /**
401: *
402: * Load MP3 info from URL.
403: *
404: *
405: *
406: * @param input
407: *
408: * @throws IOException
409: *
410: * @throws UnsupportedAudioFileException
411: *
412: */
413:
414: protected void loadInfo(URL input) throws IOException,
415:
416: UnsupportedAudioFileException {
417:
418: AudioFileFormat aff = AudioSystem.getAudioFileFormat(input);
419:
420: loadInfo(aff);
421:
422: loadShoutastInfo(aff);
423:
424: }
425:
426: /**
427: *
428: * Load Shoutcast info from AudioFileFormat.
429: *
430: *
431: *
432: * @param aff
433: *
434: * @throws IOException
435: *
436: * @throws UnsupportedAudioFileException
437: *
438: */
439:
440: protected void loadShoutastInfo(AudioFileFormat aff)
441: throws IOException,
442:
443: UnsupportedAudioFileException {
444:
445: String type = aff.getType().toString();
446:
447: if (!type.equalsIgnoreCase("mp3"))
448:
449: throw new UnsupportedAudioFileException(
450: "Not MP3 audio format");
451:
452: if (aff instanceof TAudioFileFormat) {
453:
454: Map props = ((TAudioFileFormat) aff).properties();
455:
456: // Try shoutcast meta data (if any).
457:
458: Iterator it = props.keySet().iterator();
459:
460: comments = new Vector();
461:
462: while (it.hasNext()) {
463:
464: String key = (String) it.next();
465:
466: if (key.startsWith("mp3.shoutcast.metadata.")) {
467:
468: String value = (String) props.get(key);
469:
470: key = key.substring(23, key.length());
471:
472: if (key.equalsIgnoreCase("icy-name")) {
473:
474: title = value;
475:
476: } else if (key.equalsIgnoreCase("icy-genre")) {
477:
478: genre = value;
479:
480: } else {
481:
482: comments.add(key + "=" + value);
483:
484: }
485:
486: }
487:
488: }
489:
490: }
491:
492: }
493:
494: public boolean getVBR() {
495:
496: return vbr;
497:
498: }
499:
500: public int getChannels() {
501:
502: return channels;
503:
504: }
505:
506: public String getVersion() {
507:
508: return version;
509:
510: }
511:
512: public String getEmphasis() {
513:
514: return emphasis;
515:
516: }
517:
518: public boolean getCopyright() {
519:
520: return copyright;
521:
522: }
523:
524: public boolean getCRC() {
525:
526: return crc;
527:
528: }
529:
530: public boolean getOriginal() {
531:
532: return original;
533:
534: }
535:
536: public String getLayer() {
537:
538: return layer;
539:
540: }
541:
542: public long getSize() {
543:
544: return size;
545:
546: }
547:
548: public String getLocation() {
549:
550: return location;
551:
552: }
553:
554: /*-- TagInfo Implementation --*/
555:
556: public int getSamplingRate() {
557:
558: return rate;
559:
560: }
561:
562: public int getBitRate() {
563:
564: return nominalbitrate;
565:
566: }
567:
568: public long getPlayTime() {
569:
570: return total;
571:
572: }
573:
574: public String getTitle() {
575:
576: return title;
577:
578: }
579:
580: public String getArtist() {
581:
582: return artist;
583:
584: }
585:
586: public String getAlbum() {
587:
588: return album;
589:
590: }
591:
592: public int getTrack() {
593:
594: return track;
595:
596: }
597:
598: public String getGenre() {
599:
600: return genre;
601:
602: }
603:
604: public Vector getComment() {
605:
606: return comments;
607:
608: }
609:
610: public String getYear() {
611:
612: return year;
613:
614: }
615:
616: /**
617: *
618: * Get channels mode.
619: *
620: *
621: *
622: * @return
623: *
624: */
625:
626: public String getChannelsMode() {
627:
628: return channelsMode;
629:
630: }
631:
632: }
|