Exemple #1
0
  @Override
  public void parse(Builder b) throws IOException {

    Logger.getLogger("org.jaudiotagger").setLevel(Level.OFF);

    try {
      audio = AudioFileIO.read(new File(src.path()));
    } catch (CannotReadException e) {
      System.out.println(
          "Detected empty or corrupt Music file '" + src.path() + "': " + e.getMessage());
    } catch (TagException e) {
      System.out.println(
          "Detected empty or corrupt Music file '" + src.path() + "': " + e.getMessage());
    } catch (ReadOnlyFileException e) {
      System.out.println(
          "Detected empty or corrupt Music file '" + src.path() + "': " + e.getMessage());
    } catch (InvalidAudioFrameException e) {
      System.out.println(
          "Detected empty or corrupt Music file '" + src.path() + "': " + e.getMessage());
    }
    try {
      builder = b;
      atts.add(NAME, token("." + src.name() + ".deepfs"));
      atts.add(TYPE, META);
      builder.startElem(FOLDER, atts);
      insertMusicMetadata();
      builder.endElem();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public String getSongTitle(String songFilePath) {

    String songTitle = "Title";

    // Try to get the song title from the ID3 tag.
    File songFile = new File(songFilePath);
    AudioFile audioFile = null;
    Tag tag = null;
    try {
      audioFile = AudioFileIO.read(songFile);
    } catch (CannotReadException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (TagException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ReadOnlyFileException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (InvalidAudioFrameException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    tag = audioFile.getTag();
    songTitle = tag.getFirst(FieldKey.TITLE);

    // If the ID3 tag doesn't give us the info we need, just use the file name.
    if (songTitle.equals("Title") || songTitle.isEmpty()) {
      int indexOfLastSlash = songTitle.lastIndexOf("/") + 1;
      int indexOfLastDot = songTitle.lastIndexOf(".");
      songTitle = songTitle.substring(indexOfLastSlash, indexOfLastDot);
    }

    return songTitle;
  }
  /**
   * Write tag to file
   *
   * @param tag
   * @param raf
   * @param rafTemp
   * @throws CannotWriteException
   * @throws IOException
   */
  public void write(Tag tag, RandomAccessFile raf, RandomAccessFile rafTemp)
      throws CannotWriteException, IOException {
    logger.config("Writing tag");

    MetadataBlockInfo blockInfo = new MetadataBlockInfo();

    // Read existing data
    FlacStreamReader flacStream = new FlacStreamReader(raf);
    try {
      flacStream.findStream();
    } catch (CannotReadException cre) {
      throw new CannotWriteException(cre.getMessage());
    }

    boolean isLastBlock = false;
    while (!isLastBlock) {
      MetadataBlockHeader mbh = MetadataBlockHeader.readHeader(raf);
      switch (mbh.getBlockType()) {
        case STREAMINFO:
          {
            blockInfo.streamInfoBlock =
                new MetadataBlock(mbh, new MetadataBlockDataStreamInfo(mbh, raf));
            break;
          }

        case VORBIS_COMMENT:
        case PADDING:
        case PICTURE:
          {
            // All these will be replaced by the new metadata so we just treat as padding in order
            // to determine how much space is already allocated in the file
            raf.seek(raf.getFilePointer() + mbh.getDataLength());
            MetadataBlockData mbd = new MetadataBlockDataPadding(mbh.getDataLength());
            blockInfo.metadataBlockPadding.add(new MetadataBlock(mbh, mbd));
            break;
          }
        case APPLICATION:
          {
            MetadataBlockData mbd = new MetadataBlockDataApplication(mbh, raf);
            blockInfo.metadataBlockApplication.add(new MetadataBlock(mbh, mbd));
            break;
          }
        case SEEKTABLE:
          {
            MetadataBlockData mbd = new MetadataBlockDataSeekTable(mbh, raf);
            blockInfo.metadataBlockSeekTable.add(new MetadataBlock(mbh, mbd));
            break;
          }
        case CUESHEET:
          {
            MetadataBlockData mbd = new MetadataBlockDataCueSheet(mbh, raf);
            blockInfo.metadataBlockCueSheet.add(new MetadataBlock(mbh, mbd));
            break;
          }
        default:
          {
            // What are the consequences of doing this
            raf.seek(raf.getFilePointer() + mbh.getDataLength());
            break;
          }
      }
      isLastBlock = mbh.isLastBlock();
    }

    // Number of bytes in the existing file available before audio data
    int availableRoom = computeAvailableRoom(blockInfo);

    // Minimum Size of the New tag data without padding
    int newTagSize = tc.convert(tag).limit();

    // Number of bytes required for new tagdata and other metadata blocks
    int neededRoom = newTagSize + computeNeededRoom(blockInfo);

    // Go to start of Flac within file
    raf.seek(flacStream.getStartOfFlacInFile());

    logger.config("Writing tag available bytes:" + availableRoom + ":needed bytes:" + neededRoom);

    // There is enough room to fit the tag without moving the audio just need to
    // adjust padding accordingly need to allow space for padding header if padding required
    if ((availableRoom == neededRoom)
        || (availableRoom > neededRoom + MetadataBlockHeader.HEADER_LENGTH)) {
      // Jump over Id3 (if exists) Flac and StreamInfoBlock
      raf.seek(flacStream.getStartOfFlacInFile() + FlacStreamReader.FLAC_STREAM_IDENTIFIER_LENGTH);

      // Write StreamInfo, we always write this first even if wasn't first in original spec
      raf.write(blockInfo.streamInfoBlock.getHeader().getBytesWithoutIsLastBlockFlag());
      raf.write(blockInfo.streamInfoBlock.getData().getBytes());

      // Write Application Blocks
      for (MetadataBlock aMetadataBlockApplication : blockInfo.metadataBlockApplication) {
        raf.write(aMetadataBlockApplication.getHeader().getBytesWithoutIsLastBlockFlag());
        raf.write(aMetadataBlockApplication.getData().getBytes());
      }

      // Write Seek Table Blocks
      for (MetadataBlock aMetadataBlockSeekTable : blockInfo.metadataBlockSeekTable) {
        raf.write(aMetadataBlockSeekTable.getHeader().getBytesWithoutIsLastBlockFlag());
        raf.write(aMetadataBlockSeekTable.getData().getBytes());
      }

      // Write Cue sheet Blocks
      for (MetadataBlock aMetadataBlockCueSheet : blockInfo.metadataBlockCueSheet) {
        raf.write(aMetadataBlockCueSheet.getHeader().getBytesWithoutIsLastBlockFlag());
        raf.write(aMetadataBlockCueSheet.getData().getBytes());
      }

      // Write tag (and padding)
      raf.getChannel().write(tc.convert(tag, availableRoom - neededRoom));
    }
    // Need to move audio
    else {
      // Skip to start of Audio

      // If Flac tag contains ID3header or something before start of official Flac header copy it
      // over
      if (flacStream.getStartOfFlacInFile() > 0) {
        raf.seek(0);
        rafTemp.getChannel().transferFrom(raf.getChannel(), 0, flacStream.getStartOfFlacInFile());
        rafTemp.seek(flacStream.getStartOfFlacInFile());
      }
      rafTemp.writeBytes(FlacStreamReader.FLAC_STREAM_IDENTIFIER);
      rafTemp.writeByte(0); // To ensure never set Last-metadata-block flag even if was before

      int uptoStreamHeaderSize =
          flacStream.getStartOfFlacInFile()
              + FlacStreamReader.FLAC_STREAM_IDENTIFIER_LENGTH
              + MetadataBlockHeader.BLOCK_TYPE_LENGTH;
      rafTemp.seek(uptoStreamHeaderSize);
      raf.seek(uptoStreamHeaderSize);

      rafTemp
          .getChannel()
          .transferFrom(
              raf.getChannel(),
              uptoStreamHeaderSize,
              MetadataBlockHeader.BLOCK_LENGTH
                  + MetadataBlockDataStreamInfo.STREAM_INFO_DATA_LENGTH);

      int dataStartSize =
          flacStream.getStartOfFlacInFile()
              + FlacStreamReader.FLAC_STREAM_IDENTIFIER_LENGTH
              + MetadataBlockHeader.HEADER_LENGTH
              + MetadataBlockDataStreamInfo.STREAM_INFO_DATA_LENGTH;
      rafTemp.seek(dataStartSize);

      // Write all the metadatablocks
      for (MetadataBlock aMetadataBlockApplication : blockInfo.metadataBlockApplication) {
        rafTemp.write(aMetadataBlockApplication.getHeader().getBytesWithoutIsLastBlockFlag());
        rafTemp.write(aMetadataBlockApplication.getData().getBytes());
      }

      for (MetadataBlock aMetadataBlockSeekTable : blockInfo.metadataBlockSeekTable) {
        rafTemp.write(aMetadataBlockSeekTable.getHeader().getBytesWithoutIsLastBlockFlag());
        rafTemp.write(aMetadataBlockSeekTable.getData().getBytes());
      }

      for (MetadataBlock aMetadataBlockCueSheet : blockInfo.metadataBlockCueSheet) {
        rafTemp.write(aMetadataBlockCueSheet.getHeader().getBytesWithoutIsLastBlockFlag());
        rafTemp.write(aMetadataBlockCueSheet.getData().getBytes());
      }

      // Write tag data use default padding
      rafTemp.write(tc.convert(tag, FlacTagCreator.DEFAULT_PADDING).array());
      // Write audio to new file
      raf.seek(dataStartSize + availableRoom);

      // Issue #385
      // Transfer 'size' bytes from raf at its current position to rafTemp at position but do it in
      // batches
      // to prevent OutOfMemory exceptions
      long amountToBeWritten = raf.getChannel().size() - raf.getChannel().position();
      long written = 0;
      long chunksize = TagOptionSingleton.getInstance().getWriteChunkSize();
      long count = amountToBeWritten / chunksize;
      long mod = amountToBeWritten % chunksize;
      for (int i = 0; i < count; i++) {
        written +=
            rafTemp
                .getChannel()
                .transferFrom(raf.getChannel(), rafTemp.getChannel().position(), chunksize);
        rafTemp.getChannel().position(rafTemp.getChannel().position() + chunksize);
      }
      written +=
          rafTemp.getChannel().transferFrom(raf.getChannel(), rafTemp.getChannel().position(), mod);
      if (written != amountToBeWritten) {
        throw new CannotWriteException(
            "Was meant to write "
                + amountToBeWritten
                + " bytes but only written "
                + written
                + " bytes");
      }
    }
  }