2017-08-17 21 views
18

Tôi đang sử dụng Exo PlayerExtractorMediaSource để phát video trong ứng dụng Android của mình. Tôi đang tải xuống phương tiện từ máy chủ và lưu vào cơ sở dữ liệu cục bộ và vào một thời điểm cụ thể Báo thức tôi phát phương tiện này bằng cách sử dụng ConcatenatingMediaSource trong trình phát exo. nhưng trước tiên tôi kiểm tra xem tất cả các tập tin video đã tải xuống hay chưa và bắt đầu trình phát bằng nguồn phương tiện đã tải xuống. và nếu bất kỳ video không được tải về sau đó tôi muốn tải nó ở chế độ nền tại khi nó được tải về sau đó tôi muốn kèm phim này vào playlist đã tạo tôiLàm mới nguồn phương tiện trong exoplayer

Đây là mẫu mã

private void playAndUpdateVideo(ArrayList<String> mediaSourc) { 



     simpleExoPlayerView.setVisibility(View.VISIBLE); 
     simpleExoPlayerView.setDefaultArtwork(null); 

     mainHandler = new Handler(); 
     DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); 
     TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter); 
     TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); 
     dataSourceFactory = new DefaultDataSourceFactory(context, 
       Util.getUserAgent(context, "com.cloveritservices.hype"), bandwidthMeter); 
// 2. Create a default LoadControl 
     extractorsFactory = new DefaultExtractorsFactory(); 
     LoadControl loadControl = new DefaultLoadControl(); 

// 3. Create the player 
     player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl); 
     player.addListener(this); 

//Set media controller 
     simpleExoPlayerView.setUseController(false); 
     simpleExoPlayerView.requestFocus(); 
// Bind the player to the view. 
     simpleExoPlayerView.setPlayer(player); 




     MediaSource[] mediaSources = new MediaSource[mediaSourc.size()]; 
     for (int i=0;i<mediaSourc.size();i++) 
     { 

      mediaSources[i]= buildMediaSource(Uri.parse(mediaSourc.get(i))); 

     } 

     MediaSource mediaSource = mediaSources.length == 1 ? mediaSources[0] 
       : new ConcatenatingMediaSource(mediaSources); 
     LoopingMediaSource loopingSource = new LoopingMediaSource(mediaSource); 
     player.prepare(loopingSource); 
     SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); 
     boolean isChecked = settings.getBoolean("switch", false); 
     if (!isChecked) 
     player.setVolume(0f); 
     else player.setVolume(2f); 
     player.setPlayWhenReady(true); 

    } 

Và đây tôi đang kiểm tra tệp video được tải xuống hay không

if (CommonUtils.isExternalStorageExistAndWritable()) { 
       for (int i = 0; i < videoUrl.size(); i++) { 


        if (!new File(Environment.getExternalStorageDirectory().toString() + Constants.PROFILE_VIDEO_FOLDER + CommonUtils.fileFromUrl(videoUrl.get(i))).exists() && !CommonUtils.currentlyDownloading(context,CommonUtils.fileFromUrl(videoUrl.get(i)))) { 
         downloadByDownloadManager(videoUrl.get(i), CommonUtils.fileFromUrl(videoUrl.get(i))); 
         if (flag==Constants.FLAG_PLAY){downloadFlag=true;} 
        } 
       } 

      } else { 
       Toast.makeText(getApplicationContext(), "SD Card not mounted.Please Mount SD Card", Toast.LENGTH_SHORT).show(); 
      } 
      if (flag==Constants.FLAG_PLAY && !downloadFlag) 
      { 
       playAndUpdateVideo(videoUrl); 
      } 

    public void downloadByDownloadManager(String url, String fileName1) { 
     downloadUrl=url; 
     fileName=fileName1; 
     request = new DownloadManager.Request(Uri.parse(url)); 
     request.setDescription("video file"); 
     request.setTitle(fileName); 

     request.setNotificationVisibility(2); 
     request.allowScanningByMediaScanner(); 

        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); 
        request.setDestinationInExternalPublicDir(Constants.PROFILE_VIDEO_FOLDER, fileName); 
        DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); 

        manager.enqueue(request); 







     // get download service and enqueue file 



    } 

Vui lòng giúp cách thêm tệp video bị thiếu sau đó vào danh sách phát nếu nó chưa được tải xuống.

+0

Bạn muốn thêm nó vào danh sách phát sau khi tệp được tải xuống? –

+0

có nhưng không muốn intialize danh sách phát lại @ SagarPujari –

+0

bạn có thể chia sẻ mã mà bạn đang tải xuống tệp hay không. –

Trả lời

3

Để thêm tệp video mới vào danh sách phát của bạn, bạn cần triển khai MediaSource mới có thể xử lý danh sách các nguồn để kích hoạt thay đổi kích thước. Điều này khá đơn giản để đạt được, cách dễ nhất để thực hiện điều này là tạo một bản sửa đổi ConcaternatingMediaSource sử dụng danh sách thay vì mảng để lưu trữ và lặp qua các nguồn phương tiện. Sau đó, bạn thay thế ConcaternatingMediaSource trong playAndUpdateVideo bằng cách triển khai mới bằng danh sách. Điều này sẽ cho phép bạn thêm và xóa khỏi danh sách phát của mình như bạn muốn, bạn có thể nối thêm các tệp phương tiện mới khi trình nghe hoàn chỉnh tải xuống của bạn được kích hoạt. Đây là lớp học đầy đủ cho một triển khai nguồn phương tiện truyền thông sử dụng danh sách:

public final class DynamicMediaSource implements MediaSource { 

    private List<MediaSource> mediaSources; 
    private SparseArray<Timeline> timelines; 
    private SparseArray<Object> manifests; 
    private Map<MediaPeriod, Integer> sourceIndexByMediaPeriod; 
    private SparseArray<Boolean> duplicateFlags; 
    private boolean isRepeatOneAtomic; 

    private Listener listener; 
    private DynamicTimeline timeline; 

    /** 
    * @param mediaSources The {@link MediaSource}s to concatenate. It is valid for the same 
    *  {@link MediaSource} instance to be present more than once in the array. 
    */ 
    public DynamicMediaSource(List<MediaSource> mediaSources) { 
     this(false, mediaSources); 
    } 

    /** 
    * @param isRepeatOneAtomic Whether the concatenated media source shall be treated as atomic 
    *  (i.e., repeated in its entirety) when repeat mode is set to {@code Player.REPEAT_MODE_ONE}. 
    * @param mediaSources The {@link MediaSource}s to concatenate. It is valid for the same 
    *  {@link MediaSource} instance to be present more than once in the array. 
    */ 
    public DynamicMediaSource(boolean isRepeatOneAtomic, List<MediaSource> mediaSources) { 
     for (MediaSource mediaSource : mediaSources) { 
      Assertions.checkNotNull(mediaSource); 
     } 
     this.mediaSources = mediaSources; 
     this.isRepeatOneAtomic = isRepeatOneAtomic; 
     timelines = new SparseArray<Timeline>(); 
     manifests = new SparseArray<Object>(); 
     sourceIndexByMediaPeriod = new HashMap<>(); 
     duplicateFlags = buildDuplicateFlags(mediaSources); 
    } 

    @Override 
    public void prepareSource(ExoPlayer player, boolean isTopLevelSource, Listener listener) { 
     this.listener = listener; 
     for (int i = 0; i < mediaSources.size(); i++) { 
      if (!duplicateFlags.get(i)) { 
       final int index = i; 
       mediaSources.get(i).prepareSource(player, false, new Listener() { 
        @Override 
        public void onSourceInfoRefreshed(Timeline timeline, Object manifest) { 
         handleSourceInfoRefreshed(index, timeline, manifest); 
        } 
       }); 
      } 
     } 
    } 

    @Override 
    public void maybeThrowSourceInfoRefreshError() throws IOException { 
     for (int i = 0; i < mediaSources.size(); i++) { 
      if (!duplicateFlags.get(i)) { 
       mediaSources.get(i).maybeThrowSourceInfoRefreshError(); 
      } 
     } 
    } 

    @Override 
    public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator) { 
     int sourceIndex = timeline.getChildIndexByPeriodIndex(id.periodIndex); 
     MediaPeriodId periodIdInSource = 
      new MediaPeriodId(id.periodIndex - timeline.getFirstPeriodIndexByChildIndex(sourceIndex)); 
     MediaPeriod mediaPeriod = mediaSources.get(sourceIndex).createPeriod(periodIdInSource, allocator); 
     sourceIndexByMediaPeriod.put(mediaPeriod, sourceIndex); 
     return mediaPeriod; 
    } 

    @Override 
    public void releasePeriod(MediaPeriod mediaPeriod) { 
     int sourceIndex = sourceIndexByMediaPeriod.get(mediaPeriod); 
     sourceIndexByMediaPeriod.remove(mediaPeriod); 
     mediaSources.get(sourceIndex).releasePeriod(mediaPeriod); 
    } 

    @Override 
    public void releaseSource() { 
     for (int i = 0; i < mediaSources.size(); i++) { 
      if (!duplicateFlags.get(i)) { 
       mediaSources.get(i).releaseSource(); 
      } 
     } 
    } 

    private void handleSourceInfoRefreshed(int sourceFirstIndex, Timeline sourceTimeline, 
             Object sourceManifest) { 
     // Set the timeline and manifest. 
     timelines.put(sourceFirstIndex, sourceTimeline); 
     manifests.put(sourceFirstIndex, sourceManifest); 

     // Also set the timeline and manifest for any duplicate entries of the same source. 
     for (int i = sourceFirstIndex + 1; i < mediaSources.size(); i++) { 
      if (mediaSources.get(i).equals(mediaSources.get(sourceFirstIndex))) { 
       timelines.put(i, sourceTimeline); 
       manifests.put(i, sourceManifest); 
      } 
     } 

     for(int i= 0; i<mediaSources.size(); i++){ 
      if(timelines.get(i) == null){ 
       // Don't invoke the listener until all sources have timelines. 
       return; 
      } 
     } 

     timeline = new DynamicTimeline(timelines, isRepeatOneAtomic); 
     listener.onSourceInfoRefreshed(timeline, new ArrayList(asList(manifests))); 
    } 

    private static SparseArray<Boolean> buildDuplicateFlags(List<MediaSource> mediaSources) { 
     SparseArray<Boolean> duplicateFlags = new SparseArray<Boolean>(); 
     IdentityHashMap<MediaSource, Void> sources = new IdentityHashMap<>(mediaSources.size()); 
     for (int i = 0; i < mediaSources.size(); i++) { 
      MediaSource source = mediaSources.get(i); 
      if (!sources.containsKey(source)) { 
       sources.put(source, null); 
       duplicateFlags.append(i,false); 
      } else { 
       duplicateFlags.append(i,true); 
      } 
     } 
     return duplicateFlags; 
    } 

    /** 
    * A {@link Timeline} that is the concatenation of one or more {@link Timeline}s. 
    */ 
    public static final class DynamicTimeline extends AbstractConcatenatedTimeline { 

     private final SparseArray<Timeline> timelines; 
     private final int[] sourcePeriodOffsets; 
     private final int[] sourceWindowOffsets; 
     private final boolean isRepeatOneAtomic; 

     public DynamicTimeline(SparseArray<Timeline> timelines, boolean isRepeatOneAtomic) { 
      super(timelines.size()); 
      int[] sourcePeriodOffsets = new int[timelines.size()]; 
      int[] sourceWindowOffsets = new int[timelines.size()]; 
      long periodCount = 0; 
      int windowCount = 0; 
      for (int i = 0; i < timelines.size(); i++) { 
       Timeline timeline = timelines.get(i); 
       periodCount += timeline.getPeriodCount(); 
       Assertions.checkState(periodCount <= Integer.MAX_VALUE, 
        "ConcatenatingMediaSource children contain too many periods"); 
       sourcePeriodOffsets[i] = (int) periodCount; 
       windowCount += timeline.getWindowCount(); 
       sourceWindowOffsets[i] = windowCount; 
      } 
      this.timelines = timelines; 
      this.sourcePeriodOffsets = sourcePeriodOffsets; 
      this.sourceWindowOffsets = sourceWindowOffsets; 
      this.isRepeatOneAtomic = isRepeatOneAtomic; 
     } 

     @Override 
     public int getWindowCount() { 
      return sourceWindowOffsets[sourceWindowOffsets.length - 1]; 
     } 

     @Override 
     public int getPeriodCount() { 
      return sourcePeriodOffsets[sourcePeriodOffsets.length - 1]; 
     } 

     @Override 
     public int getNextWindowIndex(int windowIndex, @Player.RepeatMode int repeatMode) { 
      if (isRepeatOneAtomic && repeatMode == Player.REPEAT_MODE_ONE) { 
       repeatMode = Player.REPEAT_MODE_ALL; 
      } 
      return super.getNextWindowIndex(windowIndex, repeatMode); 
     } 

     @Override 
     public int getPreviousWindowIndex(int windowIndex, @Player.RepeatMode int repeatMode) { 
      if (isRepeatOneAtomic && repeatMode == Player.REPEAT_MODE_ONE) { 
       repeatMode = Player.REPEAT_MODE_ALL; 
      } 
      return super.getPreviousWindowIndex(windowIndex, repeatMode); 
     } 

     @Override 
     public int getChildIndexByPeriodIndex(int periodIndex) { 
      return Util.binarySearchFloor(sourcePeriodOffsets, periodIndex, true, false) + 1; 
     } 

     @Override 
     protected int getChildIndexByWindowIndex(int windowIndex) { 
      return Util.binarySearchFloor(sourceWindowOffsets, windowIndex, true, false) + 1; 
     } 

     @Override 
     protected int getChildIndexByChildUid(Object childUid) { 
      if (!(childUid instanceof Integer)) { 
       return C.INDEX_UNSET; 
      } 
      return (Integer) childUid; 
     } 

     @Override 
     protected Timeline getTimelineByChildIndex(int childIndex) { 
      return timelines.get(childIndex); 
     } 

     @Override 
     public int getFirstPeriodIndexByChildIndex(int childIndex) { 
      return childIndex == 0 ? 0 : sourcePeriodOffsets[childIndex - 1]; 
     } 

     @Override 
     protected int getFirstWindowIndexByChildIndex(int childIndex) { 
      return childIndex == 0 ? 0 : sourceWindowOffsets[childIndex - 1]; 
     } 

     @Override 
     protected Object getChildUidByChildIndex(int childIndex) { 
      return childIndex; 
     } 

    } 

} 

Để kiểm tra khi tập tin được tải về và cài đặt một download hoàn thành người biết lắng nghe, bạn có thể sử dụng một BroadcastReceiver. A detailed example of how to set up the BroadcastReceiver is provided here.

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