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; |
| | | } |
| | | |
| | | } |