2017-08-17 7 views
18

में रीफ्रेश मीडिया स्रोत मैं अपने एंड्रॉइड ऐप में वीडियो चलाने के लिए Exo PlayerExtractorMediaSource का उपयोग कर रहा हूं। मैं सर्वर से मीडिया डाउनलोड कर रहा हूं और स्थानीय डेटाबेस में और एक विशिष्ट समय पर सहेज रहा हूं अलार्म मैं इस मीडिया को एक्सो प्लेयर में ConcatenatingMediaSource का उपयोग करके चलाता हूं। लेकिन सबसे पहले मैं जांचता हूं कि डाउनलोड की गई सभी वीडियो फ़ाइल डाउनलोड की गई हैं या नहीं और डाउनलोड मीडिया स्रोत के साथ प्लेयर शुरू करें। और किसी भी वीडियो तो डाउनलोड नहीं किया जाता है, तो मैं जब यह तो डाउनलोड की समय पृष्ठभूमि में डाउनलोड कर सकें मैं अपने पहले से बनाए प्लेलिस्ट में इस वीडियो को जोड़ना चाहते हैंexoplayer

यह नमूना कोड

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

    } 

और यहाँ है मैं वीडियो फ़ाइल के लिए जाँच कर रहा हूँ कि यह डाउनलोड किया जाता है या नहीं

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 



    } 

कृपया मदद कि कैसे याद आ रही वीडियो फ़ाइल जोड़ने के लिए बाद में अगर यह डाउनलोड नहीं किया जाता प्लेलिस्ट में।

+0

फ़ाइल डाउनलोड होने के बाद आप इसे प्लेलिस्ट में जोड़ना चाहते हैं? –

+0

हाँ लेकिन न प्लेलिस्ट को फिर से intialize करने के लिए @ SagarPujari –

+0

यू कोड है जिसमें आप फ़ाइल डाउनलोड कर रहे हैं साझा कर सकते हैं चाहता हूँ। –

उत्तर

3

अपनी प्लेलिस्ट में नई वीडियो फाइलें जोड़ने के लिए, आपको एक नया MediaSource कार्यान्वयन की आवश्यकता है जो आकार बदलने में सक्षम बनाने के लिए स्रोतों की एक सूची को संभाल सकता है। यह हासिल करने के लिए काफी सरल है, ऐसा करने का सबसे आसान तरीका ConcaternatingMediaSource का संशोधित कार्यान्वयन बनाना है जो मीडिया स्रोतों को स्टोर और पुन: स्थापित करने के लिए सरणी के बजाय सूचियों का उपयोग करता है। फिर आप सूचियों का उपयोग करके नए कार्यान्वयन के साथ playAndUpdateVideo में ConcaternatingMediaSource को प्रतिस्थापित करें। यह आपकी इच्छानुसार आपकी प्लेलिस्ट से जोड़ने और निकालने की अनुमति देगा, जब आप डाउनलोड पूर्ण श्रोता ट्रिगर होते हैं तो आप नई मीडिया फ़ाइलों को जोड़ सकते हैं। जब फाइल डाउनलोड किया जाता है

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

    } 

} 

की जाँच करें और एक डाउनलोड पूरा श्रोता सेट करने के लिए, आप एक BroadcastReceiver उपयोग कर सकते हैं: यहाँ सूचियों का उपयोग कर एक मीडिया स्रोत कार्यान्वयन के लिए पूर्ण वर्ग है। A detailed example of how to set up the BroadcastReceiver is provided here.

संबंधित मुद्दे