2011-08-29 13 views
7

Pracowałem godzinami nad opracowaniem odpowiedniego odtwarzacza strumieniowego wideo w Androidzie i całkiem udanego tworzenia odtwarzacza, który może odtwarzać małe treści, takie jak utwory, zwiastuny itp. Bardzo dobrze. Jednak odtwarzacz pokazuje nietypowe zachowanie dla dużych treści, takich jak filmy i programy telewizyjne, ponieważ wymaga dużej ilości transmisji strumieniowej, odtwarzacz rozpoczyna opóźnienia w poszukiwaniu takich danych. Czy ktoś może mi pomóc rozwiązać rozwiązanie tego problemu?Jak utworzyć odtwarzacz wideo strumieniowego dla dużych treści?

z góry dzięki ...

Oto źródło:

public class player extends Activity implements OnErrorListener, 
    OnPreparedListener { 



/** Called when the activity is first created. */ 
private static final int UPDATE_FREQUENCY = 500; 

private static final int STEP_VALUE = 4000; 

private static final int DIALOG_KEY = 0; 

private TextView currentTime, duration; 

private VideoView videoView; 

private SeekBar seekbar = null; 

private View mediacontroller; 

private ProgressDialog progressDialog = null; 

private ImageButton playButton = null; 

private ImageButton prevButton = null; 

private ImageButton nextButton = null; 

private boolean isMoveingSeekBar = false; 

private boolean isMediaCtrlShown = false; 

private final Handler handler = new Handler(); 

private boolean isStarted = true; 

private String currentFile = "singham_320b"; 

private boolean isCustomSeekButtonClick = false; 

private boolean isPauseButtonClick = false; 

private static boolean isMyDialogShowing = false; 

private static int percentageBuffer = 0; 

private int mpCurrentPosition; 

int hh = 00, mm = 00, ss = 00, ms = 00; 

int i = 0; 

int previouPosition = 0; 

private Runnable onEverySecond=new Runnable() { 
     public void run() { 
       if (videoView!=null) { 
         seekbar.setProgress(videoView.getCurrentPosition()); 
       } 

       if (!isPauseButtonClick) { 
         mediacontroller.postDelayed(onEverySecond, 1000); 
       } 
     } 
}; 

private final Runnable updatePositionRunnable = new Runnable() 
{ 
    public void run() 
    { 
     updatePosition(); 
    } 
}; 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    setUpMyDialog(); 
    showMyDialog(); 

    videoView = (VideoView) findViewById(R.id.videoview); 

    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    seekbar = (SeekBar) findViewById(R.id.seekbar); 

    currentTime = (TextView) findViewById(R.id.currentTime); 

    playButton = (ImageButton) findViewById(R.id.play); 

    prevButton = (ImageButton) findViewById(R.id.prev); 

    nextButton = (ImageButton) findViewById(R.id.next); 

    duration = (TextView) findViewById(R.id.duration); 

    mediacontroller = findViewById(R.id.mediacontroller); 


    videoView.setOnErrorListener(this); 

    videoView.setOnPreparedListener(this); 

    videoView.setOnTouchListener(new View.OnTouchListener() 
    { 

     @Override 
     public boolean onTouch(View v, MotionEvent event) 
     { 

      if (!isMediaCtrlShown) 
      { 
       mediacontroller.setVisibility(View.GONE); 

       isMediaCtrlShown = true; 

      } 
      else 
      { 
       mediacontroller.setVisibility(View.VISIBLE); 

       isMediaCtrlShown = false; 
      } 
      return false; 
     } 
    }); 

    Uri video = Uri.parse("http://wpc.1B42.edgecastcdn.net/001B42/mobile/songs/pyaar_ka_punchnama/life_sahi_hai_320b.mp4"); 

    videoView.setVideoURI(video); 

    seekbar.setOnSeekBarChangeListener(seekBarChanged); 

    playButton.setOnClickListener(onButtonClick); 

    nextButton.setOnClickListener(onButtonClick); 

    prevButton.setOnClickListener(onButtonClick); 

} 

@Override 
public boolean onError(MediaPlayer mp, int what, int extra) { 
    // TODO Auto-generated method stub 
    return false; 
} 

public void calculateTime(int ms) { 

    ss = ms/1000; 

    mm = ss/60; 

    ss %= 60; 

    hh = mm/60; 

    mm %= 60; 

    hh %= 24; 

} 

@Override 
public void onPrepared(MediaPlayer mp) 
{ 
    dismissMyDialog(); 

    videoView.start(); 

    mediacontroller.setVisibility(View.VISIBLE); 

    isMediaCtrlShown = false; 

    seekbar.setProgress(0); 

    seekbar.setMax(videoView.getDuration()); 


    ms = videoView.getDuration(); 

    calculateTime(ms); 

    duration.setText("" + hh + ":" + mm + ":" + ss); 

    ms = videoView.getCurrentPosition(); 

    calculateTime(ms); 

    currentTime.setText("" + hh + ":" + mm + ":" + ss); 

    playButton.setImageResource(android.R.drawable.ic_media_pause); 

    updatePosition(); 

    isStarted = true; 

    mp.setOnBufferingUpdateListener(new OnBufferingUpdateListener() 
    { 
     // show updated information about the buffering progress 
     @Override 
     public void onBufferingUpdate(MediaPlayer mp, int percent) 
     { 
      Log.d(this.getClass().getName(), "percent: " + percent); 
      percentageBuffer = percent; 
      secondarySeekBarProgressUpdater(percent); 
      // progress.setSecondaryProgress(percent); 
      if (i == 0) 
      { 
       i = i + 1; 

       previouPosition = mp.getCurrentPosition(); 
      } 
      else if (i == 1) 
      { 
       if (mp.getCurrentPosition() == previouPosition) 
       { 
        if (!isPauseButtonClick) 
        { 

         showMyDialog(); 
         if (percent == 100) 
         { 
          dismissMyDialog(); 
         } 
        } 
       } 
       else 
       { 
        i = 0; 

        previouPosition = 0; 

        dismissMyDialog(); 
       } 
      } 
      else if (isCustomSeekButtonClick) 
      { 
       isCustomSeekButtonClick = false; 

       if (mpCurrentPosition == mp.getCurrentPosition()) 
       { 

        showMyDialog(); 
        if (percent == 100) 
        { 
         dismissMyDialog(); 
        } 
       } 
       else 
       { 
        dismissMyDialog(); 
       } 
      } 
     } 
    }); 

    mp.setOnSeekCompleteListener(new OnSeekCompleteListener() 
    { 
     public void onSeekComplete(MediaPlayer mp) 
     { 
      if (mp.isPlaying()) 
      { 

      } 
      else 
      { 
       onStart(); 

       onPause(); 

       onStart(); 

      } 

     } 
    }); 
} 


private SeekBar.OnSeekBarChangeListener seekBarChanged = new SeekBar.OnSeekBarChangeListener() 
{ 
    @Override 
    public void onStopTrackingTouch(SeekBar seekBar) 
    { 
     isMoveingSeekBar = false; 
    } 

    @Override 
    public void onStartTrackingTouch(SeekBar seekBar) 
    { 
     isMoveingSeekBar = true; 
    } 

    @Override 
    public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) 
    { 
     Log.e("",""+progress+""+percentageBuffer); 

     if (fromUser) 
     { 
      isCustomSeekButtonClick = fromUser; 

      videoView.seekTo(progress); 

      mpCurrentPosition = progress; 

      Log.e("OnSeekBarChangeListener", "onProgressChanged"); 
     } 
     if (isMoveingSeekBar) 
     { 
      videoView.seekTo(progress); 

      Log.i("OnSeekBarChangeListener", "onProgressChanged"); 
     } 
    } 
}; 
private View.OnClickListener onButtonClick = new View.OnClickListener() { 

    @Override 
    public void onClick(View v) 
    { 
     switch (v.getId()) 
     { 
     case R.id.play: 
     { 
      if (videoView.isPlaying()) 
      { 
       handler.removeCallbacks(updatePositionRunnable); 

       isPauseButtonClick = true; 

       videoView.pause(); 

       playButton.setImageResource(android.R.drawable.ic_media_play); 

      } 
      else 
      { 
       if (isStarted) 
       { 
        videoView.start(); 
        isPauseButtonClick = false; 
        playButton.setImageResource(android.R.drawable.ic_media_pause); 

        updatePosition(); 
       } 
       else 
       { 
        startPlay(currentFile); 
        isPauseButtonClick = false; 
        videoView.start(); 
       } 
      } 

      break; 
     } 
     case R.id.next: 
     { 
      int seekto = videoView.getCurrentPosition() + STEP_VALUE; 

      if (seekto > videoView.getDuration()) 

       seekto = videoView.getDuration(); 

      videoView.pause(); 

      videoView.seekTo(seekto); 
      /* 
      * try { Thread.sleep(15000); } catch (InterruptedException e) { 
      * // TODO Auto-generated catch block e.printStackTrace(); } 
      */ 
      // player.pause(); 
      videoView.start(); 

      break; 
     } 
     case R.id.prev: { 
      int seekto = videoView.getCurrentPosition() - STEP_VALUE; 

      if (seekto < 0) 
       seekto = 0; 

      videoView.pause(); 

      videoView.seekTo(seekto); 

      // player.pause(); 
      videoView.start(); 

      break; 
     } 
     } 
    } 
}; 

private void updatePosition() 
{ 
    handler.removeCallbacks(updatePositionRunnable); 

    seekbar.setProgress(videoView.getCurrentPosition()); 

    ms = videoView.getCurrentPosition(); 

    calculateTime(ms); 

    currentTime.setText("" + hh + ":" + mm + ":" + ss); 

    handler.postDelayed(updatePositionRunnable, UPDATE_FREQUENCY); 
} 

private void startPlay(String file) 
{ 
    Log.i("Selected: ", file); 

    // selelctedFile.setText(file); 
    seekbar.setProgress(0); 

    videoView.stopPlayback(); 

    videoView.start(); 

    seekbar.setMax(videoView.getDuration()); 

    playButton.setImageResource(android.R.drawable.ic_media_pause); 

    updatePosition(); 

    isStarted = true; 
} 
void setUpMyDialog() 
{ 
    if (progressDialog == null) 
    { 
     progressDialog = (ProgressDialog) onCreateDialog(DIALOG_KEY); 

     progressDialog = new ProgressDialog(player.this); 
     progressDialog.setMessage("Loading..."); 
     progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
    } 
} 

void showMyDialog() 
{ 
    Log.e("showMyDialog***", "****" + isMyDialogShowing); 

    if (!isMyDialogShowing) 
    { 
     isMyDialogShowing = true; 

     Log.e("showMyDialog: true***", "****" + isMyDialogShowing); 

     if (progressDialog != null && !progressDialog.isShowing()) 
     { 
      Log.e("showMyDialog: true***", "****progressDialog" + progressDialog.isShowing()); 

      progressDialog.show(); 
     } 
     else if(progressDialog == null) 
     { 
      setUpMyDialog(); 
      progressDialog.show(); 
     } 
    } 
} 

void dismissMyDialog() 
{ 
    Log.e("dismissMyDialog***", "****"); 

    if (progressDialog != null && progressDialog.isShowing()) 
    { 
     progressDialog.dismiss(); 
     progressDialog = null; 

     isMyDialogShowing = false; 
    } 
} 

void killMyDialog() 
{ 
    isMyDialogShowing = false; 
} 
private void secondarySeekBarProgressUpdater(int percent){ 
    seekbar.setSecondaryProgress(percent); 
} 
+0

Nie informując nas o tym, co zrobiliśmy do tej pory, i umieszczenie kodu, którego obecnie używasz, jest BARDZO nieprawdopodobne, aby ktokolwiek tutaj mógł rozwiązać ten problem. – FoamyGuy

+0

SO to witryna, w której można zadawać konkretne pytania dotyczące programowania. –

+1

Wiem, że SO jest specjalnie przeznaczony do programowania, nie pytam o konkretny kod, ale podstawową logikę do stworzenia takiego odtwarzacza strumieniowego, wtedy też dodaję swój kod służący do tworzenia mojego odtwarzacza – Jitu

Odpowiedz

2

Moja intuicja mówi na ten temat może być widokiem coś, koncentrując się na odtwarzaczu, zwłaszcza, że ​​to działa dobrze dla mniejszej zawartości . Czy myślałeś o sprawdzeniu transmisji strumieniowej serwera? Jeśli serwer nie jest w stanie przesyłać strumieniowo większych plików, niewiele może z tym zrobić gracz. Co więcej, możesz dostosować rozmiar pakietu z serwera, aby pomóc graczowi w zarządzaniu odtwarzaniem za pomocą mniejszych "ukąszeń" (przepraszam za kalambur) mediów na raz. Spróbuj skorzystać z bezpłatnego serwera strumieniowego Darwin Apple . Istnieje wersja dla Apache, Windows i innych, i jest bardzo konfigurowalna. Zdobądź zestaw plików o różnych rozmiarach i spróbuj ustalić, od jakiego rozmiaru odtwarzanie zaczyna się nie udać. Liczba ta da ci dużą wskazówkę, gdzie leży problem, czy to w rozmiarze przesyłanego pakietu serwera, dostępnej pamięci w środowisku Android, czy gdzie indziej. Niezależnie od liczby, spróbuj ustawić mniejszy rozmiar pakietu z serwera. To powinno dać twojemu graczowi mniej pracy do wykonania i, miejmy nadzieję, poprawić odtwarzanie.

Możesz uzyskać serwer Darwin z wielu miejsc online. Here is one such link. Wikipedia zawiera przydatne informacje i linki do tego serwera, find them here. Życzymy powodzenia w twoich badaniach na ten temat.

Frank.

+0

Udało nam się ładnie odtwarzać wideo, prawidłowo kodując filmy. Dzięki za odpowiedź.. :-) – Jitu

Powiązane problemy