首页 文章

媒体播放器进度更新到seekbar不顺畅?

提问于
浏览
12

我正在使用带录音机和播放器的应用程序 . 我正在使用mediaplayer播放录制的.wav文件,同时我想更新到搜索栏 . 一切都工作正常但我的问题是媒体播放器进度更新到seekbar没有顺利发生,如果我们playig一个小文件,搜索栏的拇指在几秒钟或之间跳跃 .

任何人都可以帮助我解决方法,使其顺利寻求seekbar的进展 . 我的代码如下所示 . 我被困在这里 .

mediaPlayerIntiate();
    mediaPlayerSetSource();
    mMediaPlayer.start();
    task = new TimerTask() {
                @Override
                public void run() {
                    Graphbar.post(new Runnable() {
                        @Override
                        public void run() {

                            if (mMediaPlayer != null) {

                                if (playButtonState == MediaMode.PLAY) {
                                    if (mMediaPlayer.isPlaying()) {
                                        Graphbar.setProgress(mMediaPlayer
                                                .getCurrentPosition());
                                        mediaPlayerUpdateTimer(mMediaPlayer
                                                .getCurrentPosition());
                                        enableRewindandForward();
                                    }
                                }

                            }

                        }
                    });
                }
            };
            timer = new Timer();
            timer.schedule(task, 0, 8);

5 回答

  • 4

    mMediaPlayer.getCurrentPosition() 返回当前时间(以毫秒为单位),您将此更新为Seekbar,最大容量为100.将一个公式设置为文件长度为100.尝试此功能

    MediaPlayer mMediaPlayer = new MediaPlayer();
        final SeekBar mSeelBar = new SeekBar(this);
        final int duration = mMediaPlayer.getDuration();
        final int amoungToupdate = duration / 100;
        Timer mTimer = new Timer();
        mTimer.schedule(new TimerTask() {
    
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
    
                    @Override
                    public void run() {
                        if (!(amoungToupdate * mSeelBar.getProgress() >= duration)) {
                            int p = mSeelBar.getProgress();
                            p += 1;
                            mSeelBar.setProgress(p);
                        }
                    }
                });
            };
        }, amoungToupdate);
    

    当媒体播放器开始播放时应该调用此过程 . 内

    mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
    
        @Override
        public void onPrepared(MediaPlayer mp) {
        **// call here**
    });
    

    Update

    在几秒钟内更新125次不是你应该做的事情 . 请增加更新SeekBar的间隔 . 我在阅读NullPointer的评论后添加了这个

  • 0

    这是我如何处理搜索栏;

    mediaPlayer.setOnPreparedListener(new OnPreparedListener(){
    
            @Override
            public void onPrepared(MediaPlayer mp) {
                mediaPlayer.start();
                new SeekBarHandler().execute();
        });
    

    现在我有一个名为SeekBarHandler的异步任务来处理搜索栏,如下所示:

    public class SeekBarHandler extends AsyncTask<Void, Void, Void> {
    
    @Override
    protected void onPostExecute(Void result) {
        Log.d("##########Seek Bar Handler ################","###################Destroyed##################");
        super.onPostExecute(result);
    }
    
    @Override
    protected void onProgressUpdate(Void... values) {
        seekBar.setProgress(mediaPlayer.getCurrentPosition());
        super.onProgressUpdate(values);
    }
    
    @Override
    protected Void doInBackground(Void... arg0) {
        while(mediaPlayer.isPlaying()&&isViewOn==true) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        onProgressUpdate();
        }
        return null;
    }
    
        }
    

    现在在我的onPause中,我终止了AsyncTask,因为当用户无法看到搜索栏时保持线程运行没有意义

    protected void onPause() {
        isViewOn=false;
        super.onPause();
        }
    

    在onResume上,我就像这样启动AsyncTaskAgain

    protected void onResume() {
        isViewOn=true;
        new SeekBarHandler().execute();
        super.onResume();
        }
    

    如您所见,我使用布尔标志isViewOn来检查视图是否打开以处理搜索条 .

  • 4
    player.prepare(); // or start()
    
    ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
    service.scheduleWithFixedDelay(new Runnable()
    {
      @Override
      public void run()
      {
        progressBar.setProgress(player.getCurrentPosition());
      }
    }, 1, 1, TimeUnit.MICROSECONDS);
    
  • 16

    seekbar.setProgress()只接受int . 因此,我们大多数人倾向于将经过的百分比传递给此方法 . 但是,如果您需要更平滑的进展,那么您可以使用持续时间(以毫秒为单位)作为MAX . 然后我们每毫秒更新一次搜索条的进度 . 下面是一个例子,我每隔15毫秒就更新一次,因为几乎每款Android手机的刷新率都是60 fps(每秒帧数) .

    try{
            mediaPlayer.start();
            seekbar.setProgress(0);
            seekbar.setMax(mediaPlayer.getDuration());
    
            // Updating progress bar
            seekHandler.postDelayed(updateSeekBar, 15);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    
    /**
     * Background Runnable thread
     * */
    private Runnable updateSeekBar = new Runnable() {
        public void run() {
            long totalDuration = mediaPlayer.getDuration();
            long currentDuration = mediaPlayer.getCurrentPosition();
    
            // Displaying Total Duration time
            remaining.setText(""+ milliSecondsToTimer(totalDuration-currentDuration));
            // Displaying time completed playing
            elapsed.setText(""+ milliSecondsToTimer(currentDuration));
    
            // Updating progress bar
            seekbar.setProgress((int)currentDuration);
    
            // Call this thread again after 15 milliseconds => ~ 1000/60fps
            seekHandler.postDelayed(this, 15);
        }
    };
    
    /**
     * Function to convert milliseconds time to
     * Timer Format
     * Hours:Minutes:Seconds
     * */
    public String milliSecondsToTimer(long milliseconds){
        String finalTimerString = "";
        String secondsString = "";
    
        // Convert total duration into time
        int hours = (int)( milliseconds / (1000*60*60));
        int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60);
        int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60) / 1000);
        // Add hours if there
        if(hours > 0){
            finalTimerString = hours + ":";
        }
    
        // Prepending 0 to seconds if it is one digit
        if(seconds < 10) {
            secondsString = "0" + seconds;
        }else {
            secondsString = "" + seconds;
        }
    
        finalTimerString = finalTimerString + minutes + ":" + secondsString;
    
        // return timer string
        return finalTimerString;
    }
    
  • 3

    你设计/实现了SeekBar的问题 . 虽然它运行良好,但您受限于所使用的段的组合(即 seekbar.setMax(int) )和处理程序的延迟时间 .

    话虽这么说,我将SeekBar子类化为使用ViewPropertyAnimators而不是Handler创建自己的SmoothSeekBar .

    在这里查看:https://github.com/Indatus/Android-SmoothSeekBar

相关问题