我使用纹理视图和媒体播放器实现了一个视频播放器的回收视图。当我通过列表滚动时,我可以单击该项并播放视频。不过,使用回收视图后,一旦视图从屏幕上消失,它就会被循环利用。如果我向上滚动,所有视图现在都是空白的(黑色)。
我正在寻找添加功能的方法,当用户将视频滚动到屏幕外时,它将暂停并保留对该视频的引用,以便如果他们滚动回该视频,则会从那个点播放。
我已经查看了这里,但我不想下载视频,我只想流式传输。我不是在寻找有人为我做这件事,我只是希望有些指针,希望有人能分享他们的知识......谢谢您提前
到目前为止,这就是我所做的:
视频播放器
public class CustomVideoPlayer implements TextureView.SurfaceTextureListener, VideoControllerView.MediaPlayerControl, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener {
private Context mContext;
private String mUrl;
private MediaPlayer mMediaPlayer;
private Surface mSurface;
private VideoControllerView mControllerView;
private TextureView mTextureView;
private CardView mCardView;
private ProgressBar mProgress;
private FrameLayout mView;
private RelativeLayout mLayout;
public CustomVideoPlayer(Context ctx, TextureView view, ProgressBar progressDialog, FrameLayout holderView){
this.mContext = ctx;
mTextureView = view;
mTextureView.setSurfaceTextureListener(this);
mProgress = progressDialog;
mControllerView = new VideoControllerView(ctx);
mView = holderView;
mTextureView.setOnTouchListener(new ControlTouchListener());
}
@Override
public boolean canPause() {
return true;
}
@Override
public boolean canSeekBackward() {
return true;
}
@Override
public boolean canSeekForward() {
return true;
}
@Override
public int getBufferPercentage() {
return 0;
}
@Override
public int getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
@Override
public int getDuration() {
return mMediaPlayer.getDuration();
}
@Override
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
@Override
public void pause() {
mMediaPlayer.pause();
}
@Override
public void seekTo(int i) {
mMediaPlayer.seekTo(i);
}
@Override
public void start() {
mMediaPlayer.start();
}
@Override
public boolean isFullScreen() {
return false;
}
@Override
public void toggleFullScreen() {
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
@Override
public void onCompletion(MediaPlayer mp) {
}
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mSurface = new Surface(surface);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
public void changePlayState(){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
}else{
mMediaPlayer.start();
}
}
public void startVideo(String url){
if(mMediaPlayer!=null){
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = new MediaPlayer();
}else{
mMediaPlayer = new MediaPlayer();
}
if(!mMediaPlayer.isPlaying()){
try {
mMediaPlayer.setSurface(mSurface);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setDataSource(url);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
mMediaPlayer.setOnPreparedListener(this);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onPrepared(MediaPlayer mp) {
Log.i(VersysVideoPlayer.class.getSimpleName(), "ON PREPARED CALLED");
mControllerView.setMediaPlayer(this);
mControllerView.setAnchorView(mView);
mControllerView.show();
mProgress.setVisibility(View.GONE);
mMediaPlayer.start();
}
//Touch listener to display video controls
class ControlTouchListener implements View.OnTouchListener{
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
mControllerView.show();
}
return false;
}
}
}
活动/适配器
public class VideoViewListActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_view_list);
//Create instance of Recycler view
final RecyclerView videoList = (RecyclerView) findViewById(R.id.feed_list);
LinearLayoutManager llm = new LinearLayoutManager(this);
videoList.setLayoutManager(llm);
videoList.setHasFixedSize(true);
final List<String> list = new ArrayList<>();
list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
list.add("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
final VideoAdapter adapter = new VideoAdapter(list, this);
videoList.setAdapter(adapter);
videoList.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
TextureView view = adapter.getVideoPlayer();
Log.i("PERCENTAGE VISIBLE: ", String.valueOf(getVisiblePercent(adapter.getVideoPlayer())));
if(getVisiblePercent(view)==100) {
return;
}
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_video_view_list, menu);
return true;
}
public static int getVisiblePercent(View v) {
if (v.isShown()) {
Rect r = new Rect();
v.getGlobalVisibleRect(r);
double sVisible = r.width() * r.height();
double sTotal = v.getWidth() * v.getHeight();
return (int) (100 * sVisible / sTotal);
} else {
return -1;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Recycler View Adapter
*/
class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoFeedHolder> {
public TextureView mPreview;
private CardView mCardView;
private List<String> mUrls;
private Context mContext;
private Surface mSurface;
VideoControllerView controller;
private View mAnchor;
private ProgressBar mProgressDialog;
private ImageView mHolder;
private int mPosition;
private VersysVideoPlayer mVideoPlayer;
OnItemClickListener mItemClickListener;
public VideoAdapter(List<String> url, Context ctx) {
mUrls = url;
mContext = ctx;
controller = new VideoControllerView(ctx);
}
@Override
public VideoAdapter.VideoFeedHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.video_item_feed, viewGroup, false);
VideoFeedHolder holder = new VideoFeedHolder(v);
return holder;
}
@Override
public void onBindViewHolder(final VideoFeedHolder videoFeedHolder, final int i) {
final VersysVideoPlayer videoPlayer = new VersysVideoPlayer(mContext, videoFeedHolder.mTexturePreview, mProgressDialog, videoFeedHolder.controlHolder);
videoFeedHolder.placeholder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
videoPlayer.startVideo(mUrls.get(i));
videoFeedHolder.placeholder.setVisibility(View.GONE);
videoFeedHolder.bar.setVisibility(View.VISIBLE);
}
});
mPosition = i;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public String getUrl() {
return mUrls.get(mPosition);
}
@Override
public int getItemCount() {
return mUrls.size();
}
public TextureView getVideoPlayer() {
return mPreview;
}
public class VideoFeedHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextureView mTexturePreview;
ProgressBar bar;
ImageView placeholder;
FrameLayout controlHolder;
RelativeLayout touchLayout;
public VideoFeedHolder(View itemView) {
super(itemView);
mTexturePreview = (TextureView) itemView.findViewById(R.id.video_player);
mPreview = mTexturePreview;
mCardView = (CardView) itemView.findViewById(R.id.cv);
bar = (ProgressBar)itemView.findViewById(R.id.buffereing);
placeholder = (ImageView) itemView.findViewById(R.id.holder);
mProgressDialog = bar;
controlHolder = (FrameLayout) itemView.findViewById(R.id.media_controller_anchor);
}
@Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(v, getAdapterPosition());
}
}
}
}
}
视频反馈项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.support.v7.widget.CardView
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="400dp"
android:id="@+id/cv">
<RelativeLayout
android:id="@+id/anchor"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/detail_layout"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/profile_pic"
android:background="@drawable/profiler"
android:layout_marginLeft="10dp"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:id="@+id/user_name"
android:layout_alignTop="@+id/profile_pic"
android:layout_toRightOf="@+id/profile_pic"
android:text="Joe Bloggs"
android:layout_marginLeft="10dp"
android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/date"
android:layout_below="@+id/user_name"
android:layout_toRightOf="@+id/profile_pic"
android:layout_marginLeft="10dp"
android:text="10 Aug 2015"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/desc"
android:layout_below="@+id/profile_pic"
android:layout_marginLeft="10dp"
android:text="This a sample video of a bird getting hit on the head and a rabbit waking from a nap!!"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<RelativeLayout
android:layout_below="@+id/detail_layout"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextureView
android:id="@+id/video_player"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/media_controller_anchor"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
<ImageView
android:id="@+id/holder"
android:layout_centerInParent="true"
android:background="@drawable/default_video_poster"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ProgressBar
android:id="@+id/buffereing"
android:visibility="gone"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>