Reproducción de HLS con ExoPlayer
Estoy intentando crear una visión muy simple extendiendo SurfaceView y haciendo el vídeo de ExoPlayer a su superficie. Quiero apoyar HLS y SÓLO HLS. Parece que obtener el audio de forma coherente, pero nunca veo vídeo prestados a la pantalla. Tengo curiosidad por lo que podría estar haciendo mal.
El único error que veo en mi Logcat es el siguiente:
- Android - Exoplayer 2 - reproduce múltiples sonidos / audio simultáneamente - MergingMediaSource
- ¿Es posible precargar múltiples secuencias con Exoplayer y reproducir varios videos simultáneamente?
- ¿Cómo escuchar mp3 url usando exoplayer?
- Cómo utilizar un solo jugador para los anuncios y el vídeo con google android Exoplayer
- ExoPlayer AudioTrack Tartamudez
E/OMXMaster﹕ A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
A continuación se muestra mi código.
private static final int BUFFER_SEGMENT_SIZE = 256 * 1024; private static final int BUFFER_SEGMENTS = 64; private ExoPlayer mExoPlayer; private Handler mHandler; private AudioCapabilitiesReceiver mAudioCapabilitiesReceiver; private AudioCapabilities mAudioCapabilities; private ManifestFetcher<HlsPlaylist> playlistFetcher; private String mUserAgent; String url = "http://solutions.brightcove.com/bcls/assets/videos/Great-Blue-Heron.m3u8"; public ExoPlayerView(Context context) { super(context); } public ExoPlayerView(Context context, AttributeSet attrs) { super(context, attrs); } public ExoPlayerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void init() { mHandler = new Handler(); mUserAgent = Util.getUserAgent(getContext(), "CX Video Player"); HlsPlaylistParser parser = new HlsPlaylistParser(); playlistFetcher = new ManifestFetcher<>(url, new DefaultUriDataSource(getContext(), mUserAgent), parser); mAudioCapabilitiesReceiver = new AudioCapabilitiesReceiver(getContext(), this); mAudioCapabilitiesReceiver.register(); } @Override public void play() { mExoPlayer.setPlayWhenReady(true); } @Override public void stop() { mExoPlayer.stop(); release(); } @Override public void pause() { mExoPlayer.setPlayWhenReady(false); } @Override public void seekTo(long timeMillis) { mExoPlayer.seekTo(timeMillis); } @Override public long getCurrentPosition() { return mExoPlayer.getCurrentPosition(); } @Override public boolean isPlaying() { return false; } @Override public void playNext() { } @Override public boolean isPlayingLastVideo() { return false; } @Override public int getDuration() { return (int)mExoPlayer.getDuration(); } @Override public void addVideo(Uri uri) { } @Override public void addVideos(List<Uri> uris) { } @Override public void release() { mAudioCapabilitiesReceiver.unregister(); mExoPlayer.release(); } @Override public void onSingleManifest(HlsPlaylist hlsPlaylist) { final int numRenderers = 2; LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE)); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); int[] variantIndices = null; if (hlsPlaylist instanceof HlsMasterPlaylist) { HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) hlsPlaylist; try { variantIndices = VideoFormatSelectorUtil.selectVideoFormatsForDefaultDisplay( getContext(), masterPlaylist.variants, null, false); } catch (MediaCodecUtil.DecoderQueryException e) { e.printStackTrace(); return; } if (variantIndices.length == 0) { return; } } DataSource dataSource = new DefaultUriDataSource(getContext(), bandwidthMeter, mUserAgent); HlsChunkSource hlsChunkSource = new HlsChunkSource(dataSource, url, hlsPlaylist, bandwidthMeter, variantIndices, HlsChunkSource.ADAPTIVE_MODE_SPLICE, mAudioCapabilities); HlsSampleSource hlsSampleSource = new HlsSampleSource(hlsChunkSource, loadControl, BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE); // Build the track renderers TrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(hlsSampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(hlsSampleSource); // Build the ExoPlayer and start playback mExoPlayer = ExoPlayer.Factory.newInstance(numRenderers); mExoPlayer.prepare(videoRenderer, audioRenderer); // Pass the surface to the video renderer. mExoPlayer.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, getHolder().getSurface()); mExoPlayer.setPlayWhenReady(true); } @Override public void onSingleManifestError(IOException e) { } @Override public void onAudioCapabilitiesChanged(AudioCapabilities audioCapabilities) { mAudioCapabilities = audioCapabilities; playlistFetcher.singleLoad(mHandler.getLooper(), this); } }
- ¿Hay una manera de utilizar ExoPlayer para recrear ThumbnailUtils.extractThumbnail
- Exoplayer tocando archivos m3u8 en Android
- ¿Cómo evitar que el exoplayer se recargue en caso de retroceso?
- MPEG-TS H.264 con ExoPlayer
- ¿Cómo jugar múltiples (máximo de cuatro en mi caso). M3u8 streaming de vídeo en una sola actividad en android?
- Obtención de pantalla en negro cuando se agrega ExoPlayer a GLSurfaceView
- Exoplayer lanza excepción de inicialización de decodificador para archivos mp4 grandes en android
- Uso del caché en ExoPlayer
Así que encontré mi problema. Después de volver a través del código de demostración, me di cuenta de que la demo SurfaceView se envolvió en com.google.android.exoplayer.AspectRatioFrameLayout. Después de envolver mi SurfaceView en este mismo diseño, el video comenzó mágicamente a jugar.
Tuve una situación similar en la que podía escuchar el audio, pero no de vídeo, sólo una pantalla en negro. Resulta que estaba tratando de enviar el mesagge de superficie establecida:
player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface);
Antes de que el procesamiento de vídeo fue realmente inicializado y listo, es por eso que sólo podía escuchar audio
- Android Mala calidad de imagen al guardar la imagen de takePicture devolución de llamada
- Cámara web externa para cámara a android usando usb