@Override protected boolean handlesTrack(MediaFormat mediaFormat) throws DecoderQueryException { // TODO: Use MediaCodecList.findDecoderForFormat on API 23. String mimeType = mediaFormat.mimeType; return MimeTypes.isVideo(mimeType) && (MimeTypes.VIDEO_UNKNOWN.equals(mimeType) || MediaCodecUtil.getDecoderInfo(mimeType, false) != null); }
@Override protected DecoderInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder) throws DecoderQueryException { if (MimeTypes.isPassthroughAudio(mimeType)) { return new DecoderInfo(RAW_DECODER_NAME, true); } return super.getDecoderInfo(mimeType, requiresSecureDecoder); }
@Override public void onError(Exception e) { String errorString = null; if (e instanceof UnsupportedDrmException) { // Special case DRM failures. UnsupportedDrmException unsupportedDrmException = (UnsupportedDrmException) e; errorString = getString(Util.SDK_INT < 18 ? R.string.error_drm_not_supported : unsupportedDrmException.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME ? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown); } else if (e instanceof ExoPlaybackException && e.getCause() instanceof DecoderInitializationException) { // Special case for decoder initialization failures. DecoderInitializationException decoderInitializationException = (DecoderInitializationException) e.getCause(); if (decoderInitializationException.decoderName == null) { if (decoderInitializationException.getCause() instanceof DecoderQueryException) { errorString = getString(R.string.error_querying_decoders); } else if (decoderInitializationException.secureDecoderRequired) { errorString = getString(R.string.error_no_secure_decoder, decoderInitializationException.mimeType); } else { errorString = getString(R.string.error_no_decoder, decoderInitializationException.mimeType); } } else { errorString = getString(R.string.error_instantiating_decoder, decoderInitializationException.decoderName); } } if (errorString != null) { Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_LONG).show(); } playerNeedsPrepare = true; updateButtonVisibilities(); showControls(); }
/** * Determines whether an individual format is playable, given an array of allowed container types, * whether HD formats should be filtered and a maximum decodable frame size in pixels. */ private static boolean isFormatPlayable(Format format, String[] allowedContainerMimeTypes, boolean filterHdFormats) throws DecoderQueryException { if (allowedContainerMimeTypes != null && !Util.contains(allowedContainerMimeTypes, format.mimeType)) { // Filtering format based on its container mime type. return false; } if (filterHdFormats && (format.width >= 1280 || format.height >= 720)) { // Filtering format because it's HD. return false; } if (format.width > 0 && format.height > 0) { if (Util.SDK_INT >= 21) { String videoMediaMimeType = MimeTypes.getVideoMediaMimeType(format.codecs); if (MimeTypes.VIDEO_UNKNOWN.equals(videoMediaMimeType)) { // Assume the video is H.264. videoMediaMimeType = MimeTypes.VIDEO_H264; } if (format.frameRate > 0) { return MediaCodecUtil.isSizeAndRateSupportedV21(videoMediaMimeType, false, format.width, format.height, format.frameRate); } else { return MediaCodecUtil.isSizeSupportedV21(videoMediaMimeType, false, format.width, format.height); } } // Assume the video is H.264. if (format.width * format.height > MediaCodecUtil.maxH264DecodableFrameSize()) { // Filtering format because it exceeds the maximum decodable frame size. return false; } } return true; }
@Override protected boolean handlesTrack(MediaCodecSelector mediaCodecSelector, MediaFormat mediaFormat) throws DecoderQueryException { String mimeType = mediaFormat.mimeType; return MimeTypes.isVideo(mimeType) && (MimeTypes.VIDEO_UNKNOWN.equals(mimeType) || mediaCodecSelector.getDecoderInfo(mimeType, false) != null); }
@Override protected boolean handlesTrack(MediaCodecSelector mediaCodecSelector, MediaFormat mediaFormat) throws DecoderQueryException { String mimeType = mediaFormat.mimeType; return MimeTypes.isAudio(mimeType) && (MimeTypes.AUDIO_UNKNOWN.equals(mimeType) || (allowPassthrough(mimeType) && mediaCodecSelector.getPassthroughDecoderInfo() != null) || mediaCodecSelector.getDecoderInfo(mimeType, false) != null); }
@Override protected DecoderInfo getDecoderInfo(MediaCodecSelector mediaCodecSelector, String mimeType, boolean requiresSecureDecoder) throws DecoderQueryException { if (allowPassthrough(mimeType)) { DecoderInfo passthroughDecoderInfo = mediaCodecSelector.getPassthroughDecoderInfo(); if (passthroughDecoderInfo != null) { passthroughEnabled = true; return passthroughDecoderInfo; } } passthroughEnabled = false; return super.getDecoderInfo(mediaCodecSelector, mimeType, requiresSecureDecoder); }
@Override public void onError(Exception e) { String errorString = null; if (e instanceof UnsupportedDrmException) { // Special case DRM failures. UnsupportedDrmException unsupportedDrmException = (UnsupportedDrmException) e; errorString = getString(Util.SDK_INT < 18 ? R.string.video_error_drm_not_supported : unsupportedDrmException.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME ? R.string.video_error_drm_unsupported_scheme : R.string.video_error_drm_unknown); } else if (e instanceof ExoPlaybackException && e.getCause() instanceof DecoderInitializationException) { // Special case for decoder initialization failures. DecoderInitializationException decoderInitializationException = (DecoderInitializationException) e.getCause(); if (decoderInitializationException.decoderName == null) { if (decoderInitializationException.getCause() instanceof DecoderQueryException) { errorString = getString(R.string.video_error_querying_decoders); } else if (decoderInitializationException.secureDecoderRequired) { errorString = getString(R.string.video_error_no_secure_decoder, decoderInitializationException.mimeType); } else { errorString = getString(R.string.video_error_no_decoder, decoderInitializationException.mimeType); } } else { errorString = getString(R.string.video_error_instantiating_decoder, decoderInitializationException.decoderName); } } if (errorString != null) { Toast.makeText(getApplicationContext(), errorString, Toast.LENGTH_LONG).show(); } playerNeedsPrepare = true; showControls(); }
@Override public void onSingleManifest(HlsPlaylist manifest) { Handler mainHandler = player.getMainHandler(); LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { callback.onRenderersError(e); return; } } DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE, audioCapabilities); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player, DemoPlayer.TYPE_VIDEO); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT]; renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer; renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer; callback.onRenderers(null, null, renderers, bandwidthMeter); }
@Override public void onSingleManifest(HlsPlaylist manifest) { if (canceled) { return; } Handler mainHandler = player.getMainHandler(); LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { player.onRenderersError(e); return; } if (variantIndices.length == 0) { player.onRenderersError(new IllegalStateException("No variants selected.")); return; } } DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, DemoPlayer.TYPE_VIDEO); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); 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()); TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT]; renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer; renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer; renderers[DemoPlayer.TYPE_METADATA] = id3Renderer; renderers[DemoPlayer.TYPE_TEXT] = closedCaptionRenderer; player.onRenderers(renderers, bandwidthMeter); }
@Override public void onSingleManifest(HlsPlaylist manifest) { if (canceled) { return; } Handler mainHandler = player.getMainHandler(); LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { player.onRenderersError(e); return; } if (variantIndices.length == 0) { player.onRenderersError(new IllegalStateException("No variants selected.")); return; } } DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE, audioCapabilities); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, MediaPlayer.TYPE_VIDEO); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); MetadataTrackRenderer<Map<String, Object>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper()); Eia608TrackRenderer closedCaptionRenderer = new Eia608TrackRenderer(sampleSource, player, mainHandler.getLooper()); TrackRenderer[] renderers = new TrackRenderer[MediaPlayer.RENDERER_COUNT]; renderers[MediaPlayer.TYPE_VIDEO] = videoRenderer; renderers[MediaPlayer.TYPE_AUDIO] = audioRenderer; renderers[MediaPlayer.TYPE_METADATA] = id3Renderer; renderers[MediaPlayer.TYPE_TEXT] = closedCaptionRenderer; player.onRenderers(null, null, renderers, bandwidthMeter); }
@Override protected final boolean handlesTrack(MediaFormat mediaFormat) throws DecoderQueryException { return handlesTrack(mediaCodecSelector, mediaFormat); }
@Override protected final boolean doPrepare(long positionUs) throws ExoPlaybackException { boolean allSourcesPrepared = true; for (int i = 0; i < sources.length; i++) { allSourcesPrepared &= sources[i].prepare(positionUs); } if (!allSourcesPrepared) { return false; } // The sources are all prepared. int totalSourceTrackCount = 0; for (int i = 0; i < sources.length; i++) { totalSourceTrackCount += sources[i].getTrackCount(); } long durationUs = 0; int handledTrackCount = 0; int[] handledSourceIndices = new int[totalSourceTrackCount]; int[] handledTrackIndices = new int[totalSourceTrackCount]; int sourceCount = sources.length; for (int sourceIndex = 0; sourceIndex < sourceCount; sourceIndex++) { SampleSourceReader source = sources[sourceIndex]; int sourceTrackCount = source.getTrackCount(); for (int trackIndex = 0; trackIndex < sourceTrackCount; trackIndex++) { MediaFormat format = source.getFormat(trackIndex); boolean handlesTrack; try { handlesTrack = handlesTrack(format); } catch (DecoderQueryException e) { throw new ExoPlaybackException(e); } if (handlesTrack) { handledSourceIndices[handledTrackCount] = sourceIndex; handledTrackIndices[handledTrackCount] = trackIndex; handledTrackCount++; if (durationUs == TrackRenderer.UNKNOWN_TIME_US) { // We've already encountered a track for which the duration is unknown, so the media // duration is unknown regardless of the duration of this track. } else { long trackDurationUs = format.durationUs; if (trackDurationUs == TrackRenderer.UNKNOWN_TIME_US) { durationUs = TrackRenderer.UNKNOWN_TIME_US; } else if (trackDurationUs == TrackRenderer.MATCH_LONGEST_US) { // Do nothing. } else { durationUs = Math.max(durationUs, trackDurationUs); } } } } } this.durationUs = durationUs; this.handledSourceIndices = Arrays.copyOf(handledSourceIndices, handledTrackCount); this.handledSourceTrackIndices = Arrays.copyOf(handledTrackIndices, handledTrackCount); return true; }
@Override public DecoderInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder) throws DecoderQueryException { return MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder); }
@Override public DecoderInfo getPassthroughDecoderInfo() throws DecoderQueryException { return MediaCodecUtil.getPassthroughDecoderInfo(); }
@Override public void onSingleManifest(HlsPlaylist manifest) { if (canceled) { return; } Handler mainHandler = player.getMainHandler(); LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { player.onRenderersError(e); return; } if (variantIndices.length == 0) { player.onRenderersError(new IllegalStateException("No variants selected.")); return; } } DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, Player.TYPE_VIDEO); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); 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()); TrackRenderer[] renderers = new TrackRenderer[Player.RENDERER_COUNT]; renderers[Player.TYPE_VIDEO] = videoRenderer; renderers[Player.TYPE_AUDIO] = audioRenderer; renderers[Player.TYPE_METADATA] = id3Renderer; renderers[Player.TYPE_TEXT] = closedCaptionRenderer; player.onRenderers(renderers, bandwidthMeter); }
@Override public void onSingleManifest(HlsPlaylist manifest) { if (canceled) { return; } Handler mainHandler = player.getMainHandler(); LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { player.onRenderersError(e); return; } if (variantIndices.length == 0) { player.onRenderersError(new IllegalStateException("No variants selected.")); return; } } DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE, audioCapabilities); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, VideoPlayer.TYPE_VIDEO); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); MetadataTrackRenderer<Map<String, Object>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper()); Eia608TrackRenderer closedCaptionRenderer = new Eia608TrackRenderer(sampleSource, player, mainHandler.getLooper()); TrackRenderer[] renderers = new TrackRenderer[VideoPlayer.RENDERER_COUNT]; renderers[VideoPlayer.TYPE_VIDEO] = videoRenderer; renderers[VideoPlayer.TYPE_AUDIO] = audioRenderer; renderers[VideoPlayer.TYPE_METADATA] = id3Renderer; renderers[VideoPlayer.TYPE_TEXT] = closedCaptionRenderer; player.onRenderers(null, null, renderers, bandwidthMeter); }
@Override public void onSingleManifest(HlsPlaylist manifest) { Handler mainHandler = player.getMainHandler(); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { callback.onRenderersError(e); return; } } DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE, audioCapabilities); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, true, 3, REQUESTED_BUFFER_SIZE, REQUESTED_BUFFER_DURATION_MS, mainHandler, player, DemoPlayer.TYPE_VIDEO); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); MetadataTrackRenderer<Map<String, Object>> id3Renderer = new MetadataTrackRenderer<Map<String, Object>>(sampleSource, new Id3Parser(), player.getId3MetadataRenderer(), mainHandler.getLooper()); Eia608TrackRenderer closedCaptionRenderer = new Eia608TrackRenderer(sampleSource, player, mainHandler.getLooper()); // Build the debug renderer. TrackRenderer debugRenderer = debugTextView != null ? new DebugTrackRenderer(debugTextView, player, videoRenderer) : null; TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT]; renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer; renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer; renderers[DemoPlayer.TYPE_TIMED_METADATA] = id3Renderer; renderers[DemoPlayer.TYPE_TEXT] = closedCaptionRenderer; renderers[DemoPlayer.TYPE_DEBUG] = debugRenderer; callback.onRenderers(null, null, renderers); }
@Override public void onSingleManifest(HlsPlaylist manifest) { if (canceled) { return; } Handler mainHandler = player.getMainHandler(); LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { player.onRenderersError(e); return; } if (variantIndices.length == 0) { player.onRenderersError(new IllegalStateException("No variants selected.")); return; } } DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, FlyingPlayer.TYPE_VIDEO); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); 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()); TrackRenderer[] renderers = new TrackRenderer[FlyingPlayer.RENDERER_COUNT]; renderers[FlyingPlayer.TYPE_VIDEO] = videoRenderer; renderers[FlyingPlayer.TYPE_AUDIO] = audioRenderer; renderers[FlyingPlayer.TYPE_METADATA] = id3Renderer; renderers[FlyingPlayer.TYPE_TEXT] = closedCaptionRenderer; player.onRenderers(renderers, bandwidthMeter); }
@Override public void onSingleManifest(HlsPlaylist manifest) { if (canceled) { return; } Handler mainHandler = player.getMainHandler(); //Allocator资源的分配,设置默认的资源分配(初始化一个空的资源池来装) //数据加载控制 LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); //如果数据传输是开放的,那创建一个带宽采样并更新的时候,可以记录传输的字节数 DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); //对于主播放列表,以最大的可能去发现设备能够播放的类型 int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { //解码器查询错误 player.onRenderersError(e); return; } if (variantIndices.length == 0) { //不支持播放,没有可以选择的变量 player.onRenderersError(new IllegalStateException("No variants selected.")); return; } } //创建采样源用于渲染 DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, OkPlayer.TYPE_VIDEO); //创建渲染器 //5000是最大加载事件 MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); 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()); //填充渲染器列表并回调 TrackRenderer[] renderers = new TrackRenderer[OkPlayer.RENDERER_COUNT]; renderers[OkPlayer.TYPE_VIDEO] = videoRenderer; renderers[OkPlayer.TYPE_AUDIO] = audioRenderer; // renderers[OkPlayer.TYPE_METADATA] = id3Renderer; // renderers[OkPlayer.TYPE_TEXT] = closedCaptionRenderer; player.onRenderers(renderers, bandwidthMeter); }
@Override public void onSingleManifest(HlsPlaylist manifest) { if (canceled) { return; } Handler mainHandler = player.getMainHandler(); LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (manifest instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) manifest; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( context, masterPlaylist.variants, null, false); } catch (DecoderQueryException e) { player.onRenderersError(e); return; } if (variantIndices.length == 0) { player.onRenderersError(new IllegalStateException("No variants selected.")); return; } } DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent); HlsChunkSource chunkSource = new HlsChunkSource(dataSource, url, manifest, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE, audioCapabilities); HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, DemoPlayer.TYPE_VIDEO); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, mainHandler, player, 50); MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource); MetadataTrackRenderer<Map<String, Object>> id3Renderer = new MetadataTrackRenderer<>( sampleSource, new Id3Parser(), player, mainHandler.getLooper()); Eia608TrackRenderer closedCaptionRenderer = new Eia608TrackRenderer(sampleSource, player, mainHandler.getLooper()); TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT]; renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer; renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer; renderers[DemoPlayer.TYPE_METADATA] = id3Renderer; renderers[DemoPlayer.TYPE_TEXT] = closedCaptionRenderer; player.onRenderers(null, null, renderers, bandwidthMeter); }
/** * Chooses a suitable subset from a number of video formats, to be rendered on the device's * default display. * * @param context A context. * @param formatWrappers Wrapped formats from which to select. * @param allowedContainerMimeTypes An array of allowed container mime types. Null allows all * mime types. * @param filterHdFormats True to filter HD formats. False otherwise. * @return An array holding the indices of the selected formats. * @throws DecoderQueryException */ public static int[] selectVideoFormatsForDefaultDisplay(Context context, List<? extends FormatWrapper> formatWrappers, String[] allowedContainerMimeTypes, boolean filterHdFormats) throws DecoderQueryException { WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); Point displaySize = getDisplaySize(display); return selectVideoFormats(formatWrappers, allowedContainerMimeTypes, filterHdFormats, true, displaySize.x, displaySize.y); }
/** * Chooses a suitable subset from a number of video formats, to be rendered on the device's * default display. * * @param context A context. * @param formatWrappers Wrapped formats from which to select. * @param allowedContainerMimeTypes An array of allowed container mime types. Null allows all * mime types. * @param filterHdFormats True to filter HD formats. False otherwise. * @return An array holding the indices of the selected formats. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ public static int[] selectVideoFormatsForDefaultDisplay(Context context, List<? extends FormatWrapper> formatWrappers, String[] allowedContainerMimeTypes, boolean filterHdFormats) throws DecoderQueryException { Point viewportSize = getViewportSize(context); return selectVideoFormats(formatWrappers, allowedContainerMimeTypes, filterHdFormats, true, viewportSize.x, viewportSize.y); }
/** * Returns a {@link DecoderInfo} for decoding media in the specified MIME type. * * @param mimeType The type of media to decode. * @param requiresSecureDecoder Whether a secure decoder is needed for decoding {@code mimeType}. * @return {@link DecoderInfo} for decoding media in the specified MIME type, or {@code null} if * no suitable decoder is available. */ protected DecoderInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder) throws DecoderQueryException { return MediaCodecUtil.getDecoderInfo(mimeType, requiresSecureDecoder); }
/** * Returns whether this renderer is capable of handling the provided track. * * @param mediaCodecSelector The decoder selector. * @param mediaFormat The format of the track. * @return True if the renderer can handle the track, false otherwise. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ protected abstract boolean handlesTrack(MediaCodecSelector mediaCodecSelector, MediaFormat mediaFormat) throws DecoderQueryException;
/** * Returns a {@link DecoderInfo} for a given format. * * @param mediaCodecSelector The decoder selector. * @param mimeType The mime type for which a decoder is required. * @param requiresSecureDecoder Whether a secure decoder is required. * @return A {@link DecoderInfo} describing the decoder to instantiate, or null if no suitable * decoder exists. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ protected DecoderInfo getDecoderInfo(MediaCodecSelector mediaCodecSelector, String mimeType, boolean requiresSecureDecoder) throws DecoderQueryException { return mediaCodecSelector.getDecoderInfo(mimeType, requiresSecureDecoder); }
/** * Returns whether this renderer is capable of handling the provided track. * * @param mediaFormat The format of the track. * @return True if the renderer can handle the track, false otherwise. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ protected abstract boolean handlesTrack(MediaFormat mediaFormat) throws DecoderQueryException;
/** * Selects a decoder to instantiate for a given mime type. * * @param mimeType The mime type for which a decoder is required. * @param requiresSecureDecoder Whether a secure decoder is required. * @return A {@link DecoderInfo} describing the decoder, or null if no suitable decoder exists. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ DecoderInfo getDecoderInfo(String mimeType, boolean requiresSecureDecoder) throws DecoderQueryException;
/** * Selects a decoder to instantiate for audio passthrough. * * @return A {@link DecoderInfo} describing the decoder, or null if no suitable decoder exists. * @throws DecoderQueryException Thrown if there was an error querying decoders. */ DecoderInfo getPassthroughDecoderInfo() throws DecoderQueryException;