Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
280 views
in Technique[技术] by (71.8m points)

android - SeekBar not working properly with streaming audio from server

I have audio files on my mysql server. When audio is played seekbar mismatch with current position and repeat audio in background with difference of milliseconds. When I remove seekbar.setMax(mPlayer.getDuration) it works fine. And in Android:7 audio not playing properly. Please help me to solve this problem as soon as possible. Thank You in Advance.

  initilizeUI();

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            if (b && mPlayer.isPlaying()) {
                mPlayer.seekTo((mediaFileLengthInMilliseconds / 100) * i);
                Log.d("time", String.valueOf((mediaFileLengthInMilliseconds / 100) * seekBar.getProgress()));
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });

    return root;
}

@SuppressLint("ClickableViewAccessibility")
private void initilizeUI() {
    btn.setOnClickListener((View.OnClickListener) this);
    seekBar.setMax(99);
    mPlayer = new MediaPlayer();
    mPlayer.setOnBufferingUpdateListener(this);
    mPlayer.setOnCompletionListener(this);

}

@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {

    seekBar.setSecondaryProgress(percent);
}

@Override
public void onCompletion(MediaPlayer mp) {
    if (getActivity() != null) {
        int id = getResources().getIdentifier(String.valueOf(R.drawable.restartbtn), "drawable", getActivity().getPackageName());
        btn.setImageResource(id);
    }

}

@Override
public void onClick(View v) {
    if (v.getId() == R.id.imageButton) {

        try {

            mPlayer.setDataSource(audio_url);
            mPlayer.prepare(); // you must call this method after setup
            mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
            mmr.setDataSource(audio_url);
            mediaFileLengthInMilliseconds = Integer.parseInt(mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));

        } catch (Exception e) {
            e.printStackTrace();
        }

        if (!mPlayer.isPlaying()) {
            mPlayer.start();
            btn.setImageResource(R.drawable.pausebtn);
        } else {
            mPlayer.pause();
            btn.setImageResource(R.drawable.playbtn);
        }

        seekUpdation();
    }
}

Runnable run = new Runnable() {
    @Override
    public void run() {
        seekUpdation();
    }
};

public void seekUpdation() {
    if (mPlayer.isPlaying()) {
        seekBar.setProgress((int) (((float) mPlayer
                .getCurrentPosition() / mediaFileLengthInMilliseconds) * 100));
                   seekHandler.postDelayed(run, 1000);
    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mPlayer.isPlaying()) {
        mPlayer.stop();
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've checked your MP3 file and yes it is encoded in Variable Bit-Rate mode.

Possible solutions:

(1) Confirm if working: The CBR version of your MP3 (right-click and save, then put & test on your server). If seekbar is working as expected then your solution is to re-convert. You can use a tool to re-convert MP3 from VBR mode into CBR mode.

Try converting via this site : https://audio.online-convert.com/convert-to-mp3

If converting many files try : FFmpeg which runs on the commandline, can process multiple files in a folder.

(2) Your values from .getDuration() and .getCurrentPosition() must be divided by 1000.

.getDuration() will return a number in milliseconds. It takes 1000 m-secs to make 1 second. So your code must get expected value by dividing. eg: 5000 ms / 1000 = 5 seconds duration.

examples:

//# when using "getDuration"...
seekBar.setMax( mPlayer.getDuration() / 1000 );

//# when using "getCurrentPosition"...
seekBar.setProgress( mPlayer.getCurrentPosition() / 1000 );

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...