如何从服务器在线获取音频流的持续时间

时间:2016-02-20 17:06:30

标签: android

收集音频的总持续时间对我来说已经成为一个问题。我正在创建一个从在线播放音频的活动,我使用的是Android媒体播放器。现在音频能够正常播放,但我面临的问题是允许seek bar相应的音频进度。搜索栏设置正确但我已经看到getDuration返回0值。 以下是我的所作所为。

public class AudioDetails extends AppCompatActivity
    implements MediaPlayer.OnCompletionListener, SeekBar.OnSeekBarChangeListener {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.audios_details_activity);


    // Mediaplayer
    mp = new MediaPlayer();
    utils = new AudioUtilities();

    // Listeners
    songProgressBar.setOnSeekBarChangeListener(this); // Important
    mp.setOnCompletionListener(this); // Important



    // By default play first song
    playSong(0);

    /**
     * Play button click event
     * plays a song and changes button to pause image
     * pauses a song and changes button to play image
     * */
    btnPlay.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // check for already playing
            if(mp.isPlaying()){
                if(mp!=null){

                    mp.pause();
                    // Changing button image to play button
                    btnPlay.setImageResource(R.drawable.btn_play);
                }
            }else{
                // Resume song
                if(mp!=null){
                    mp.start();
                    // Changing button image to pause button
                    btnPlay.setImageResource(R.drawable.btn_pause);
                }
            }

        }
    });



}



/**
 * Function to play a song
 * @param songIndex - index of song
 * */
public void  playSong(int songIndex){
    // Play song
    try {
        mp.reset();
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {

            mp.setDataSource("http://test.com/test/upload/Twale_FLO.mp3");
            mp.prepareAsync();
            mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {                        
                    mp.start();
                    totalDuration =mp.getDuration();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }




        // set Progress bar values
        songProgressBar.setProgress(0);
        songProgressBar.setMax(99);

        // Updating progress bar
        updateProgressBar();


    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
       e.printStackTrace();
    }
}

/**
 * Update timer on seekbar
 * */
public void updateProgressBar() {
    mHandler.postDelayed(mUpdateTimeTask, 100);
}

/**
 * Background Runnable thread
 * */
private Runnable mUpdateTimeTask = new Runnable() {
    public void run() {
        long currentDuration = mp.getCurrentPosition();
        long totalDuration = mp.getDuration();

        // Displaying Total Duration time
       songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration));

        // Displaying time completed playing
        songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration));

        // Updating progress bar
        int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration ));
        Log.d("Progress", "" + progress);
        songProgressBar.setProgress(progress);

        // Running this thread after 100 milliseconds
        mHandler.postDelayed(this, 100);
    }
};

/**
 *
 * */
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {

}

/**
 * When user starts moving the progress handler
 * */
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
    // remove message Handler from updating progress bar
    mHandler.removeCallbacks(mUpdateTimeTask);
}

/**
 * When user stops moving the progress hanlder
 * */
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
    mHandler.removeCallbacks(mUpdateTimeTask);
    int totalDuration = mp.getDuration();
    int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration);

    // forward or backward to certain seconds
    mp.seekTo(currentPosition);

    // update timer progress again
    updateProgressBar();
}

/**
 * On Song Playing completed
 * if repeat is ON play same song again
 * if shuffle is ON play random song
 * */
@Override
public void onCompletion(MediaPlayer arg0) {

    // check for repeat is ON or OFF
    if(isRepeat){
        // repeat is on play same song again
        playSong(currentSongIndex);
    }  else{
            // play first song
            playSong(0);
            currentSongIndex = 0;
    }
}

@Override
public void onDestroy(){
    super.onDestroy();
    mp.release();
}}

请问如何通过Android从线上获取音频文件的总持续时间?提前谢谢。

1 个答案:

答案 0 :(得分:8)

此主题存在一些问题。

  1. getDuration()不适用于所有API版本。因此,它不确定什么时候会起作用,什么时候不起作用。
  2. 另一种方法是提取元数据。不幸的是,android MediaMetadataRetriever不能与在线资源一起使用。它仅适用于SD卡文件。
  3. 幸运的是有一个可以帮助我们的图书馆。我得到了那个图书馆的持续时间。所以,这些都是步骤。

    1. compile 'com.github.wseemann:FFmpegMediaMetadataRetriever:1.0.3'添加到您的gradle.build依赖
    2. 然后你可以通过以下代码获得持续时间

      FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
                  mmr.setDataSource("http://owatechinnovations.com/test/upload/Twale_FLO.mp3");
                  mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ALBUM);
                  mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ARTIST);
                  long duration =Long.parseLong(mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));
                  duration=duration/1000;
                  long minute=duration/(60);
                  long second=duration-(minute*60);
                  mmr.release();
                  your_text_view.setText(minute+":"+second);
      

      我得到结果" 4:18" 4分18秒希望它可以帮到你