Android SeekBar无法使用来自服务器的流式音频正常工作

Android SeekBar无法使用来自服务器的流式音频正常工作,android,audio-streaming,android-seekbar,Android,Audio Streaming,Android Seekbar,我的mysql服务器上有音频文件。当播放音频时,seekbar与当前位置不匹配,并在背景中以毫秒的差重复音频。当我删除seekbar.setMax(mPlayer.getDuration)时,它可以正常工作。在Android中:7音频播放不正常。请帮我尽快解决这个问题。先谢谢你 initilizeUI(); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Over

我的mysql服务器上有音频文件。当播放音频时,seekbar与当前位置不匹配,并在背景中以毫秒的差重复音频。当我删除seekbar.setMax(mPlayer.getDuration)时,它可以正常工作。在Android中:7音频播放不正常。请帮我尽快解决这个问题。先谢谢你

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

我检查了你的MP3文件,是的,它是以V可变Bit-Rate模式编码的

可能的解决方案

(1)确认是否工作:右键单击并保存,然后在服务器上进行测试。如果seekbar按预期工作,那么您的解决方案是重新转换。您可以使用工具将MP3从VBR模式重新转换为CBR模式

尝试通过此网站进行转换:

如果转换多个文件,请尝试:在命令行上运行,它可以处理文件夹中的多个文件

(2)来自
.getDuration()
.getCurrentPosition()
的值必须除以1000

.getDuration()
将以毫秒为单位返回一个数字。制作1秒需要1000米秒。因此,您的代码必须通过除法获得期望值。例如:5000毫秒/1000=5秒的持续时间

示例:


问题可能是音频文件本身(而不是代码)。下载
MediaInfo
并用它检查您的文件。或者使用44100hz立体声MP3进行测试,该MP3具有连续比特率(CBR)而非可变比特率(VBR)。您还可以共享一个指向这些神秘的“mysql服务器上的音频文件”的链接。供我们自己检查。请检查上述链接以及如何下载“MediaInfo”?我已检查了您的文件,VBR可能是查找的问题。看看我的回答是否对你有帮助。PS:这是操作系统的链接。在许多设备上仍然无法工作,seekbar没有设置音频的持续时间,seekbar进度终于设置好了。看看新添加的点(2)是否对您有帮助。mPlayer.getDuration()返回0。我想这是因为在尝试获取持续时间时,您的文件甚至没有加载(或者至少元数据没有准备好)。您的代码是否来自关于在设备存储上播放文件的教程?这样的文件可以立即获得持续时间,但不能在web仍在发送文件的小数据包时获得。尝试侦听加载了元数据的事件。我认为,当我使用原始文件测试它时,它工作正常,即使在最新版本中,它也可以与web url一起工作,但不是在所有设备中都可以。你能帮我做这个吗。
//# when using "getDuration"...
seekBar.setMax( mPlayer.getDuration() / 1000 );

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