Получить время выполнения видео, воспроизводимого в режиме просмотра видео?

#android

#Android

Вопрос:

Мне нужно получить время выполнения видео, которое воспроизводится в «Видеообзоре» (то есть время, показанное в левой части индикатора выполнения).

Любая помощь будет действительно оценена. Спасибо.

Ответ №1:

Вы можете получить продолжительность видео mVideoView.getDuration() , сначала установить индикатор выполнения на 0, а затем получить текущий прогресс видео mVideoView.getCurrentPosition(); и увеличить статус индикатора выполнения на основе текущего прогресса видео в процентах (%) (current * 100 / duration) . Я попробовал это, используя AsyncTask проверку этого полного примера.

main.xml

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<VideoView  android:id="@ id/my_Video_View"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />

    <ProgressBar android:layout_alignParentBottom="true"
  style="@android:style/Widget.ProgressBar.Horizontal"
  android:layout_width="fill_parent"
  android:layout_height="10dp"
  android:id="@ id/Progressbar"/>
</RelativeLayout>
  

VideoPlayActivity.java

 public class VideoPlayActivity extends Activity {

    ProgressBar mProgressBar;
    VideoView mVideoView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String path = Environment.getExternalStorageDirectory().toString();
        String filename = "/hr.3gp";

        mProgressBar = (ProgressBar) findViewById(R.id.Progressbar);
        mProgressBar.setProgress(0);
        mProgressBar.setMax(100);

        mVideoView = (VideoView) findViewById(R.id.my_Video_View);
        mVideoView.setVideoURI(Uri.parse(path filename));
        new MyAsync().execute();
    }

    private class MyAsync extends AsyncTask<Void, Integer, Void>
    {
        int duration = 0;
        int current = 0;
        @Override
        protected Void doInBackground(Void... params) {

            mVideoView.start();
            mVideoView.setOnPreparedListener(new OnPreparedListener() {

                public void onPrepared(MediaPlayer mp) {
                    duration = mVideoView.getDuration();
                }
            });

            do {
                current = mVideoView.getCurrentPosition();
                System.out.println("duration - "   duration   " current- "
                          current);
                try {
                    publishProgress((int) (current * 100 / duration));
                    if(mProgressBar.getProgress() >= 100){
                        break;
                    }
                } catch (Exception e) {
                }
            } while (mProgressBar.getProgress() <= 100);

            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            System.out.println(values[0]);
            mProgressBar.setProgress(values[0]);
        }
    }
}
  

Комментарии:

1. вы действительно можете позвонить mVideoView.start(); doInBackground ? нет исключения wrongUiThread?

2. привет, Лалит. Что произойдет, если пользователь выйдет из VideoView или закроет его? Как можно предотвратить бесконечное выполнение этой асинхронной задачи?

3. @android-user вы можете явно вызвать cancel() метод в своей AsyncTask

4. метод setOnPreparedListener должен вызываться из потока пользовательского интерфейса.

5. Весь ваш код фоновой задачи должен вызываться из потока пользовательского интерфейса

Ответ №2:

Для этой цели вы можете использовать поток, как показано ниже:

 videoView.start();
    videoView.setOnPreparedListener(new OnPreparedListener() {
        public void onPrepared(MediaPlayer mp) {
            running = true;
            final int duration = videoView.getDuration();

            new Thread(new Runnable() {
                public void run() {  
                    do{                         
                        textView.post(new Runnable() {
                         public void run() {
                            int time = (duration - videoView.getCurrentPosition())/1000;
                            textView.setText(time "");
                         }
                        });
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {                                      
                            e.printStackTrace();
                        }
                        if(!running) break;
                    }
                    while(videoView.getCurrentPosition()<duration);
                }
            }).start();                     
        }
    });
  

Комментарии:

1. это приводит к утечке в textview

2. @isudansh не беспокойтесь об утечках памяти, просто забудьте

Ответ №3:

Вы можете использовать getCurrentPosition() и getDuration() для вычисления прогресса.

Комментарии:

1. но, когда вызывать эти методы?, так как мне нужно отслеживать это каждую секунду.

2. @mr-narendra, вы можете обратиться к ответам от Nolesh и Алексея Тимощенко выше, установив таймер или режим ожидания потока на 1000 мс.

3. Я добился этого с помощью handler .

Ответ №4:

Я добился этого таким образом

 private void playVideo() {
    setViewNotVisibility();

    final String videoSource = "android.resource://"   getPackageName()   File.separator   R.raw.moviiegood;
    videoView.setKeepScreenOn(true);
    videoView.setVideoURI(Uri.parse(videoSource));
    videoView.setMediaController(null);
    videoView.setOnCompletionListener(myVideoViewCompletionListener);
    videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                                        @Override
                                        public void onPrepared(MediaPlayer mp) {
                                            startVideo();
                                            setDuration();
                                            timerCounter();
                                        }
                                    }

    );
}

private Timer timer;
private void timerCounter(){
    timer = new Timer();
    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    updateUI();
                }
            });
        }
    };
    timer.schedule(task, 0, 1000);
}

private int duration = 0;

private void setDuration(){
    duration = videoView.getDuration();
}

private void updateUI(){
    if (pbVideoView.getProgress() >= 100) {
        timer.cancel();
    }
    int current = videoView.getCurrentPosition();
    int progress = current * 100 / duration;
    pbVideoView.setProgress(progress);
}
  

Если у вас есть вопросы, не стесняйтесь задавать