6

我有一个问题,是否可以在 Android 中将视频数据加载到 a 中VideoView而不立即开始播放?如果是这样,我该怎么做?

4

7 回答 7

15

正如 sghael 所说,我还在考虑展示一个缩略图。但我认为这可能会导致性能下降。

所以我现在做的就是打电话

videoView.seekTo(1);

将视频转发到第一毫秒。这对我来说很好,并且可以快速实施。

于 2013-08-20T07:39:44.127 回答
7

I also wanted my VideoView to be in a paused state when the activity started. I could not find a simple way to have the VideoView show the first (non-black) frame of the video.

As a workaround, I created a bitmap thumbnail from the video resource, and then place that thumbnail as the background to the VideoView on activity start. Then when the Video begins playing, you only need to null out the background (or else your playing video is hidden behind your background image).

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

    }
}

Then whereever your playbutton is, you can do something like

    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;
            }
        }
    });
于 2011-06-09T15:35:49.440 回答
4

VideoView不会自动开始播放,至少如果你有一个MediaController附件。你需要打电话start()让它开始播放。因此,如果您不希望它开始播放,请不要调用start().

于 2010-07-23T12:06:11.587 回答
1

我发现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();
    }
  });
}
于 2017-06-07T21:55:24.910 回答
0

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>
于 2012-11-19T15:22:25.050 回答
0

我发现可以通过启动视频,等待 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();
    }
});
于 2013-12-30T05:12:25.593 回答
0

我使用 MediaController 作为我的播放按钮,所以我使用下面的链接答案结合这个背景位图作为我的解决方案。

VideoView 播放状态或 MediaController 播放/暂停的事件

于 2012-03-15T12:44:01.583 回答