2012-01-23 20 views
9

Mô tả:Làm thế nào để có được thời gian của Audio Stream và tiếp tục âm thanh trực tuyến từ bất kỳ điểm nào

Tôi đã sau mã cho một máy nghe Audio. Tôi có thể tiếp tục phát lại âm thanh từ bất kỳ thời lượng nào bằng cách nhấp vào Progress Bar (giữa 0-to-mediaplayer.getDuration()). Nó hoạt động hoàn hảo để phát lại âm thanh.

Vấn đề trong Audio Streaming:

  • Khi tôi dòng một tập tin âm thanh từ một máy chủ Internet (nói s3-xô) nó bắt đầu truyền một cách chính xác.
  • Nhưng phương tiện mediaPlayer.getDuration() và mediaPlayer.getCurrentPosition() trả về giá trị sai. Khi bắt đầu phát trực tiếp mediaPlayer.getCurrentPosition() trả về 5 giờ.
  • Do điều này tôi không thể tiếp tục phát trực tuyến Âm thanh từ một thời lượng được chỉ định là Thời lượng luồng (Thời lượng 0-to-Stream).

Câu hỏi:

  1. Làm thế nào tôi có thể nhận được trong suốt thời gian của một dòng âm thanh
  2. Làm thế nào tôi có thể tiếp tục Audio Streaming từ một khoảng thời gian xác định. Đối với ví dụ cho một tệp có thời lượng 10 phút, tôi muốn bắt đầu phát trực tuyến từ ngày phút.

Code:

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

Thời gian được hiển thị trên thanh tiến trình.

Thời gian: 'Thời gian hiện tại'/'Tổng thời'

enter image description here

+0

@Arif: Tôi đang làm việc để tạo một trình phát đa phương tiện và nếu bạn giải quyết được vấn đề, bạn có gửi email cho tôi mã không? abuhamzah09 tại gmail dot com –

+0

điều khiển nào là 'LTDAudioPlayer'? –

+0

@AbuHamzah đó là MyAudioPlayer thay vì LTDAudioPlayer –

Trả lời

3

Đầu tiên vấn đề lớn là đặt hàng của bạn khởi tạo: bạn gọi getDuration trước khi bạn thực sự gọi setDataSource trong resetAndStartPlayer. MediaPlayer phải biết thời lượng mà không cần nguồn dữ liệu như thế nào?

Dưới đây là làm thế nào để làm điều đó đúng:

  1. gọi MediaPlayer.setDataSource() trong Activity.onCreate

  2. thực hiện AsyncTask, trong nó doInBackground gọi MediaPlayer.prepare(), điều này sẽ mất một trong khi phát trực tiếp từ http, nhưng sau khi kết thúc, người chơi phải biết chiều dài của phương tiện

  3. trong AsyncTask.onPostExecute gọi MediaPlayer.getDuration(), thành công nếu luồng được mở thành công; sau đó bạn có thể gọi MediaPlayer.bắt đầu()

Những điều quan trọng:

  • getDuration công trình sau khi chuẩn bị được gọi là
  • chuẩn bị có thể mất thời gian lâu hơn, và nên được gọi là trong chủ đề khác
  • bạn cũng có thể sử dụng prepareAsync và tránh AsyncTask, khi đó bạn sẽ sử dụng gọi lại setOnPreparedListener để gọi getDuration
+1

Tôi đánh giá cao sự quan tâm của bạn trong việc giải quyết vấn đề. Tôi đã sửa đổi mã để getDuration sau khi mediaPlayer được chuẩn bị trong mediaPlayer.onPrepared() ... Như tôi đã đề cập rằng vấn đề là trong streaming âm thanh, nó vẫn còn đó. Khi tôi phát âm thanh thậm chí nhỏ hơn. GetDuration trả về tôi 6 giờ và một cái gì đó. Nhưng khi tôi chơi âm thanh từ sdcard cùng một mã trả về thời gian chính xác. –

+0

Url ví dụ bài đăng của luồng từ xa của bạn. –

13

Hy vọng rằng nó có thể giải quyết được sự cố của bạn.

1) Thời gian và tiến độ của âm thanh suối

tôi đã nhìn vào code của bạn, bạn có một lỗi lớn trong mã của bạn để tính toán thời gian. Bạn tạo ngày mới (durationInMillis). Ngày thêm locallity của bạn tức là GMT + XX giờ, đó là lý do tại sao bạn nhận được 5- giờ trong sự bắt đầu của streaming. Bạn nên sử dụng phương pháp sau đây để tính toán 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) Scrubbing cho Stream.

MediaPlayer cho phép quét luồng âm thanh. Tôi đã thực hiện nó trong một trong các dự án của tôi, nhưng phải mất một thời gian. Phải mất một chút thời gian để tiếp tục phát lại âm thanh từ một vị trí khác.

+1

Cảm ơn talha. Tôi không chú ý đến điểm nhỏ này. – Arslan

Các vấn đề liên quan