7

Ho lavorato per ore nello sviluppo di un vero riproduttore di video streaming in Android e con un discreto successo nella creazione di un lettore in grado di riprodurre piccoli contenuti come canzoni, trailer ecc. Ma il giocatore mostra un comportamento insolito per contenuti di grandi dimensioni come film e programmi TV in quanto richiede un sacco di streaming, il giocatore inizia a ritardare per tali dati. Qualcuno può aiutarmi a risolvere la soluzione per un tale problema.Come creare un lettore video in streaming per contenuti di grandi dimensioni?

Grazie in anticipo ...

Qui è la fonte:

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

Senza dirci cosa avete fatto finora e postando il codice che state usando, è MOLTO improbabile che qualcuno qui sia in grado di risolvere il problema. – FoamyGuy

+0

SO è un sito per porre domande specifiche di programmazione. –

+1

So che SO è specifico per la domanda di programmazione, non sto chiedendo un codice specifico ma una logica di base per la creazione di un tale streaming player, quindi aggiungo il mio codice usato per creare il mio lettore. – Jitu

risposta

2

mio intuito dice su questo si potrebbe essere vista qualcosa concentrandosi sul lettore, soprattutto perché funziona bene per i contenuti più piccoli . Hai pensato di controllare il server di streaming ? Se il server non è in grado di eseguire lo streaming di file più grandi, il lettore può fare ben poco. Inoltre, potresti essere in grado di regolare le dimensioni del pacchetto dal server per aiutare il giocatore a gestire la riproduzione usando piccoli "morsi" (scusate il gioco di parole) di media alla volta. Prova a utilizzare il server di streaming di Apple gratuito Darwin. C'è una versione per Apache, Windows e altri, ed è molto configurabile. Prendi una serie di file di varie dimensioni e cerca di stabilire a quale dimensione la riproduzione inizia a fallire. Questa cifra ti darà un grande indizio su dove si trova il problema, sia nella dimensione del pacchetto del server trasmesso, sia nella memoria disponibile nell'ambiente Android, o altrove. Qualunque sia la cifra, prova a impostare una dimensione del pacchetto più piccola dal server. Questo dovrebbe dare al tuo giocatore meno lavoro da fare e, si spera, migliorare la riproduzione.

È possibile ottenere il server Darwin da molti posti online. Here is one such link. Wikipedia ha alcune informazioni utili e alcuni collegamenti anche per questo server, find them here. Buona fortuna per le tue ricerche su questo.

Frank.

+0

Siamo riusciti a riprodurre video piacevolmente eseguendo la codifica dei video correttamente. Grazie per la tua risposta.. :-) – Jitu