Package com.tulskiy.musique.audio.formats.mp3

Source Code of com.tulskiy.musique.audio.formats.mp3.MP3FileReader

/*
* Copyright (c) 2008, 2009, 2010, 2011 Denis Tulskiy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.tulskiy.musique.audio.formats.mp3;

import java.io.IOException;
import java.util.List;

import com.tulskiy.musique.gui.model.FieldValues;
import com.tulskiy.musique.util.Util;
import org.jaudiotagger.audio.mp3.LameFrame;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.audio.mp3.XingFrame;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.KeyNotFoundException;
import org.jaudiotagger.tag.Tag;
import org.jaudiotagger.tag.TagField;
import org.jaudiotagger.tag.id3.*;
import org.jaudiotagger.tag.id3.framebody.AbstractFrameBodyTextInfo;
import org.jaudiotagger.tag.id3.framebody.FrameBodyCOMM;
import org.jaudiotagger.tag.id3.framebody.FrameBodyPOPM;
import org.jaudiotagger.tag.id3.framebody.FrameBodyTPOS;
import org.jaudiotagger.tag.id3.framebody.FrameBodyTRCK;
import org.jaudiotagger.tag.id3.valuepair.TextEncoding;

import com.tulskiy.musique.audio.AudioFileReader;
import com.tulskiy.musique.audio.formats.ape.APETagProcessor;
import com.tulskiy.musique.playlist.Track;
import com.tulskiy.musique.playlist.TrackData;

import davaguine.jmac.info.ID3Tag;

/**
* @Author: Denis Tulskiy
* @Date: 26.06.2009
*/
public class MP3FileReader extends AudioFileReader {
    private static final int GAPLESS_DELAY = 529;

    private APETagProcessor apeTagProcessor = new APETagProcessor();

    public Track readSingle(Track track) {
      TrackData trackData = track.getTrackData();
        TextEncoding.getInstanceOf().setDefaultNonUnicode(defaultCharset.name());
        ID3Tag.setDefaultEncoding(defaultCharset.name());
        MP3File mp3File = null;
        try {
            mp3File = new MP3File(trackData.getFile(), MP3File.LOAD_ALL, true);
        } catch (Exception ignored) {
            System.out.println("Couldn't read file: " + trackData.getFile());
        }

        ID3v24Tag v24Tag = null;
        if (mp3File != null) {
            try {
                v24Tag = mp3File.getID3v2TagAsv24();
                if (v24Tag != null) {
                    copyCommonTagFields(v24Tag, track);
                    copySpecificTagFields(v24Tag, track);
                }

                ID3v1Tag id3v1Tag = mp3File.getID3v1Tag();
                if (id3v1Tag != null) {
                    copyCommonTagFields(id3v1Tag, track);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            MP3AudioHeader mp3AudioHeader = mp3File.getMP3AudioHeader();
            copyHeaderFields(mp3AudioHeader, track);

            long totalSamples = trackData.getTotalSamples();
            int enc_delay = GAPLESS_DELAY;

            XingFrame xingFrame = mp3AudioHeader.getXingFrame();
            if (xingFrame != null) {
                LameFrame lameFrame = xingFrame.getLameFrame();
                if (lameFrame != null) {
                    long length = totalSamples;
                    enc_delay += lameFrame.getEncDelay();
                    int enc_padding = lameFrame.getEncPadding() - GAPLESS_DELAY;
                    if (enc_padding < length)
                        length -= enc_padding;

                    if (totalSamples > length)
                        totalSamples = length;
                } else {
                    totalSamples += GAPLESS_DELAY;
                }
            }

            totalSamples -= enc_delay;
            trackData.setTotalSamples(totalSamples);
        }

        // TODO review correctness of reading APETag only in case ID3 is missed
        // for example, maybe useful to read and set those fields
        // that are missed in ID3 but presented in APE
        if (v24Tag == null) {
          try {
              apeTagProcessor.readAPEv2Tag(track);
          }
          catch (Exception ignored) {
          }
        }

        return track;
    }

    public boolean isFileSupported(String ext) {
        return ext.equalsIgnoreCase("mp3");
    }

  @Override
  protected void copyCommonTagFields(Tag tag, Track track) throws IOException {
        if (tag instanceof ID3v24Tag) {
            ID3v24Tag v24Tag = (ID3v24Tag) tag;
            for (FieldKey key : FieldKey.values()) {
                setMusiqueTagFieldValues(track, key, v24Tag);
            }
        } else if (tag instanceof ID3v1Tag) {
            ID3v1Tag id3v1Tag = (ID3v1Tag) tag;
            TrackData trackData = track.getTrackData();
            for (FieldKey key : FieldKey.values()) {
                String val = id3v1Tag.getFirst(key);
                if (!Util.isEmpty(val)) {
                    FieldValues tagFieldValues = trackData.getTagFieldValues(key);
                    if (tagFieldValues == null || tagFieldValues.isEmpty())
                        trackData.setTagFieldValues(key, val);
                }
            }
        }
    }

//  @Override
//  protected void copySpecificTagFields(Tag tag, Track track) {
//    ID3v24Tag v24Tag = (ID3v24Tag) tag;
//  }

  // TODO review (T?? [but not TXXX] are only supported at the moment)
  private void setMusiqueTagFieldValues(Track track, FieldKey key, ID3v24Tag tag) {
    List<TagField> fields;

    try {
      fields = tag.getFields(key);
    }
    catch (KeyNotFoundException ignored) {
      return;
    }

    for (TagField field : fields) {
      ID3v24Frame frame = (ID3v24Frame) field;
      if (frame.getBody() instanceof FrameBodyTRCK) {
        FrameBodyTRCK body = (FrameBodyTRCK) frame.getBody();
        if (FieldKey.TRACK.equals(key)) {
          track.getTrackData().addTrack(body.getTrackNo());
        }
        else if (FieldKey.TRACK_TOTAL.equals(key)) {
          track.getTrackData().addTrackTotal(body.getTrackTotal());
        }
      }
      else if (frame.getBody() instanceof FrameBodyTPOS) {
        FrameBodyTPOS body = (FrameBodyTPOS) frame.getBody();
        if (FieldKey.DISC_NO.equals(key)) {
          track.getTrackData().addDisc(body.getDiscNo());
        }
        else if (FieldKey.DISC_TOTAL.equals(key)) {
          track.getTrackData().addDiscTotal(body.getDiscTotal());
        }
      }
      else if (frame.getBody() instanceof FrameBodyCOMM) {
        FrameBodyCOMM body = (FrameBodyCOMM) frame.getBody();
        track.getTrackData().addComment(body.getText());
      }
      else if (frame.getBody() instanceof FrameBodyPOPM) {
        FrameBodyPOPM body = (FrameBodyPOPM) frame.getBody();
        track.getTrackData().addRating(String.valueOf(body.getRating()));
      }
      else if (frame.getBody() instanceof AbstractFrameBodyTextInfo) {
        AbstractFrameBodyTextInfo body = (AbstractFrameBodyTextInfo) frame.getBody();
        for (int i = 0; i < body.getNumberOfValues(); i++) {
          track.getTrackData().addTagFieldValues(key, body.getValueAtIndex(i));
        }
      }
    }
  }

}
TOP

Related Classes of com.tulskiy.musique.audio.formats.mp3.MP3FileReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.