/* 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 . */ 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 Track models an audio file including ID3 metadata. * * @author Ulrich Hilger, http://dev.uhilger.de * @author Published under the terms and conditions of * the GNU Affero General Public License * * @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 properties; /** * Create a new object of class Track * @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 * *

Example

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

* * @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 getMetadata(File file) { Map map = new HashMap(); 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 * *

Example

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

* * @return Map the properties Map with information such as in above example */ public Map 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 Object * @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 Object * @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; } }