Java Code Examples for com.google.android.exoplayer2.extractor.GaplessInfoHolder#GAPLESS_INFO_ID3_FRAME_PREDICATE

The following examples show how to use com.google.android.exoplayer2.extractor.GaplessInfoHolder#GAPLESS_INFO_ID3_FRAME_PREDICATE . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Mp3Extractor.java    From K-Sonic with MIT License 5 votes vote down vote up
/**
 * Peeks ID3 data from the input, including gapless playback information.
 *
 * @param input The {@link ExtractorInput} from which data should be peeked.
 * @throws IOException If an error occurred peeking from the input.
 * @throws InterruptedException If the thread was interrupted.
 */
private void peekId3Data(ExtractorInput input) throws IOException, InterruptedException {
  int peekedId3Bytes = 0;
  while (true) {
    input.peekFully(scratch.data, 0, Id3Decoder.ID3_HEADER_LENGTH);
    scratch.setPosition(0);
    if (scratch.readUnsignedInt24() != Id3Decoder.ID3_TAG) {
      // Not an ID3 tag.
      break;
    }
    scratch.skipBytes(3); // Skip major version, minor version and flags.
    int framesLength = scratch.readSynchSafeInt();
    int tagLength = Id3Decoder.ID3_HEADER_LENGTH + framesLength;

    if (metadata == null) {
      byte[] id3Data = new byte[tagLength];
      System.arraycopy(scratch.data, 0, id3Data, 0, Id3Decoder.ID3_HEADER_LENGTH);
      input.peekFully(id3Data, Id3Decoder.ID3_HEADER_LENGTH, framesLength);
      // We need to parse enough ID3 metadata to retrieve any gapless playback information even
      // if ID3 metadata parsing is disabled.
      Id3Decoder.FramePredicate id3FramePredicate = (flags & FLAG_DISABLE_ID3_METADATA) != 0
          ? GaplessInfoHolder.GAPLESS_INFO_ID3_FRAME_PREDICATE : null;
      metadata = new Id3Decoder(id3FramePredicate).decode(id3Data, tagLength);
      if (metadata != null) {
        gaplessInfoHolder.setFromMetadata(metadata);
      }
    } else {
      input.advancePeekPosition(framesLength);
    }

    peekedId3Bytes += tagLength;
  }

  input.resetPeekPosition();
  input.advancePeekPosition(peekedId3Bytes);
}
 
Example 2
Source File: Mp3Extractor.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private boolean synchronize(ExtractorInput input, boolean sniffing)
    throws IOException, InterruptedException {
  int validFrameCount = 0;
  int candidateSynchronizedHeaderData = 0;
  int peekedId3Bytes = 0;
  int searchedBytes = 0;
  int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
  input.resetPeekPosition();
  if (input.getPosition() == 0) {
    // We need to parse enough ID3 metadata to retrieve any gapless playback information even
    // if ID3 metadata parsing is disabled.
    boolean onlyDecodeGaplessInfoFrames = (flags & FLAG_DISABLE_ID3_METADATA) != 0;
    Id3Decoder.FramePredicate id3FramePredicate =
        onlyDecodeGaplessInfoFrames ? GaplessInfoHolder.GAPLESS_INFO_ID3_FRAME_PREDICATE : null;
    metadata = id3Peeker.peekId3Data(input, id3FramePredicate);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
    peekedId3Bytes = (int) input.getPeekPosition();
    if (!sniffing) {
      input.skipFully(peekedId3Bytes);
    }
  }
  while (true) {
    if (!input.peekFully(scratch.data, 0, 4, validFrameCount > 0)) {
      // We reached the end of the stream but found at least one valid frame.
      break;
    }
    scratch.setPosition(0);
    int headerData = scratch.readInt();
    int frameSize;
    if ((candidateSynchronizedHeaderData != 0
        && !headersMatch(headerData, candidateSynchronizedHeaderData))
        || (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
      // The header doesn't match the candidate header or is invalid. Try the next byte offset.
      if (searchedBytes++ == searchLimitBytes) {
        if (!sniffing) {
          throw new ParserException("Searched too many bytes.");
        }
        return false;
      }
      validFrameCount = 0;
      candidateSynchronizedHeaderData = 0;
      if (sniffing) {
        input.resetPeekPosition();
        input.advancePeekPosition(peekedId3Bytes + searchedBytes);
      } else {
        input.skipFully(1);
      }
    } else {
      // The header matches the candidate header and/or is valid.
      validFrameCount++;
      if (validFrameCount == 1) {
        MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
        candidateSynchronizedHeaderData = headerData;
      } else if (validFrameCount == 4) {
        break;
      }
      input.advancePeekPosition(frameSize - 4);
    }
  }
  // Prepare to read the synchronized frame.
  if (sniffing) {
    input.skipFully(peekedId3Bytes + searchedBytes);
  } else {
    input.resetPeekPosition();
  }
  synchronizedHeaderData = candidateSynchronizedHeaderData;
  return true;
}
 
Example 3
Source File: Mp3Extractor.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
private boolean synchronize(ExtractorInput input, boolean sniffing)
    throws IOException, InterruptedException {
  int validFrameCount = 0;
  int candidateSynchronizedHeaderData = 0;
  int peekedId3Bytes = 0;
  int searchedBytes = 0;
  int searchLimitBytes = sniffing ? MAX_SNIFF_BYTES : MAX_SYNC_BYTES;
  input.resetPeekPosition();
  if (input.getPosition() == 0) {
    // We need to parse enough ID3 metadata to retrieve any gapless playback information even
    // if ID3 metadata parsing is disabled.
    boolean onlyDecodeGaplessInfoFrames = (flags & FLAG_DISABLE_ID3_METADATA) != 0;
    Id3Decoder.FramePredicate id3FramePredicate =
        onlyDecodeGaplessInfoFrames ? GaplessInfoHolder.GAPLESS_INFO_ID3_FRAME_PREDICATE : null;
    metadata = id3Peeker.peekId3Data(input, id3FramePredicate);
    if (metadata != null) {
      gaplessInfoHolder.setFromMetadata(metadata);
    }
    peekedId3Bytes = (int) input.getPeekPosition();
    if (!sniffing) {
      input.skipFully(peekedId3Bytes);
    }
  }
  while (true) {
    if (!input.peekFully(scratch.data, 0, 4, validFrameCount > 0)) {
      // We reached the end of the stream but found at least one valid frame.
      break;
    }
    scratch.setPosition(0);
    int headerData = scratch.readInt();
    int frameSize;
    if ((candidateSynchronizedHeaderData != 0
        && !headersMatch(headerData, candidateSynchronizedHeaderData))
        || (frameSize = MpegAudioHeader.getFrameSize(headerData)) == C.LENGTH_UNSET) {
      // The header doesn't match the candidate header or is invalid. Try the next byte offset.
      if (searchedBytes++ == searchLimitBytes) {
        if (!sniffing) {
          throw new ParserException("Searched too many bytes.");
        }
        return false;
      }
      validFrameCount = 0;
      candidateSynchronizedHeaderData = 0;
      if (sniffing) {
        input.resetPeekPosition();
        input.advancePeekPosition(peekedId3Bytes + searchedBytes);
      } else {
        input.skipFully(1);
      }
    } else {
      // The header matches the candidate header and/or is valid.
      validFrameCount++;
      if (validFrameCount == 1) {
        MpegAudioHeader.populateHeader(headerData, synchronizedHeader);
        candidateSynchronizedHeaderData = headerData;
      } else if (validFrameCount == 4) {
        break;
      }
      input.advancePeekPosition(frameSize - 4);
    }
  }
  // Prepare to read the synchronized frame.
  if (sniffing) {
    input.skipFully(peekedId3Bytes + searchedBytes);
  } else {
    input.resetPeekPosition();
  }
  synchronizedHeaderData = candidateSynchronizedHeaderData;
  return true;
}