我在我的活动中创建了VideoView
,下面是代码。
VideoView vvVideos = (VideoView) rootView.findViewById(R.id.videoView);
MediaController mediacontroller = new MediaController(ctx);
mediacontroller.setAnchorView(vvVideos);
Uri video = Uri.parse("android.resource://" + packageName +"/"+R.raw.sample);
vvVideos.setMediaController(mediacontroller);
LayoutParams params=vvVideos.getLayoutParams();
params.height=150;
vvVideos.setLayoutParams(params);
vvVideos.setVideoURI(video);
vvVideos.requestFocus();
vvVideos.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
vvVideos.start();
}
});
现在视频在创建活动时开始播放。我想按照以下方式开展活动
答案 0 :(得分:92)
seekTo( 1 )
显示第一帧。确保影片已暂停,然后使用seekTo()
显示视频的第一帧:
VideoView mVideoView = (VideoView) findViewById( R.id.video_preview );
mVideoView.setVideoURI( yourVideoPath );
mVideoView.seekTo( 1 ); // 1 millisecond (0.001 s) into the clip.
注意:我们使用.seekTo( 1 )
,因为设置.seekTo( 0 )
在Android 9上无效。
@Lingviston在另一个答案中回答了点击时播放的内容。
答案 1 :(得分:26)
使用此
创建视频缩略图Bitmap thumb = ThumbnailUtils.createVideoThumbnail("file path/url",
MediaStore.Images.Thumbnails.MINI_KIND);
并设置为videoview
BitmapDrawable bitmapDrawable = new BitmapDrawable(thumb);
mVideoView.setBackgroundDrawable(bitmapDrawable);
答案 2 :(得分:9)
1)删除你的onPrepareListener。我不知道为什么你的视频在活动创建后开始播放,但在videoView.start()之后调用onPrepareListener。
2)在VideoView顶部的布局中添加一个ImageView小部件。然后像这样设置另一个onPrepareListener:
vvVideos.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
previewImage.setVisibility(View.GONE);
}
});
我注意到onPreparedListener过早触发,所以你可以使用
new Handler().postDelay(Runnable, timeInMilis)
取消预览图片。
3)向您添加带有任何手势检测的OnTouchListener VideoView。这是我现在使用的一个例子:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
mGestureDetector = new GestureDetector(this, mGestureListener);
((VideoView) findViewById(R.id.activity_video_videoview)).setOnTouchListener(mTouchListener);
}
private OnTouchListener mTouchListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true;
}
};
private SimpleOnGestureListener mGestureListener = new SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if(mVideoView.isPlaying())
mVideoView.pause();
else
mVideoView.start();
return true;
};
};
通过点按开始/停止播放。
答案 3 :(得分:6)
只需使用seekTo()方法
查看视频到100毫秒它就会显示缩略图try
答案 4 :(得分:4)
您可以使用Glide 4.x
执行此操作。它会抓取您视频的第一帧,在ImageView
添加到您的build.gradle
implementation 'com.github.bumptech.glide:glide:4.x.x'
并在你的班级
GlideApp.with(context)
.load("your video URL")
.into(videoImageView);;
答案 5 :(得分:3)
我以为我会分享我的解决方案。 seekTo
方法效果很好,但仅适用于某些设备。这是我的工作。我在onPreparedListener的onPrepared方法中处理这个问题,但由你决定。
@Override
public void onPrepared(MediaPlayer mp) {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(uri.getPath());
try {
Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(currentPosition);
videoView.setBackgroundDrawable(new BitmapDrawable(bitmap));
} catch (OutOfMemoryError outOfMemoryError) {
//Not entirely sure if this will ever be thrown but better safe than sorry.
videoView.seekTo(currentPosition);
}
}
现在播放视频时,您需要删除此背景图片,如下所示:
private void play() {
...
videoView.setBackgroundDrawable(null);
..
}
享受!
答案 6 :(得分:2)
我知道这是一个老问题,但我需要相同的解决方案而无法在其他地方找到答案,所以我做了解决方案,我在这里分享了爱:
我刚为它创建了一个小课程:
public class LoadFirstVideoFrame implements Runnable {
private static Handler uiHandler = new Handler(Looper.getMainLooper());
private VideoView videoView;
private LoadFirstVideoFrame(VideoView videoView) {
this.videoView = videoView;
videoView.start();
videoView.resume();
uiHandler.post(this);
}
public void stop() {
videoView = null;
uiHandler.removeCallbacks(this);
}
@Override public void run() {
if (videoView == null) return;
if (videoView.isPlaying()) {
videoView.pause();
videoView.seekTo(0);
videoView = null;
} else {
uiHandler.post(this);
}
}
}
它只是要求开始播放并在第一帧实际播放后暂停视频(意味着它加载了文件并且它已经在SurfaceView上渲染)。
这里重要的一点是要记住在这个类上调用stop()
,这样它就可以正常清理,而不是内存泄漏。
我希望它有所帮助。
答案 7 :(得分:1)
非常简单! 您可以使用滑行库。
首先在imageView
上添加videoView
并使用以下代码:
GlideApp.with(getApplicationContext()).load("empty")
.thumbnail(GlideApp.with(getApplicationContext()).load("videoURL"))
.into(imageView);
此代码将下载图像,并最终减少互联网使用量。
答案 8 :(得分:0)
我已经为缩略图创建了一个ImageView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:clickable="true"
android:focusable="true">
<VideoView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="220dp"/>
<ImageView
android:id="@+id/videoView_thumbnail"
android:layout_width="match_parent"
android:layout_height="220dp"
android:scaleType="centerCrop"/>
</RelativeLayout>
并以这种方式在Java中添加setOnPreparedListener和setOnCompletionListener
VideoView videoView = (VideoView) view.findViewById(R.id.video_view);
ImageView thumbnailView=(ImageView)view.findViewById(R.id.videoView_thumbnail);
Glide.with(getApplicationContext()).load(your_Image_Path).into(thumbnailView);
//you can add progress dialog here until video is start playing;
mediaController= new MediaController(getContext());
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setKeepScreenOn(true);
videoView.setVideoPath(your_video_path);
videoView.start(); //call this method for auto playing video
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
thumbnailView.setVisibility(View.GONE);
//you can Hide progress dialog here when video is start playing;
}
});
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
videoView.stopPlayback();
thumbnailView.setVisibility(View.VISIBLE);
}
});
对我来说很好,我希望对所有人都有用
答案 9 :(得分:0)
您可以使用@Joshua Pinter的答案来解决问题。但我想给您更多建议。您自己会回答seekTo(100)
可以代替seekTo(1)
起作用。两种方式都不完美。这是因为seekTo(1)
会得到黑色图像,而seekTo(100)
可能会出现异常。
我更喜欢这样:
// calculate the during time of the media
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
long time = mediaPlayer.getDuration();
// use a proper number
mVideoView.seekTo(time/2);
如果没有后端服务器,可能会更好。或者,如果您有后端服务器,则可以通过这种方式尝试。
缩略图是由服务器计算的,客户端只显示后端响应的图像。当涉及到服务器端时,您可以做很多事情。
如果您想进一步讨论这两个问题,我们可以在后面讨论。
答案 10 :(得分:0)
将此添加到您的xml中
`<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dimen180"
android:background="@color/color_bg">
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/epPlayer"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/flTv"
android:layout_width="match_parent"
android:background="@color/color_bg"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/ivTv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/tv"/>
</FrameLayout>
<ProgressBar
android:id="@+id/pbVideoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_centerInParent="true"
android:indeterminate="true" />
</RelativeLayout>
` 对于Kotlin用户
声明变量
private var simpleExoPlayer: ExoPlayer? = null
使用此
simpleExoPlayer = SimpleExoPlayer.Builder(this).build()
epPlayer.player = simpleExoPlayer
val dataSourceFactory = DefaultDataSourceFactory(
this,
Util.getUserAgent(this, getString(R.string.app_name))
)
val videoSource = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(it1))
simpleExoPlayer!!.prepare(videoSource)
simpleExoPlayer!!.playWhenReady = true
simpleExoPlayer!!.addListener(object : Player.EventListener{
override fun onPlayerStateChanged(
playWhenReady: Boolean,
playbackState: Int
) {
if(playbackState== Player.STATE_READY)
{
pbVideoView.visibility= View.GONE
epPlayer.visibility= View.VISIBLE
flTv.visibility= View.GONE
}
if (playbackState== Player.STATE_BUFFERING)
{
pbVideoView.visibility= View.VISIBLE
}
}
})
我希望这会有所帮助。
答案 11 :(得分:-1)
要使视频在活动开始时停止播放,只需删除video.start()
方法。