在 recyclerview 中流畅地播放来自 URL 的视频
Posted
技术标签:
【中文标题】在 recyclerview 中流畅地播放来自 URL 的视频【英文标题】:Smoothly Play video from URL in recyclerview 【发布时间】:2019-10-26 05:17:40 【问题描述】:我尝试在 Recyclerview 中播放视频,但无法正常工作。为此,我使用了:https://github.com/danylovolokh/VideoPlayerManager。
谁能告诉我相同的替代解决方案。
【问题讨论】:
【参考方案1】:根据需要修改
@BindView(R.id.rv_home) RecyclerView recyclerView;
private static final String TAG = "HomeFragment";
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
requestForRead();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment_home, container, false);
ButterKnife.bind(this, view);
setRecyclerView();
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
new VideosAsync(getContext()).execute();
else
requestForRead();
return view;
private void setRecyclerView()
LinearSnapHelper linearSnapHelper = new SnapHelperOneByOne();
linearSnapHelper.attachToRecyclerView(recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
//get list of videos
private List<String> getAllMedia()
HashSet<String> videoItemHashSet = new HashSet<>();
String[] projection = MediaStore.Video.VideoColumns.DATA;
Cursor cursor = getContext().getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection
, null, null, null);
try
cursor.moveToFirst();
do
String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
videoItemHashSet.add(path);
while(cursor.moveToNext());
cursor.close();
catch (Exception e)
e.printStackTrace();
return new ArrayList<>(videoItemHashSet);
private void requestForRead()
ActivityCompat.requestPermissions( getActivity(), new String[]Manifest.permission.READ_EXTERNAL_STORAGE, 100);
public class VideosAsync extends AsyncTask<Void, Void, List<String>>
private Context context;
private List<String> videoList;
public VideosAsync(Context context)
this.context = context;
this.videoList = new ArrayList<>();
@Override
protected List<String> doInBackground(Void... params)
videoList.addAll(getAllMedia());
return videoList;
@Override
protected void onPostExecute(List<String> videos)
HomeAdapter adapter = new HomeAdapter(videos, context);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
@Override
protected void onPreExecute()
SnapHelperOneByOne
public class SnapHelperOneByOne extends LinearSnapHelper
@Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY)
if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider))
return RecyclerView.NO_POSITION;
final View currentView = findSnapView(layoutManager);
if( currentView == null )
return RecyclerView.NO_POSITION;
final int currentPosition = layoutManager.getPosition(currentView);
if (currentPosition == RecyclerView.NO_POSITION)
return RecyclerView.NO_POSITION;
return currentPosition;
适配器
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder>
private List<String> videoList;
private Context context;
public HomeAdapter(List<String> videoList, Context context)
this.videoList = videoList;
this.context = context;
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_video_home, parent, false));
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
Uri path = Uri.parse(videoList.get(position));
setVideoView(holder, path);
@Override
public int getItemCount()
return videoList.size();
public class ViewHolder extends RecyclerView.ViewHolder
@BindView(R.id.video_view_home) FullScreenVideoView fullScreenVideoView;
public ViewHolder(@NonNull View itemView)
super(itemView);
ButterKnife.bind(this, itemView);
private void setVideoView(ViewHolder holder, Uri videoPath)
holder.fullScreenVideoView.seekTo(100);
holder.fullScreenVideoView.setVideoURI(videoPath);
holder.fullScreenVideoView.requestFocus();
holder.fullScreenVideoView.setOnPreparedListener(mp ->
mp.setLooping(true);
//Set the surface holder height to the screen dimensions
holder.fullScreenVideoView.start();
);
适配器的行布局
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_
android:layout_>
<RelativeLayout
android:layout_
android:layout_>
<com.codencolors.myapplication.helper.FullScreenVideoView
android:id="@+id/video_view_home"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_
android:layout_ />
<LinearLayout
android:layout_alignParentEnd="true"
android:layout_marginEnd="20dp"
android:layout_centerVertical="true"
android:layout_
android:layout_
android:orientation="vertical">
<ImageView
android:layout_
android:layout_
android:src="@drawable/ic_heart"/>
<ImageView
android:layout_marginTop="20dp"
android:layout_
android:layout_
android:src="@drawable/ic_message"/>
<ImageView
android:layout_marginTop="20dp"
android:layout_
android:layout_
android:src="@drawable/ic_forward"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
片段布局
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".fragments.HomeFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_home"
android:layout_
android:layout_/>
</FrameLayout>
清单权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
【讨论】:
以上是关于在 recyclerview 中流畅地播放来自 URL 的视频的主要内容,如果未能解决你的问题,请参考以下文章
如何优化 mp4 视频以在浏览器中尽可能流畅地播放 (HTML5)
在recyclerview中使用textureview播放视频
Android:如何流畅地按顺序播放视频而不会出现故障和延迟?
我如何使用来自firebase的数据制作recyclerview,并有意图地点击