Только загрузка видео в VideoView без мгновенного воспроизведения - PullRequest
4 голосов
/ 23 июля 2010

У меня возник вопрос, возможно ли в Android загрузить видеоданные в VideoView без мгновенного начала воспроизведения?Если да, то как я могу это сделать?

Ответы [ 7 ]

15 голосов
/ 20 августа 2013

Я также думал о том, чтобы показать thunbnail, как сказал sghael. Но я думаю, что это может привести к снижению производительности.

Так что я сейчас делаю, просто позвони

videoView.seekTo(1);

для пересылки видео на первую миллисекунду. Это хорошо работает для меня и быстро реализовать.

6 голосов
/ 09 июня 2011

Я также хотел, чтобы мой VideoView находился в состоянии паузы, когда началась активность. Я не мог найти простой способ, чтобы VideoView показывал первый (не черный) кадр видео.

В качестве обходного пути я создал миниатюру растрового изображения из видеоресурса, а затем поместил эту миниатюру в качестве фона для VideoView при запуске действия. Затем, когда видео начинает воспроизводиться, вам нужно только обнулить фон (иначе ваше воспроизводимое видео скрыто за фоновым изображением).

Bitmap thumbAsBitmap = null;
BitmapDrawable thumbAsDrawable = null;
private String current;

private void setupVideo() {
    try {

        setVideoFilePath();

        if (current == null || current.length() == 0) {
            Toast.makeText(PreviewMessage.this, "File URL/path is empty",
                    Toast.LENGTH_LONG).show();
        } else {
            keepScreenOn();

            mVideoView.setVideoPath(getDataSource(current));
            mVideoView.setOnCompletionListener(this);

            // create and place a thumbnail for the start state
            thumbAsBitmap = ThumbnailUtils.createVideoThumbnail(current, MediaStore.Images.Thumbnails.MINI_KIND);
            thumbAsDrawable = new BitmapDrawable(thumbAsBitmap);
            mVideoView.setBackgroundDrawable(thumbAsDrawable);

            mVideoView.pause();
            isPlaying = false;
        }

    } catch (Exception e) {
        if (mVideoView != null) {
            mVideoView.stopPlayback();
        }

    }
}

Тогда, где бы вы ни находились, вы можете сделать что-то вроде

    mPlay.setOnClickListener(new OnClickListener() {
        public void onClick(View view) {
            if(!isPlaying){
                keepScreenOn();
                mPlay.setText("Pause");

                // make sure to null the background so you can see your video play
                mVideoView.setBackgroundDrawable(null);

                mVideoView.start();
                isPlaying = true;
            } else {
                mPlay.setText("Play");
                mVideoView.pause();
                isPlaying = false;
            }
        }
    });
4 голосов
/ 23 июля 2010

VideoView не запустит воспроизведение автоматически, по крайней мере, если у вас есть MediaController.Вам нужно позвонить start(), чтобы начать воспроизведение.Следовательно, если вы не хотите, чтобы он начал воспроизведение, не звоните start().

0 голосов
/ 08 июня 2017

Я обнаружил, что просто сделать VideoView.seekTo(n) недостаточно на всех устройствах, чтобы показать первый кадр видео.

Если все, что вам нужно, это показать первый кадр, но не воспроизводить видеозатем вы можете просто сделать это, что полезно для отображения миниатюры видео:

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(context, uri);
Bitmap firstFrame = MediaMetadataRetriever.getFrameAtTime(0);
// Set firstFrame bitmap to ImageView...

Однако, чтобы надежно отображать первый кадр в тех случаях, когда вы хотите воспроизвести видео в какой-то момент после рендеринга,Начиная с взаимодействия с пользователем, мое решение состоит в том, чтобы зарегистрировать OnPreparedListener, а затем вызвать start().Я также регистрирую OnInfoListener, чтобы получать уведомления о начале рендеринга.Затем я проверяю, действительно ли информация является событием «начало рендеринга», и проверяю, впервые ли VideoView начал рендеринг.Если это так, я pause(), а затем seekTo(0).

Вот как это будет выглядеть:

private void showFirstFrame(final VideoView videoView, Uri uri) {
  videoView.setVideoURI(uri);

  final AtomicBoolean showedFirstFrame = new AtomicBoolean(false);

  videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
      // If this is our first time starting video rendering, pause and show first frame
      if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START
          && showedFirstFrame.compareAndSet(false, true)) {
        videoView.pause();
        videoView.seekTo(0);
      }

      return false;
    }
  });

  videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
      videoView.start();
    }
  });
}
0 голосов
/ 30 декабря 2013

Я нашел это возможным, запустив видео, подождав 1 миллисекунду и остановившись:

mediaController = new MediaController(this);
//set the path for video here                        
Uri video = Uri.parse(tempPath);
//set the VideoView id in xml file here    
vv_item = (VideoView) findViewById(R.id.itemdetails_vv_item);
vv_item.setMediaController(mediaController);
vv_item.setVideoURI(video);
vv_item.setOnPreparedListener(new OnPreparedListener() {
    public void onPrepared(MediaPlayer mp) {
        //first starting the video, when loaded
        vv_item.start();
        //then waiting for 1 millisecond
        try {
            Thread.sleep(1);
        } 
        catch (InterruptedException e) {
            //     TODO Auto-generated catch block
            e.printStackTrace();
        }
        //then pausing the video. i guess it's the first frame
        vv_item.pause();
        //showing the control buttons here                          
        mediaController.show();
    }
});
0 голосов
/ 19 ноября 2012
I suggest you for the following Code wherein i am running my application successfully

The Code is as Follows:

XML file:

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0" >

    <Button
        android:id="@+id/btnVideoGallery"
        android:layout_width="75dp"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:text="@string/gallery" />

    <Button
        android:id="@+id/btnCancel"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnVideoGallery"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="22dp"
        android:text="@string/cancel" />

    <TextView
        android:id="@+id/lblDisplayImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnCancel"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="@string/below_this_text_video_will_be_displayed"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#000000"
        android:textSize="13dp" />

    <VideoView
        android:id="@+id/vvDisplayVideo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/lblDisplayImage"
        android:layout_marginTop="15dp" />

</RelativeLayout>

    Java File:

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;

public class VideoActivity extends Activity {

    private Button btnVideoGallery,btnCancel;
    private VideoView vvDisplayVideo;
    /** The Constant PICK_VIDEO. */
    private static final int PICK_VIDEO=1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_options);

        btnVideoGallery=(Button)findViewById(R.id.btnVideoGallery);
        vvDisplayVideo=(VideoView)findViewById(R.id.vvDisplayVideo);
        btnCancel=(Button)findViewById(R.id.btnCancel);
        vvDisplayVideo.setVisibility(View.GONE);

        btnVideoGallery.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                Intent video=new Intent();
                video.setAction(Intent.ACTION_PICK);
                video.setType("video/*");
                startActivityForResult(video, PICK_VIDEO);

            }
        });

        btnCancel.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                Intent goStartUp=new Intent(VideoActivity.this, StartUpActivity.class);
                goStartUp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(goStartUp);
                finish();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        if (resultCode==Activity.RESULT_OK && requestCode == PICK_VIDEO) {

            vvDisplayVideo.setVisibility(View.VISIBLE);
            vvDisplayVideo.setVideoURI(data.getData());
            vvDisplayVideo.setFocusable(true);
            MediaController mc=new MediaController(this);
            vvDisplayVideo.setMediaController(mc);
            Log.i("True", "Executed");
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub

        Intent goStartUp=new Intent(VideoActivity.this, StartUpActivity.class);
        goStartUp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(goStartUp);
        finish();
        return super.onKeyDown(keyCode, event);
    }
}

Also you can modify the Manifest File as per your use:
<manifest ...
<uses-sdk...  />
<uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_VIDEO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />

<application .....
</application>

</manifest>
0 голосов
/ 15 марта 2012

Я использовал MediaController для своей кнопки воспроизведения, поэтому я использовал ответ ссылки ниже, в сочетании с этим фоновым растровым изображением для моего решения.

Событие для состояния воспроизведения VideoView или воспроизведения / паузы MediaController

...