| New file | 
 |  |  | 
 |  |  |  /* | 
 |  |  |     Mediacenter - Central Media Store and Raspberry Pi remote control | 
 |  |  |     Copyright (C) 2013, 2014  Ulrich Hilger, http://uhilger.de | 
 |  |  |  | 
 |  |  |     This program is free software: you can redistribute it and/or modify | 
 |  |  |     it under the terms of the GNU Affero General Public License as published by | 
 |  |  |     the Free Software Foundation, either version 3 of the License, or | 
 |  |  |     (at your option) any later version. | 
 |  |  |  | 
 |  |  |     This program is distributed in the hope that it will be useful, | 
 |  |  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  |  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |  |  |     GNU Affero General Public License for more details. | 
 |  |  |  | 
 |  |  |     You should have received a copy of the GNU Affero General Public License | 
 |  |  |     along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
 |  |  |  | 
 |  |  |  */ | 
 |  |  |   | 
 |  |  |  | 
 |  |  | package de.uhilger.mediaz.store; | 
 |  |  |  | 
 |  |  | import java.io.File; | 
 |  |  | import java.util.HashMap; | 
 |  |  | import java.util.Map; | 
 |  |  | import javax.sound.sampled.AudioFileFormat; | 
 |  |  | import javax.sound.sampled.AudioFormat; | 
 |  |  | import javax.sound.sampled.AudioSystem; | 
 |  |  | import org.tritonus.share.sampled.TAudioFormat; | 
 |  |  | import org.tritonus.share.sampled.file.TAudioFileFormat; | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * Class <code>Track</code> models an audio file including ID3 metadata.  | 
 |  |  |  *  | 
 |  |  |  * @author Ulrich Hilger, <a href="http://dev.uhilger.de" target="_blank">http://dev.uhilger.de</a> | 
 |  |  |  * @author Published under the terms and conditions of | 
 |  |  |  * the <a href="http://www.gnu.org/licenses/" target="_blank">GNU Affero General Public License</a> | 
 |  |  |  * | 
 |  |  |  * @version 3, February 19, 2012 | 
 |  |  |  */ | 
 |  |  |  | 
 |  |  | public class Track { | 
 |  |  |  | 
 |  |  |   /** reference to file of audio track */ | 
 |  |  |   private File trackFile; | 
 |  |  |    | 
 |  |  |   /** the time at which playing this track has started */ | 
 |  |  |   private long playStart; | 
 |  |  |    | 
 |  |  |   /** reference to metadata information */ | 
 |  |  |   private Map<String, Object> properties; | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * Create a new object of class <code>Track</code> | 
 |  |  |    * @param trackFile  the audio file this track object refers to | 
 |  |  |    */ | 
 |  |  |   public Track(File trackFile) { | 
 |  |  |     super(); | 
 |  |  |     this.playStart = -1; | 
 |  |  |     this.trackFile = trackFile; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * get the time at which the playing of this track has started | 
 |  |  |    * @return  number of milliseconds since Jan 1, 1970 denoting the time this tack has  | 
 |  |  |    * started playing or -1 if it does not play  | 
 |  |  |    */ | 
 |  |  |   public long getPlayStart() { | 
 |  |  |     return playStart; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * set the time at which the playing of this track has started | 
 |  |  |    * @param playStart  number of milliseconds since Jan 1, 1970 denoting the time this tack has  | 
 |  |  |    * started playing or -1 if it does not play  | 
 |  |  |    */ | 
 |  |  |   public void setPlayStart(long playStart) { | 
 |  |  |     this.playStart = playStart; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * get the file this track refers to | 
 |  |  |    * @return  the audio file reference | 
 |  |  |    */ | 
 |  |  |   public File getTrackFile() { | 
 |  |  |     return trackFile; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * set the file this track refers to | 
 |  |  |    * @param trackFile  the audio file reference to set this track to | 
 |  |  |    */ | 
 |  |  |   public void setTrackFile(File trackFile) { | 
 |  |  |     this.trackFile = trackFile; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * get the metadata of a given audio file | 
 |  |  |    * | 
 |  |  |    * <p>Example<br><pre> | 
 |  |  |    * properties: {mp3.frequency.hz=44100, title=All Cried Out,  | 
 |  |  |    * mp3.length.bytes=6301706, comment=, mp3.channels=2, date=1984,  | 
 |  |  |    * mp3.version.layer=3, mp3.framesize.bytes=414, mp3.id3tag.track=6,  | 
 |  |  |    * mp3.version.mpeg=1, mp3.bitrate.nominal.bps=128000, mp3.vbr.scale=0,  | 
 |  |  |    * bitrate=128000, mp3.length.frames=15112, mp3.crc=false, mp3.vbr=false,  | 
 |  |  |    * album=Alf, mp3.framerate.fps=38.28125, mp3.copyright=false,  | 
 |  |  |    * mp3.id3tag.v2=java.io.ByteArrayInputStream@7efa96, mp3.version.encoding=MPEG1L3, | 
 |  |  |    * year=1984, mp3.id3tag.genre=Rock, mp3.header.pos=136, mp3.mode=0, | 
 |  |  |    * mp3.original=true, vbr=false, mp3.padding=true, duration=394762000,  | 
 |  |  |    * author=Alison Moyet} | 
 |  |  |    * </pre></p> | 
 |  |  |    * | 
 |  |  |    * @param file File  the audio file to get metadata for | 
 |  |  |    * @return Map  the properties Map with information such as in above example | 
 |  |  |    */ | 
 |  |  |   @SuppressWarnings("unchecked") | 
 |  |  |   private Map<String, Object> getMetadata(File file) { | 
 |  |  |     Map<String, Object> map = new HashMap<String, Object>(); | 
 |  |  |     try { | 
 |  |  |       AudioFileFormat audioFileFormat = AudioSystem.getAudioFileFormat(file); | 
 |  |  |       if (audioFileFormat instanceof TAudioFileFormat) { | 
 |  |  |         map.putAll(((TAudioFileFormat) audioFileFormat).properties()); | 
 |  |  |       } | 
 |  |  |       AudioFormat audioFormat = audioFileFormat.getFormat(); | 
 |  |  |       if (audioFormat instanceof TAudioFormat) { | 
 |  |  |         map.putAll(((TAudioFormat) audioFormat).properties()); | 
 |  |  |       } | 
 |  |  |     } catch (Exception ex) { | 
 |  |  |       ex.printStackTrace(); | 
 |  |  |     } | 
 |  |  |     return map; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * get the metadata of the audio file this track refers to | 
 |  |  |    * | 
 |  |  |    * <p>Example<br><pre> | 
 |  |  |    * properties: {mp3.frequency.hz=44100, title=All Cried Out,  | 
 |  |  |    * mp3.length.bytes=6301706, comment=, mp3.channels=2, date=1984,  | 
 |  |  |    * mp3.version.layer=3, mp3.framesize.bytes=414, mp3.id3tag.track=6,  | 
 |  |  |    * mp3.version.mpeg=1, mp3.bitrate.nominal.bps=128000, mp3.vbr.scale=0,  | 
 |  |  |    * bitrate=128000, mp3.length.frames=15112, mp3.crc=false, mp3.vbr=false,  | 
 |  |  |    * album=Alf, mp3.framerate.fps=38.28125, mp3.copyright=false,  | 
 |  |  |    * mp3.id3tag.v2=java.io.ByteArrayInputStream@7efa96, mp3.version.encoding=MPEG1L3, | 
 |  |  |    * year=1984, mp3.id3tag.genre=Rock, mp3.header.pos=136, mp3.mode=0, | 
 |  |  |    * mp3.original=true, vbr=false, mp3.padding=true, duration=394762000,  | 
 |  |  |    * author=Alison Moyet} | 
 |  |  |    * </pre></p> | 
 |  |  |    * | 
 |  |  |    * @return Map  the properties Map with information such as in above example | 
 |  |  |    */ | 
 |  |  |   public Map<String, Object> getMetadata() { | 
 |  |  |     if (properties == null) { | 
 |  |  |       properties = getMetadata(trackFile); | 
 |  |  |     } | 
 |  |  |     return properties; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * Get the bitrate of this track, i.e. bits per second | 
 |  |  |    * @return  the bitrate | 
 |  |  |    */ | 
 |  |  |   public long getBitrate() { | 
 |  |  |     long bitrate = -1; | 
 |  |  |     Object o = getMetadata().get("bitrate"); | 
 |  |  |     if (o != null) { | 
 |  |  |       bitrate = Long.parseLong(o.toString()); | 
 |  |  |     } | 
 |  |  |     return bitrate; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * get the artist of the currently playing song | 
 |  |  |    * @return String  the artist of the song | 
 |  |  |    */ | 
 |  |  |   public String getArtist() { | 
 |  |  |     String artist = ""; | 
 |  |  |     Object o = getMetadata().get("author"); | 
 |  |  |     if (o != null) { | 
 |  |  |       artist = o.toString().trim(); | 
 |  |  |     } | 
 |  |  |     return artist; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * get the album of the currently playing song | 
 |  |  |    * @return String  the album of the song | 
 |  |  |    */ | 
 |  |  |   public String getAlbum() { | 
 |  |  |     String album = ""; | 
 |  |  |     //if (properties != null) { | 
 |  |  |     Object o = getMetadata().get("album"); | 
 |  |  |     if (o != null) { | 
 |  |  |       album = o.toString().trim(); | 
 |  |  |     } | 
 |  |  |     //} | 
 |  |  |     return album; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * get the title of the currently playing song | 
 |  |  |    * @return String  the song title | 
 |  |  |    */ | 
 |  |  |   public String getTitle() { | 
 |  |  |     String title = ""; | 
 |  |  |     Object o = getMetadata().get("title"); | 
 |  |  |     if (o != null) { | 
 |  |  |       title = o.toString().trim(); | 
 |  |  |     } else { | 
 |  |  |       title = trackFile.getName(); | 
 |  |  |     } | 
 |  |  |     return title; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * get the duration of the currently playing song | 
 |  |  |    * | 
 |  |  |    * @return long duration in milliseconds | 
 |  |  |    */ | 
 |  |  |   public long getDuration() { | 
 |  |  |     long duration = -1; | 
 |  |  |     Object o = getMetadata().get("duration"); | 
 |  |  |     if (o != null) { | 
 |  |  |       duration = Long.parseLong(o.toString()); | 
 |  |  |     } | 
 |  |  |     return duration; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * Overridden from class <code>Object</code> | 
 |  |  |    * @return  the hash code | 
 |  |  |    * @see java.lang.Object#hashCode()  | 
 |  |  |    */ | 
 |  |  |   public int hashCode() { | 
 |  |  |     int hash = 7; | 
 |  |  |     hash = 97 * hash + (this.trackFile != null ? this.trackFile.hashCode() : 0); | 
 |  |  |     return hash; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |   /** | 
 |  |  |    * Overridden from class <code>Object</code> | 
 |  |  |    * @return  true, when this object is equal to the given object  | 
 |  |  |    * @see java.lang.Object#equals(java.lang.Object)  | 
 |  |  |    */ | 
 |  |  |   public boolean equals(Object obj) { | 
 |  |  |     boolean isEqual = false; | 
 |  |  |     if(obj != null && obj instanceof Track) { | 
 |  |  |       Track otherTrack = (Track) obj; | 
 |  |  |       File otherFile = otherTrack.getTrackFile(); | 
 |  |  |       isEqual = otherFile.equals(this.getTrackFile()); | 
 |  |  |     } | 
 |  |  |     return isEqual; | 
 |  |  |   } | 
 |  |  |  | 
 |  |  | } |