package org.jaudiotagger.tag.mp4.field; import org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader; import org.jaudiotagger.tag.FieldDataInvalidException; import org.jaudiotagger.tag.mp4.Mp4FieldKey; import org.jaudiotagger.tag.mp4.atom.Mp4DataBox; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.ArrayList; /** * Represents the Track No field * <p/> * <p>There are a number of reserved fields making matters more complicated * Reserved:2 bytes * Track Number:2 bytes * No of Tracks:2 bytes (or zero if not known) * PlayListTitleReserved: 1 byte * playtitlenameReserved:0 bytes * </p> */ public class Mp4TrackField extends Mp4TagTextNumberField { private static final int NONE_VALUE_INDEX = 0; private static final int TRACK_NO_INDEX = 1; private static final int TRACK_TOTAL_INDEX = 2; private static final int NONE_END_VALUE_INDEX = 3; /** * Create new Track Field parsing the String for the trackno/total * * @param trackValue * @throws org.jaudiotagger.tag.FieldDataInvalidException * */ public Mp4TrackField(String trackValue) throws FieldDataInvalidException { super(Mp4FieldKey.TRACK.getFieldName(), trackValue); numbers = new ArrayList<Short>(); numbers.add(new Short("0")); String values[] = trackValue.split("/"); switch (values.length) { case 1: try { numbers.add(Short.parseShort(values[0])); } catch (NumberFormatException nfe) { throw new FieldDataInvalidException("Value of:" + values[0] + " is invalid for field:" + id); } numbers.add(new Short("0")); numbers.add(new Short("0")); break; case 2: try { numbers.add(Short.parseShort(values[0])); } catch (NumberFormatException nfe) { throw new FieldDataInvalidException("Value of:" + values[0] + " is invalid for field:" + id); } try { numbers.add(Short.parseShort(values[1])); } catch (NumberFormatException nfe) { throw new FieldDataInvalidException("Value of:" + values[1] + " is invalid for field:" + id); } numbers.add(new Short("0")); break; default: throw new FieldDataInvalidException("Value is invalid for field:" + id); } } /** * Create new Track Field with only track No * * @param trackNo */ public Mp4TrackField(int trackNo) { super(Mp4FieldKey.TRACK.getFieldName(), String.valueOf(trackNo)); numbers = new ArrayList<Short>(); numbers.add(new Short("0")); numbers.add((short) trackNo); numbers.add(new Short("0")); numbers.add(new Short("0")); } /** * Create new Track Field with track No and total tracks * * @param trackNo * @param total */ public Mp4TrackField(int trackNo, int total) { super(Mp4FieldKey.TRACK.getFieldName(), String.valueOf(trackNo)); numbers = new ArrayList<Short>(); numbers.add(new Short("0")); numbers.add((short) trackNo); numbers.add((short) total); numbers.add(new Short("0")); } /** * Construct from filedata * * @param id * @param data * @throws UnsupportedEncodingException */ public Mp4TrackField(String id, ByteBuffer data) throws UnsupportedEncodingException { super(id, data); } protected void build(ByteBuffer data) throws UnsupportedEncodingException { //Data actually contains a 'Data' Box so process data using this Mp4BoxHeader header = new Mp4BoxHeader(data); Mp4DataBox databox = new Mp4DataBox(header, data); dataSize = header.getDataLength(); numbers = databox.getNumbers(); //Track number always hold three values, we can discard the first one, the second one is the track no //and the third is the total no of tracks so only use if not zero StringBuffer sb = new StringBuffer(); if (numbers != null) { sb.append(numbers.get(TRACK_NO_INDEX)); if (numbers.get(TRACK_TOTAL_INDEX) > 0) { sb.append("/").append(numbers.get(TRACK_TOTAL_INDEX)); } } content = sb.toString(); } /** * @return */ public Short getTrackNo() { return numbers.get(TRACK_NO_INDEX); } /** * @return */ public Short getTrackTotal() { return numbers.get(TRACK_TOTAL_INDEX); } /** * Set Track No * * @param trackNo */ public void setTrackNo(int trackNo) { numbers.set(TRACK_NO_INDEX, (short) trackNo); } /** * Set total number of tracks * * @param trackTotal */ public void setTrackTotal(int trackTotal) { numbers.set(TRACK_TOTAL_INDEX, (short) trackTotal); } }