2017-08-17 23 views
18

Android uygulamasında video oynatmak için Exo PlayerExtractorMediaSource kullanıyorum. Sunucudan medya indiriyorum ve yerel veritabanında ve belirli bir zamanda kaydediyorum Alarmı bu medyayı exo player'da ConcatenatingMediaSource kullanarak oynuyorum. ama önce indirilen tüm video dosyalarını kontrol edip etmediğimi kontrol edin ve indirilmiş medya kaynağıyla oynatıcıyı başlatın. Herhangi bir video daha sonra indirilen değilse ve ben benim zaten oluşturulmuş oynatma listesinde bu videoyu eklemek istediğiniz daha sonra indirilen zaman arka planda indirmek istiyorumExoplayer'da medya kaynağını yenileyin

Bu örnek kod

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); 

    } 

Ve burada ben indirilmesini video dosyası için kontrol ediyorum ya da olmasın

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 



    } 

eksik video dosyası eklemek için nasıl indirilir takdirde daha sonra Çalma listesine bu yardım edin.

+0

Dosya indirildikten sonra oynatma listesine eklemek ister misiniz? –

+0

evet ama çalma listesini tekrar intialize etmek istemiyorum @ SagarPujari –

+0

dosyayı indirmekte olduğunuz kodu paylaşabilirsiniz. –

cevap

3

Oynatma listenize yeni video dosyaları eklemek için yeniden boyutlandırmayı etkinleştirmek üzere kaynakların bir listesini işleyebilecek yeni bir MediaSource uygulamasına ihtiyacınız vardır. Bunu başarmak oldukça basittir, bunu yapmanın en kolay yolu, medya kaynakları üzerinde saklamak ve yinelemek için diziler yerine listeler kullanan ConcaternatingMediaSource'un değiştirilmiş bir uygulamasının oluşturulmasıdır. Sonra ConcaternatingMediaSource'u playAndUpdateVideo numaralı listeyi kullanarak yeni uygulama ile değiştirin. Bu, çalma listenizden istediğiniz şekilde ekleme ve çıkarma yapmanızı sağlar, indirme tamamladığınız dinleyici tetiklendiğinde yeni medya dosyalarını ekleyebilirsiniz.

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; 
     } 

    } 

} 

, bir BroadcastReceiver kullanabilirsiniz dosya indirildiğinde kontrol etmek ve bir indirme işlemi tamamlandı dinleyici ayarlamak için: Burada listelerini kullanarak bir medya kaynağı uygulanmasına tam sınıftır. A detailed example of how to set up the BroadcastReceiver is provided here.

İlgili konular