package com.exovlc; import java.io.IOException; import org.videolan.libvlc.LibVLC; import org.videolan.libvlc.Media.Track; import com.google.android.exoplayer.ExoPlaybackException; import com.google.android.exoplayer.MediaFormat; import com.google.android.exoplayer.MediaFormatHolder; import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.TrackInfo; import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.source.SampleExtractor; import com.google.android.exoplayer.util.Assertions; public class VLCSampleExtractor implements SampleExtractor { private final String uri; private TrackInfo[] trackInfos; private org.videolan.libvlc.Media.Track[] vlctracks; private LibVLC lib; private boolean prepared; private boolean hasVdo; private final org.videolan.libvlc.Media media; public VLCSampleExtractor(LibVLC vlc, String uri) throws ExoPlaybackException { if (vlc == null || uri == null) throw new ExoPlaybackException("null parms!"); this.uri = uri; this.lib = vlc; this.media = ExoVlcUtil.getMedia(vlc, uri); this.vlctracks = ExoVlcUtil.getAvailableTracks(media); if (this.vlctracks.length > 0) this.trackInfos = ExoVlcUtil.vlc2exoTracks(media.getDuration(), vlctracks, lib); else try { if ((hasVdo = vlc.hasVideoTrack(uri))) this.trackInfos = ExoVlcUtil.getDummyVdoTrack(media, com.exovlc.ExoVlcUtil.DUMM_VDO_MIME); } catch (IOException e1) { e1.printStackTrace(); } ExoVlcUtil.log(this, "get vlc tracks for uri = " + uri); } String getUri() { return uri; } public LibVLC getLibVLC() { return lib; } @Override public boolean prepare() throws IOException { System.out.println(">>>> VLCSampleExtractor.prepare() prepared = " + prepared); if (!prepared) { if (trackInfos == null || trackInfos.length == 0) throw new IOException(" No track is available (vlc read track)"); return (prepared = true); } return false; } @Override public TrackInfo[] getTrackInfos() { Assertions.checkState(prepared); TrackInfo[] r = new TrackInfo[trackInfos.length]; System.arraycopy(trackInfos, 0, r, 0, trackInfos.length); return r; } /* package */int getTrackCount() { return trackInfos.length; } @Override public void selectTrack(int track) { Assertions.checkState(prepared); if (vlctracks.length != trackInfos.length) return; if ((track < 0) && (track >= vlctracks.length)) { ExoVlcUtil.log(this, "selectTrack() out of range : " + track + "; track len=" + vlctracks.length); return; } Track vt = vlctracks[track]; ExoVlcUtil.log(this, "selectTrack() track : " + track); switch (vt.type) { case Track.Type.Video: lib.setVideoTrack(track); break; case Track.Type.Audio: if (lib.getAudioTrack() != track) lib.setAudioTrack(track); break; case Track.Type.Text: if (lib.getSpuTrack() != track) lib.setSpuTrack(track); } } @Override public void deselectTrack(int index) { Assertions.checkState(prepared); // TODO Auto-generated method stub } @Override public long getBufferedPositionUs() { Assertions.checkState(prepared); long l = lib.getLength(); if (l <= 0) return TrackRenderer.UNKNOWN_TIME_US; return l * ExoVlcUtil.MS_2_MICRO; } @Override public void seekTo(long positionUs) { Assertions.checkState(prepared); if (lib.isSeekable()) lib.setPosition(ExoVlcUtil.pos2percentage(positionUs, lib)); } @Override public void getTrackMediaFormat(int track, MediaFormatHolder mediaFormatHolder) { Assertions.checkState(prepared); if (track < 0 || track >= vlctracks.length) { ExoVlcUtil.log(this, "getTrackMediaFormat() out of range : " + track + "; track len=" + vlctracks.length); return; } mediaFormatHolder.format = MediaFormat.createFromFrameworkMediaFormatV16(ExoVlcUtil .track2mediaFormat(vlctracks[track])); mediaFormatHolder.drmInitData = null; } @Override public int readSample(int track, SampleHolder sampleHolder) throws IOException { Assertions.checkState(prepared); long ct = lib.getTime(); sampleHolder.timeUs = ct * ExoVlcUtil.MS_2_MICRO; sampleHolder.flags = android.media.MediaExtractor.SAMPLE_FLAG_SYNC; return ct >= 0L ? SampleSource.SAMPLE_READ : SampleSource.END_OF_STREAM; } @Override public synchronized void release() { if (lib != null) { ExoVlcUtil.releaseVLC(lib); lib = null; prepared = false; } } boolean isActiveTrack(int track) { Assertions.checkState(prepared); System.out.println(">>> VLCSampleExtractor.isActiveTrack() track = " + track); System.out.println(">>> VLCSampleExtractor.isActiveTrack() vlctracks.length = " + vlctracks.length); System.out.println(">>> VLCSampleExtractor.isActiveTrack() trackInfos.length = " + trackInfos.length); if (vlctracks.length != trackInfos.length) { if ((track < 0) && (track >= trackInfos.length)) { ExoVlcUtil.log(this, "getTrackMediaFormat() out of range : " + track + "; track len=" + trackInfos.length); return false; } /* * if(track == trackInfos.length - 1 ) return true; */ TrackInfo t = trackInfos[track]; System.out.println(">>> VLCSampleExtractor.isActiveTrack() track mime = " + t.mimeType); System.out.println(">>> VLCSampleExtractor.isActiveTrack() isVLCAudioMimeType = " + ExoVlcUtil.isVLCAudioMimeType(t.mimeType)); System.out.println(">>> VLCSampleExtractor.isActiveTrack() isVLCVideoMimeType= " + ExoVlcUtil.isVLCVideoMimeType(t.mimeType)); if ((ExoVlcUtil.isVLCAudioMimeType(t.mimeType) && track == lib.getAudioTrack()) || (ExoVlcUtil.isVLCVideoMimeType(t.mimeType))) return true; return false; } if ((track < 0) && (track >= vlctracks.length)) { ExoVlcUtil.log(this, "getTrackMediaFormat() out of range : " + track + "; track len=" + vlctracks.length); return false; } Track vt = vlctracks[track]; if ((vt.type == Track.Type.Video) || (vt.type == Track.Type.Audio && track == lib.getAudioTrack()) || (vt.type == Track.Type.Text && track == lib.getSpuTrack())) return true; return false; } boolean hasVideo() { return hasVdo; } }