2015-02-18 11 views
15

मैं ExoPlayer पर प्रगति परिवर्तनों की निगरानी कैसे कर सकता हूं?
मैंने एक छिपा MediaController लागू करने और setOnSeekBarChangeListener विधियों को ओवरराइड करने का प्रयास किया, लेकिन अब सफलता के बिना। मैं सोच रहा हूं कि ExoPlayer प्रगति को सुनने का कोई और तरीका है या नहीं।एंड्रॉइड एक्सपोप्लेयर ऑन प्रोग्रेस चेंज

उत्तर

3

सुनिश्चित नहीं है कि यह सबसे अच्छा तरीका है, लेकिन मैंने इसे TrackRenderer ओवरलोड करके हासिल किया।

मैं videoPlayer.getBufferedPercentage() उपयोग कर रहा हूँ, लेकिन आप केवल का उपयोग कर TrackRenderer के द्वारा प्रतिशत खुद के रूप में अच्छी तरह की गणना करने, सक्षम हो सकता है getBufferedPositionUs() और getDurationUs()

public interface ProgressListener { 
    public void onProgressChange(long progress); 
} 

public class CustomVideoRenderer extends MediaCodecVideoTrackRenderer { 

    long progress = 0; 
    private final CopyOnWriteArraySet<ProgressListener> progressListeners = new CopyOnWriteArraySet(); 

    // [...] 
    // Skipped constructors 
    // [...] 

    public void doSomeWork(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { 
     super.doSomeWork(positionUs, elapsedRealtimeUs); 

     long tmpProgress = videoPlayer.getBufferedPercentage(); 

     if (tmpProgress != this.progress) { 
      this.progress = tmpProgress; 

      for (ProgressListener progressListener : this.progressListeners) { 
       progressListener.onProgressChange(progress); 
      } 
     } 
    } 

    public void addProgressListener(ProgressListener listener) { 
     this.progressListeners.add(listener); 
    } 

} 
8

मैं जानता हूँ कि इस सवाल का बहुत पुराना है। लेकिन, ExoPlayer को लागू करते समय मैंने इस पर उतरा। यह उन लोगों की मदद करना है जो बाद में ऐसा करते हैं :)

इसलिए, मैंने प्लेबैक की प्रगति को ट्रैक करने के लिए निम्न विधियों का पालन किया है। यह ExoPlayer Google डॉक्स में किया गया है। यह आवश्यकतानुसार काम करता है।

private void updateProgressBar() { 
    long duration = player == null ? 0 : player.getDuration(); 
    long position = player == null ? 0 : player.getCurrentPosition(); 
    if (!dragging) { 
     mSeekBar.setProgress(progressBarValue(position)); 
    } 
    long bufferedPosition = player == null ? 0 : player.getBufferedPosition(); 
    mSeekBar.setSecondaryProgress(progressBarValue(bufferedPosition)); 
    // Remove scheduled updates. 
    handler.removeCallbacks(updateProgressAction); 
    // Schedule an update if necessary. 
    int playbackState = player == null ? Player.STATE_IDLE : player.getPlaybackState(); 
    if (playbackState != Player.STATE_IDLE && playbackState != Player.STATE_ENDED) { 
     long delayMs; 
     if (player.getPlayWhenReady() && playbackState == Player.STATE_READY) { 
      delayMs = 1000 - (position % 1000); 
      if (delayMs < 200) { 
       delayMs += 1000; 
      } 
     } else { 
      delayMs = 1000; 
     } 
     handler.postDelayed(updateProgressAction, delayMs); 
    } 
} 

private final Runnable updateProgressAction = new Runnable() { 
    @Override 
    public void run() { 
     updateProgressBar(); 
    } 
}; 

हम updateProgressAction भीतर updateProgressBar() फोन बार-बार प्लेबैक बंद हो जाता है जब तक: Google ExoPlayer Docs

updateProgressBar() में

चेकआउट PlaybackControlView.javaSeekBar प्रगति को अद्यतन करने के कार्य है। जब भी कोई राज्य परिवर्तन होता है तो समारोह को पहली बार बुलाया जाता है। हम removeCallbacks(Runnable runnable) का उपयोग करते हैं ताकि देखभाल के लिए हमेशा एक updateProgressAction हो।

@Override 
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { 
    updateProgressBar(); 
} 

आशा है कि इससे मदद मिलती है!

+0

कौन वास्तव में मतलब है कि आप मतदान कर रहे हैं वास्तव में एक सही समाधान का एक प्रकार हो रहा है जो राज्य – Thomas

+0

@Thomas साथ onTouchListener उपयोग करें, क्योंकि exoplayer ही प्रगति की घटनाओं भी उत्पन्न करता है अक्सर यूआई के लिए। – kot331107

+0

@AnkitAggarwal मेरे पास कस्टम प्रगति पट्टी है, मैं वीडियो प्लज़ सहायता करते समय प्रगति कैसे अपडेट कर सकता हूं –

2

यह काम करता है कम से कम Exoplayer 2. साथ

चार प्लेबैक राज्यों है: STATE_IDLE, STATE_BUFFERING, STATE_READY और STATE_ENDED।

प्लेबैक स्थिति की जांच करना आसान है। कम से कम दो समाधान हैं: if-statement या switch-statement।

जो भी प्लेबैक स्थिति आप पर जा रही है, वह आपकी विधि निष्पादित कर सकती है या उदाहरण के लिए कुछ और सेट कर सकती है।

@Override 
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { 
    if (playbackState == ExoPlayer.STATE_ENDED) { 
     showControls(); 
     Toast.makeText(getApplicationContext(), "Playback ended", Toast.LENGTH_LONG).show(); 
    } 
    else if (playbackState == ExoPlayer.STATE_BUFFERING) 
    { 
     progressBar.setVisibility(View.VISIBLE); 
     Toast.makeText(getApplicationContext(), "Buffering..", Toast.LENGTH_SHORT).show(); 
    } 
    else if (playbackState == ExoPlayer.STATE_READY) 
    { 
     progressBar.setVisibility(View.INVISIBLE); 
    } 

} 
+0

क्या आप अपने समाधान के बारे में बेहतर विवरण प्रदान कर सकते हैं? –

+0

मुझे उम्मीद थी कि मदद करता है। – user7459244

0

(पूर्व के लिए SimpleExoPlayer।) अपने मौजूदा खिलाड़ी वर्ग का विस्तार और

public interface PlayerEventsListener { 
     void onSeek(int from, int to); 
     void onProgressUpdate(long progress); 
} 

private PlayerEventsListener mListener; 
private Handler mHandler; 
private Runnable mProgressUpdater; 
private boolean isUpdatingProgress = false; 

public SomePlayersConstructor(Activity activity, /*...*/) { 
    //... 
    mListener = (PlayerEventsListener) activity; 
    mHandler = new Handler(); 
    mProgressUpdater = new ProgressUpdater(); 
} 

// Here u gain access to seek events 
@Override 
public void seekTo(long positionMs) { 
    mListener.onSeek(-1, (int)positionMs/1000); 
    super.seekTo(positionMs); 
} 

@Override 
public void seekTo(int windowIndex, long positionMs) { 
    mListener.onSeek((int)getCurrentPosition()/1000, (int)positionMs/1000); 
    super.seekTo(windowIndex, positionMs); 
} 

// Here u gain access to progress 
public void startProgressUpdater() { 

    if (!isUpdatingProgress) { 
     mProgressUpdater.run(); 
     isUpdatingProgress = true; 
    } 
} 

private class ProgressUpdater implements Runnable { 

    private static final int TIME_UPDATE_MS = 500; 

    @Override 
    public void run() { 
     mListener.onProgressUpdate(getCurrentPosition()); 
     mHandler.postDelayed(mProgressUpdater, TIME_UPDATE_MS); 
    } 
} 

फिर जोड़ने खिलाड़ी गतिविधि के अंदर बस इंटरफ़ेस को लागू और player.startProgressUpdater();

1

साथ अद्यतन शुरू यह स्पष्ट वहाँ isn बनाने के लिए, प्रगति कार्यक्रम के लिए EventListener में एक निर्माण नहीं है, लेकिन आप हैंडलर को कॉल कर सकते हैं।आप अंदर postDelayed UpdateProgress() फ़ंक्शन अधिक जानकारी के लिए वर्तमान प्रगति

private void updateProgress(){ 

    //get current progress 
    long position = player == null ? 0 : player.getCurrentPosition(); 
    //updateProgress() will be called repeatedly, you can check 
    //player state to end it 
    handler.postDelayed(updateProgressAction,1000) 

} 

private final Runnable updateProgressAction = new Runnable() { 
    @Override 
    public void run() {   
     updateProgress(); 
    } 
}; 

प्राप्त करने के लिए, Exoplayer अंदर PlaybackControlView.java का स्रोत देखने

1

बस, अपने मेरे लिए काम कर इस प्रयास करें:

handler = new Handler(); 
runnable = new Runnable() { 
     @Override 
     public void run() { 
      progressbar.setProgress((int) ((exoPlayer.getCurrentPosition()*100)/exoPlayer.getDuration())); 
      handler.postDelayed(runnable, 1000); 
     } 
}; 
handler.postDelayed(runnable, 0); 

यहां,

  • getCurrentPosition(): वर्तमान प्लेबैक वापस करें मिलीसेकंड में के स्थिति।
  • getDuration(): मिलीसेकंड में ट्रैक की अवधि।
+1

आपके उत्तर के लिए धन्यवाद –

0

केवल, MotionEvent.ACTION_UP

SeekBar exo_progress = (SeekBar) findViewById(R.id.exo_progress); 
    exo_progress.setOnTouchListener(new View.OnTouchListener() { 
       @Override 
       public boolean onTouch(View v, MotionEvent event) { 
        if (event.getAction() == MotionEvent.ACTION_UP) { 
         //put your code here!! 
        } 
        return false; 
       } 
      }); 
संबंधित मुद्दे