【问题标题】:Only loading video into VideoView without instantly playing仅将视频加载到 VideoView 中而不立即播放
【发布时间】:2010-07-23 08:48:26
【问题描述】:

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

【问题讨论】:

    标签: android video android-videoview


    【解决方案1】:

    我也在考虑像 sghael 所说的那样显示一个缩略图。但我认为这可能会导致性能下降。

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

    videoView.seekTo(1);
    

    将视频转发到第一毫秒。这对我来说很好,而且实施起来很快。

    【讨论】:

    • 这不起作用,因为视频必须处于播放状态。
    • seekTo(1) 对我来说似乎很重要。如果没有搜索,我的视频将显示一个随机帧,通常是 1 秒后的帧,在我调用 start() 的一开始
    【解决方案2】:

    我还希望我的 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;
                }
            }
        });
    

    【讨论】:

      【解决方案3】:

      VideoView 不会自动开始播放,至少如果您附加了MediaController。您需要拨打start() 让它开始播放。因此,如果您不想让它开始播放,请不要拨打start()。

      【讨论】:

      • 我现在唯一遇到的问题是视频根本没有显示在视图中,我的意思是我希望它显示(仅第一帧)并具有控件(播放/暂停、停止、前进和后退)就在它下面...
      • MediaController 是一个弹出窗口——用户必须点击您的VideoView 才能出现。如果您想要始终可见的控件,您可能必须自己做。有关使用 MediaPlayer 和带有自定义“控制器”面板的 SurfaceView 的项目,请参阅 github.com/commonsguy/vidtry。关于第一帧,除了开始播放之外,您无法强制显示该帧,AFAIK。
      • 我如何知道视频何时加载?所以,我可以处理一些其他动作或向用户展示一些东西。
      • @xaif:我不知道你认为“加载”是什么意思,但有developer.android.com/reference/android/widget/…
      【解决方案4】:

      我发现仅使用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();
          }
        });
      }
      

      【讨论】:

        【解决方案5】:

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

        Event for VideoView playback state or MediaController play/pause

        【讨论】:

          【解决方案6】:

          我发现可以通过启动视频,等待 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();
              }
          });
          

          【讨论】:

            【解决方案7】:

            我建议您使用以下代码,其中我正在成功运行我的应用程序

            代码如下:

            XML 文件:

            <?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 文件:

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

            您也可以根据自己的用途修改清单文件:

            <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>
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-03-15
              相关资源
              最近更新 更多