2012-01-23 11 views
9

Opis:Jak uzyskać czas strumień audio i kontynuować strumienia audio z dowolnego punktu

Mam następujący kod dla odtwarzacza audio. Mogę kontynuować odtwarzanie dźwięku z dowolnego czasu, klikając pasek postępu (między 0 do mediaplayer.getDuration()). Działa idealnie do odtwarzania dźwięku.

Problem w Audio Streaming:

  • Kiedy strumień plik audio z serwerem internetowym (słownie s3-wiadro) zacznie strumieniowego poprawnie.
  • Ale mediaPlayer.getDuration() i mediaPlayer.getCurrentPosition() zwracają błędne wartości. Na początku przesyłania strumieniowego mediaPlayer.getCurrentPosition() zwraca 5 godzin.
  • Z tego powodu nie mogę kontynuować przesyłania strumieniowego audio z określonego czasu trwania strumienia (czas trwania 0 do strumienia) w postaci .

Pytania:

  1. Jak mogę uzyskać czas trwania strumienia audio
  2. Jak mogę kontynuować Audio Streaming z określonym czasie trwania. Na przykład dla pliku trwającego 10 minut chcę rozpocząć przesyłanie strumieniowe z 6. minut.

Kod:

public class MyAudioPlayer extends Activity 
implements OnClickListener{ 


    MediaPlayer mediaPlayer = null; 
    private boolean isPaused=false; 
    private boolean isStop = true; 

    String filePath = null; 
    String productName = null; 

    ImageButton btnPlay = null; 
    ImageButton btnPause = null; 
    ImageButton btnReset = null; 
    ImageButton btnStop = null; 

    AudioManager audioManager = null; 
    SeekBar volControl = null; 
    SeekBar progressControl = null; 
    TextView progressText = null; 
    long durationInMillis = -1; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.ltd_audio_player); 

     volControl = (SeekBar)findViewById(R.id.player_volume); 
     progressControl = (SeekBar)findViewById(R.id.player_seekbar); 
     progressText = (TextView) findViewById(R.id.player_progress_text); 

     btnPlay = (ImageButton) findViewById(R.id.ic_player_play); 

     btnPause = (ImageButton) findViewById(R.id.ic_player_pause); 

     btnReset = (ImageButton) findViewById(R.id.ic_player_reset); 

     btnStop = (ImageButton) findViewById(R.id.ic_player_stop); 

     btnPlay.setOnClickListener(this); 
     btnPause.setOnClickListener(this); 
     btnReset.setOnClickListener(this); 
     btnStop.setOnClickListener(this); 

     filePath = getIntent().getExtras().getString("localPath"); 

     this.setPlayer(); 
     this.resetAndStartPlayer(); 


    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     isPaused=false; 
     progressText.postDelayed(onEverySecond, 1000); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 

     isPaused=true; 
    } 
    private void setProgressControl() { 
     int maxVolume = mediaPlayer.getDuration(); 
     int curVolume = mediaPlayer.getCurrentPosition(); 

     progressControl.setMax(maxVolume); 
     progressControl.setProgress(curVolume); 
     progressControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 

      @Override 
      public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { 
       mediaPlayer.seekTo(progress); 
      } 

      @Override 
      public void onStartTrackingTouch(SeekBar seekBar) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onStopTrackingTouch(SeekBar seekBar) { 
       // TODO Auto-generated method stub 

      } 
     });  
    } 
    @Override 
    public void onClick(View v) { 
     switch(v.getId()){ 
     case R.id.ic_player_play: 
      if(isStop==true){ 
       try { 
        mediaPlayer.prepareAsync(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      }else{ 
       mediaPlayer.start(); 
       isStop = true; 
      } 
      break; 
     case R.id.ic_player_pause: 
      mediaPlayer.pause(); 
      break; 
     case R.id.ic_player_reset: 
      mediaPlayer.seekTo(0); 
      break; 
     case R.id.ic_player_stop: 
      isStop = true; 
      progressControl.setProgress(0); 
      mediaPlayer.stop(); 
      break; 
     } 

    } 
    private void resetAndStartPlayer(){ 
     try { 
      if(filePath!=null){ 
       mediaPlayer.setDataSource(filePath); 
       mediaPlayer.prepareAsync(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
    private void setPlayer(){ 

     getWindow().setFormat(PixelFormat.UNKNOWN); 
     mediaPlayer = new MediaPlayer();  

     mediaPlayer.setOnBufferingUpdateListener(new OnBufferingUpdateListener() { 

      @Override 
      public void onBufferingUpdate(MediaPlayer mp, int percent) { 
       progressControl.setSecondaryProgress((progressControl.getMax()/100)*percent); 

      } 
     }); 
     mediaPlayer.setOnPreparedListener(new OnPreparedListener() { 

      @Override 
      public void onPrepared(MediaPlayer mp) { 
       mediaPlayer.start(); 
       isStop=false; 
       durationInMillis = mediaPlayer.getDuration(); 
       MyAudioPlayer.this.setProgressControl(); 
      } 
     }); 
     mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    } 
    @Override 
    protected void onDestroy() { 
     // TODO Auto-generated method stub 
     mediaPlayer.release(); 
     super.onDestroy(); 
    } 
    protected void setProgressText() { 
     durationInMillis = mediaPlayer.getDuration(); 
     int curVolume = mediaPlayer.getCurrentPosition(); 
     long HOUR = 60*60*1000; 
     if(progressText!=null){ 
      if(durationInMillis>HOUR){ 
       progressText.setText(String.format("%1$tH:%1$tM:%1$tS", new Date(curVolume)) 
         +"/"+String.format("%1$tH:%1$tM:%1$tS", new Date(durationInMillis))); 
      }else{ 
       progressText.setText(String.format("%1$tM:%1$tS", new Date(curVolume)) 
         +"/"+String.format("%1$tM:%1$tS", new Date(durationInMillis))); 
      } 
     }  
    } 
    private Runnable onEverySecond=new Runnable() { 
     public void run() { 

      if (mediaPlayer!=null) { 
       progressControl.setProgress(mediaPlayer.getCurrentPosition()); 

       MyAudioPlayer.this.setProgressText(); 
      } 

      if (!isPaused) { 
       progressText.postDelayed(onEverySecond, 1000); 
      } 
     } 
    }; 
} 

czas jest wyświetlany powyżej paska postępu.

Czas: 'Aktualny Czas'/'Całkowity czas trwania'

enter image description here

+0

@Arif: Pracuję nad utworzeniem mediaplayer i jeśli rozwiązałeś problem, wyślesz mi e-mail z kodem? abuhamzah09 at gmail dot com –

+0

jaka kontrola to 'LTDAudioPlayer'? –

+0

@AbuHamzah to był MyAudioPlayer zamiast LTDAudioPlayer –

Odpowiedz

3

Pierwszy duży problem to kolejność inicjalizacji: zadzwonić getDuration zanim faktycznie nazwać setDataSource w resetAndStartPlayer. W jaki sposób MediaPlayer powinien znać czas trwania bez źródła danych?

Oto jak to zrobić poprawnie:

  1. rozmowę MediaPlayer.setDataSource() w Activity.onCreate

  2. wykonać AsyncTask, w jego doInBackground zadzwonić MediaPlayer.prepare(), to zajmie podczas gdy strumień jest przesyłany z http, ale po jego zakończeniu odtwarzacz powinien znać długość nośnika

  3. w wywołaniu AsyncTask.onPostExecute MediaPlayer.getDuration(), które powinno się powieść, jeśli strumień został pomyślnie otwarty; potem możesz zadzwonić do MediaPlayer.start()

Ważne rzeczy:

  • getDuration działa po Przygotowujemy został zwane
  • przygotowanie może potrwać dłuższy czas, i powinny być nazywane w innym wątku
  • można również użyć prepareAsync i uniknąć AsyncTask, następnie należy użyć wywołania zwrotnego setOnPreparedListener w celu wywołania getDuration
+1

Doceniam twoje zainteresowanie rozwiązaniem tego problemu. Zmodyfikowałem kod, aby uzyskaćDuration po MediaPlayer jest przygotowywany w mediaPlayer.onPrepared() ... Jak już wspomniałem, problem dotyczył przesyłania strumieniowego audio, nadal istnieje. Kiedy przesyłam strumień audio jeszcze mniejszym. GetDuration zwraca mi 6 godzin i coś. Ale kiedy odtwarzam dźwięk z sdcard, ten sam kod zwraca poprawny czas trwania. –

+0

Przykładowy adres URL zdalnego strumienia. –

13

Mam nadzieję, że to rozwiąże Twój problem.

1) Czas trwania i Progress Audio Stream

Szukałem w kodzie, masz poważny błąd w kodzie, aby obliczyć czas. Tworzysz nową datę (durationInMillis). Data dodaje lokalność, czyli GMT + XX godzin, dlatego uzyskujesz 5 godzin na początku streamingu. Powinieneś użyć następującej metody do obliczenia currentProgress/duration.

protected void setProgressText() { 

    final int HOUR = 60*60*1000; 
    final int MINUTE = 60*1000; 
    final int SECOND = 1000; 

    int durationInMillis = mediaPlayer.getDuration(); 
    int curVolume = mediaPlayer.getCurrentPosition(); 

    int durationHour = durationInMillis/HOUR; 
    int durationMint = (durationInMillis%HOUR)/MINUTE; 
    int durationSec = (durationInMillis%MINUTE)/SECOND; 

    int currentHour = curVolume/HOUR; 
    int currentMint = (curVolume%HOUR)/MINUTE; 
    int currentSec = (curVolume%MINUTE)/SECOND; 

    if(durationHour>0){ 
     System.out.println(" 1 = "+String.format("%02d:%02d:%02d/%02d:%02d:%02d", 
       currentHour,currentMint,currentSec, durationHour,durationMint,durationSec));    
    }else{ 
     System.out.println(" 1 = "+String.format("%02d:%02d/%02d:%02d", 
       currentMint,currentSec, durationMint,durationSec)); 
    } 
} 

2) Szorowanie dla Stream.

MediaPlayer umożliwia szorowanie strumienia audio. Zaimplementowałem go w jednym z moich projektów, ale zajmuje to trochę czasu. Przywracanie strumieniowego przesyłania dźwięku z innej lokalizacji zajmuje trochę czasu.

+1

Dzięki, Talha. Nie zauważyłem tego małego punktu. – Arslan

Powiązane problemy