/*
|
Tango - 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.tango.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;
|
}
|
|
}
|