@Override protected boolean handlesTrack(MediaFormat mediaFormat) { return metadataParser.canParse(mediaFormat.mimeType); }
@SuppressWarnings("unchecked") @Override public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_INVOKE_RENDERER: invokeRendererInternal((T) msg.obj); return true; } return false; }
private void invokeRendererInternal(T metadata) { metadataRenderer.onMetadata(metadata); }
sampleSource, MediaCodecSelector.DEFAULT, null, true, player.getMainHandler(), player, AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC); MetadataTrackRenderer<List<Id3Frame>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper());
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource, null, true, player.getMainHandler(), player, AudioCapabilities.getCapabilities(context)); MetadataTrackRenderer<Map<String, Object>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper()); Eia608TrackRenderer closedCaptionRenderer = new Eia608TrackRenderer(sampleSource, player, mainHandler.getLooper());
Map<String, Object> metadata = new HashMap<>(); ParsableByteArray id3Data = new ParsableByteArray(data, size); int id3Size = parseId3Header(id3Data); String charset = getCharsetName(encoding); byte[] frame = new byte[frameSize - 1]; id3Data.readBytes(frame, 0, frameSize - 1); int firstZeroIndex = indexOfEOS(frame, 0, encoding); String description = new String(frame, 0, firstZeroIndex, charset); int valueStartIndex = firstZeroIndex + delimiterLength(encoding); int valueEndIndex = indexOfEOS(frame, valueStartIndex, encoding); String value = new String(frame, valueStartIndex, valueEndIndex - valueStartIndex, charset); metadata.put(TxxxMetadata.TYPE, new TxxxMetadata(description, value)); } else if (frameId0 == 'P' && frameId1 == 'R' && frameId2 == 'I' && frameId3 == 'V') { int firstZeroIndex = indexOf(frame, 0, (byte) 0); String owner = new String(frame, 0, firstZeroIndex, "ISO-8859-1"); byte[] privateData = new byte[frameSize - firstZeroIndex - 1]; System.arraycopy(frame, firstZeroIndex + 1, privateData, 0, frameSize - firstZeroIndex - 1); metadata.put(PrivMetadata.TYPE, new PrivMetadata(owner, privateData)); } else if (frameId0 == 'G' && frameId1 == 'E' && frameId2 == 'O' && frameId3 == 'B') { String charset = getCharsetName(encoding); byte[] frame = new byte[frameSize - 1]; id3Data.readBytes(frame, 0, frameSize - 1); int firstZeroIndex = indexOf(frame, 0, (byte) 0);
@Override protected void doSomeWork(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { continueBufferingSource(positionUs); if (!inputStreamEnded && pendingMetadata == null) { int result = readSource(positionUs, formatHolder, sampleHolder, false); if (result == SampleSource.SAMPLE_READ) { pendingMetadataTimestamp = sampleHolder.timeUs; try { pendingMetadata = metadataParser.parse(sampleHolder.data.array(), sampleHolder.size); } catch (IOException e) { throw new ExoPlaybackException(e); } sampleHolder.data.clear(); } else if (result == SampleSource.END_OF_STREAM) { inputStreamEnded = true; } } if (pendingMetadata != null && pendingMetadataTimestamp <= positionUs) { invokeRenderer(pendingMetadata); pendingMetadata = null; } }
@Override protected void onEnabled(int track, long positionUs, boolean joining) throws ExoPlaybackException { super.onEnabled(track, positionUs, joining); seekToInternal(); }
private static int indexOfEOS(byte[] data, int fromIndex, int encodingByte) { int terminationPos = indexOf(data, fromIndex, (byte) 0); // For single byte encoding charsets, we are done if (encodingByte == ID3_TEXT_ENCODING_ISO_8859_1 || encodingByte == ID3_TEXT_ENCODING_UTF_8) { return terminationPos; } // Otherwise, look for a two zero bytes while (terminationPos < data.length - 1) { if (data[terminationPos + 1] == (byte) 0) { return terminationPos; } terminationPos = indexOf(data, terminationPos + 1, (byte) 0); } return data.length; }
sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MetadataTrackRenderer<List<Id3Frame>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper());
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource, null, true, player.getMainHandler(), player, AudioCapabilities.getCapabilities(context)); MetadataTrackRenderer<Map<String, Object>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper()); Eia608TrackRenderer closedCaptionRenderer = new Eia608TrackRenderer(sampleSource, player, mainHandler.getLooper());
private void invokeRenderer(T metadata) { if (metadataHandler != null) { metadataHandler.obtainMessage(MSG_INVOKE_RENDERER, metadata).sendToTarget(); } else { invokeRendererInternal(metadata); } }
@Override protected void seekTo(long positionUs) throws ExoPlaybackException { super.seekTo(positionUs); seekToInternal(); }
sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MetadataTrackRenderer<List<Id3Frame>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper());
MediaCodecSelector.DEFAULT, null, true, player.getMainHandler(), player, AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC); MetadataTrackRenderer<Map<String, Object>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper());
sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MetadataTrackRenderer<List<Id3Frame>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper());
sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, handler, eventProxy, 50); MetadataTrackRenderer<List<Id3Frame>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), eventProxy, handler.getLooper());