2016-06-12 25 views
10

Tôi muốn tải xuống video đang phát trực tuyến trong ExoPlayer.Android ExoPlayer - tải xuống video (không DASH/HLS) và phát trực tuyến cùng một lúc

Là một sang một bên và thậm chí trước khi sử dụng ExoPlayer tôi đã tải xuống tệp từ luồng đầu vào do HttpURLConnection cung cấp và phát tệp từ bộ nhớ cục bộ. Điều này là ok, tuy nhiên nó không giải quyết vấn đề của tôi đồng thời streaming và bộ nhớ đệm.

ExoPlayer cũng cung cấp hệ thống bộ nhớ đệm và những hệ thống này dường như chỉ hoạt động đối với các loại luồng DASH hoặc HLS. Tôi đang sử dụng không ai trong số này và muốn cache mp4 với ExtractorRendererBuilder. (Chủ đề này được đề cập khá rộng rãi ở đây: https://github.com/google/ExoPlayer/issues/420).

DefaultHttpDataSource không có api để hiển thị HttpURLConnection nhưng tôi không chắc chắn tôi đang sử dụng lại luồng. Đây là mã từ các mẫu được cung cấp trong ExoPlayer.

@Override 
    public void buildRenderers(DemoPlayer player) { 
     Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE); 
     Handler mainHandler = player.getMainHandler(); 

     // Build the video and audio renderers. 
     DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(mainHandler, null); 
     DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter,userAgent); 
     ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri,dataSource,allocator, 
       BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE, mainHandler, player, 0); 
     MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, 
       sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, 
       mainHandler, player, 50); 
     MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource, 
       MediaCodecSelector.DEFAULT, null, true, mainHandler, player, 
       AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC); 
     TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player, 
       mainHandler.getLooper()); 

     // Invoke the callback. 
     TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT]; 
     renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer; 
     renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer; 
     renderers[DemoPlayer.TYPE_TEXT] = textRenderer; 
     player.onRenderers(renderers, bandwidthMeter); 
    } 

Những gì tôi đã làm tại là mở rộng DefaultHttpDataSource và sử dụng HttpURLConnection để có được một InputStream, hãy viết vào một tập tin trong getCacheDir(). Dưới đây là lớp mà kéo dài DefaultHttpDataSource:

public class CachedHttpDataSource extends DefaultHttpDataSource { 
    public CachedHttpDataSource(String userAgent, Predicate<String> contentTypePredicate) { 
     super(userAgent, contentTypePredicate); 
    } 

    public CachedHttpDataSource(String userAgent, Predicate<String> contentTypePredicate, TransferListener listener) { 
     super(userAgent, contentTypePredicate, listener); 
    } 

    public CachedHttpDataSource(String userAgent, Predicate<String> contentTypePredicate, TransferListener listener, int connectTimeoutMillis, int readTimeoutMillis) { 
     super(userAgent, contentTypePredicate, listener, connectTimeoutMillis, readTimeoutMillis); 
    } 

    public CachedHttpDataSource(String userAgent, Predicate<String> contentTypePredicate, TransferListener listener, int connectTimeoutMillis, int readTimeoutMillis, boolean allowCrossProtocolRedirects) { 
     super(userAgent, contentTypePredicate, listener, connectTimeoutMillis, readTimeoutMillis, allowCrossProtocolRedirects); 
    } 

    public HttpURLConnection getURLConnection(){ 
     HttpURLConnection connection = getConnection(); 

     return getConnection(); 
    } 
} 

tôi bây giờ có thể nhận được một InputStream qua getURLConnection() để lưu video vào một tập tin nhưng tôi không thực sự hạnh phúc bằng một InputStream một lần nữa để bộ nhớ cache video. Có bất kỳ API/hoặc phương pháp nào khác cung cấp quyền truy cập vào một mảng byte mà tôi có thể ghi vào một tệp trong khi phát trực tuyến không?

tìm kiếm stackoverflow khác của tôi đã không đưa ra một giải pháp được nêu ra:

Using cache in ExoPlayer

ExoPlayer cache

Cảm ơn thời gian và sự kiên nhẫn của bạn.

Trả lời

2

Tôi đã tìm thấy giải pháp chỉ với một vấn đề: tìm kiếm lùi hoặc tiến không hoạt động.

Đây là đoạn mã:

public void preparePlayer(String videoUri) { 
    MediaSource videoSource = 
      new ExtractorMediaSource(Uri.parse(videoUri), dataSourceFactory, extractorsFactory, handler, null); 
    exoPlayer.prepare(videoSource); 
    exoPlayer.setPlayWhenReady(true); 
} 

public DataSource.Factory buildDataSourceFactory() { 
    return new DataSource.Factory() { 
     @Override 
     public DataSource createDataSource() { 
      LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(CACHE_SIZE_BYTES); 
      File cacheDir = //Your cache dir 
      SimpleCache simpleCache = new SimpleCache(cacheDir, evictor); 
      DataSource dataSource = buildMyDataSourceFactory().createDataSource(); 
      int cacheFlags = CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_CACHE_UNBOUNDED_REQUESTS; 
      return new CacheDataSource(simpleCache, dataSource, cacheFlags, CACHE_SIZE_BYTES); 
     } 
    }; 
} 

private DefaultDataSource.Factory buildMyDataSourceFactory() { 
    return new DefaultDataSourceFactory(context, "jesty-android", new DefaultBandwidthMeter()); 
} 

Nguồn: https://github.com/google/ExoPlayer/issues/420#issuecomment-244652023

Các vấn đề liên quan