参考
android/安卓获取视频文件缩略图及时长
Android ListView 列表控件
在Android中如何获取视频的第一帧图片并显示在一个ImageView中
List集合循环添加对象会重复的原因及解决办法
思路
先使用listview显示一些简单的内容,只是这些内容是自己手动输入的。
然后获取视频的一些信息,替换掉自己手动输入的内容。
显示效果
核心代码
//获取指定文件夹下所有视频文件 public static List<VideoInfo> getVideo(Context context, String fileAbsolutePath) { File file = new File(fileAbsolutePath); if (!file.exists()) { Toast.makeText(context, "文件夹不存在", Toast.LENGTH_SHORT).show(); return null; } File[] subFile = file.listFiles(); for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) {
VideoInfo info = new VideoInfo(); //必须放在for循环里面,不然会显示几个一样的
// 判断是否为文件夹 if (!subFile[iFileLength].isDirectory()) { String filename = subFile[iFileLength].getName(); System.out.println("----name = " + filename); Log.d(TAG, filename); Log.d(TAG, String.valueOf(iFileLength)); // 判断是否为MP4结尾 if (filename.trim().toLowerCase().endsWith(".mp4") || filename.trim().toLowerCase().endsWith(".3gp") || filename.trim().toLowerCase().endsWith(".avi") || filename.trim().toLowerCase().endsWith(".flv")) { // 设置文件路径 info.setPath(subFile[iFileLength].getPath()); //Log.d(TAG, subFile[iFileLength].getPath()); ///storage/emulated/0/Android/data/com.example.video_list_demo1/cache/VID_20211229_074135.mp4 // 设置文件夹名称 info.setTitle(subFile[iFileLength].getName()); // Log.d(TAG, subFile[iFileLength].getName()); //VID_20211229_074135.mp4 //设置文件时长 MediaMetadataRetriever retriever = new MediaMetadataRetriever(); retriever.setDataSource(subFile[iFileLength].getPath()); //得到的数除1000得到秒,再把秒分为时分秒 int time = Integer.parseInt(retriever.extractMetadata (MediaMetadataRetriever.METADATA_KEY_DURATION)) / 1000; Integer hour = time / 60 / 60; Integer minutes = time / 60 % 60; Integer remainingSeconds = time % 60; String duration = hour + "时" + minutes + "分" + remainingSeconds + "秒"; info.setDuration(duration); Log.d(TAG, duration); //0时0分22秒 //根据路径获得视频缩略图 Bitmap bitmap = retriever.getFrameAtTime(); info.setId(bitmap); list.add( info); Log.d(TAG, "onCreate: " + iFileLength+ "..."+list.get(iFileLength).getTitle()); //onCreate: 2...Health20211229083327complete.mp4 } } } return list; }
全部代码
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <!-- 定义一个用于显示头像的 ImageView --> <ImageView android:id="@+id/icon" android:layout_width="32dp" android:layout_height="32dp" android:baselineAlignBottom="true" android:paddingLeft="8dp" /> <!-- 定义一个竖直方向的 LinearLayout,把 语言 与 简介 的文本框设置出来 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="8dp" android:textColor="#1D1D1C" android:textSize="20sp" /> <TextView android:id="@+id/desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="8px" android:textColor="#B4B4B9" android:textSize="14sp" /> </LinearLayout> </LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8" ?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="8dp" android:orientation="vertical" > <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
VideoInfo.java
package com.example.video_list_demo1; import android.graphics.Bitmap; public class VideoInfo { /** * */ private static final long serialVersionUID = -7920222595800367956L; private Bitmap id; private String title; private String album; private String artist; private String displayName; private String mimeType; private String path; private long size; private String duration; /** * */ public VideoInfo() { super(); } private boolean isSelect; public boolean isSelect() { return isSelect; } public void setSelect(boolean isSelect) { this.isSelect = isSelect; } public VideoInfo (String aName, String aDesc, Bitmap aIcon) { this.title = aName; this.duration = aDesc; this.id = aIcon; } public VideoInfo(Bitmap id, String title, String album, String artist, String displayName, String mimeType, String path, long size, String duration) { super(); this.id = id; this.title = title; this.album = album; this.artist = artist; this.displayName = displayName; this.mimeType = mimeType; this.path = path; this.size = size; this.duration = duration; } public Bitmap getId() { return id; } public void setId(Bitmap id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAlbum() { return album; } public void setAlbum(String album) { this.album = album; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public String getDisplayName() { return displayName; } public void setDisplayName(String displayName) { this.displayName = displayName; } public String getMimeType() { return mimeType; } public void setMimeType(String mimeType) { this.mimeType = mimeType; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public long getSize() { return size; } public void setSize(long size) { this.size = size; } public String getDuration() { return duration; } public void setDuration(String duration) { this.duration = duration; } }
YetAdapter.java
package com.example.video_list_demo1; import androidx.appcompat.app.AppCompatActivity; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.MediaMetadataRetriever; import android.os.Bundle; import android.os.FileUtils; import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private static String TAG = "xunyan"; private static ArrayList<VideoInfo> list = new ArrayList<>(); //获取指定文件夹下所有视频文件 public static List<VideoInfo> getVideo(Context context, String fileAbsolutePath) { File file = new File(fileAbsolutePath); if (!file.exists()) { Toast.makeText(context, "文件夹不存在", Toast.LENGTH_SHORT).show(); return null; } File[] subFile = file.listFiles(); for (int iFileLength = 0; iFileLength < subFile.length; iFileLength++) { VideoInfo info = new VideoInfo(); //必须放在for循环里面,不然会显示几个一样的 // 判断是否为文件夹 if (!subFile[iFileLength].isDirectory()) { String filename = subFile[iFileLength].getName(); System.out.println("----name = " + filename); Log.d(TAG, filename); Log.d(TAG, String.valueOf(iFileLength)); // 判断是否为MP4结尾 if (filename.trim().toLowerCase().endsWith(".mp4") || filename.trim().toLowerCase().endsWith(".3gp") || filename.trim().toLowerCase().endsWith(".avi") || filename.trim().toLowerCase().endsWith(".flv")) { // 设置文件路径 info.setPath(subFile[iFileLength].getPath()); //Log.d(TAG, subFile[iFileLength].getPath()); ///storage/emulated/0/Android/data/com.example.video_list_demo1/cache/VID_20211229_074135.mp4 // 设置文件夹名称 info.setTitle(subFile[iFileLength].getName()); // Log.d(TAG, subFile[iFileLength].getName()); //VID_20211229_074135.mp4 //设置文件时长 MediaMetadataRetriever retriever = new MediaMetadataRetriever(); retriever.setDataSource(subFile[iFileLength].getPath()); //得到的数除1000得到秒,再把秒分为时分秒 int time = Integer.parseInt(retriever.extractMetadata (MediaMetadataRetriever.METADATA_KEY_DURATION)) / 1000; Integer hour = time / 60 / 60; Integer minutes = time / 60 % 60; Integer remainingSeconds = time % 60; String duration = hour + "时" + minutes + "分" + remainingSeconds + "秒"; info.setDuration(duration); Log.d(TAG, duration); //0时0分22秒 //根据路径获得视频缩略图 Bitmap bitmap = retriever.getFrameAtTime(); info.setId(bitmap); list.add( info); Log.d(TAG, "onCreate: " + iFileLength+ "..."+list.get(iFileLength).getTitle()); //onCreate: 2...Health20211229083327complete.mp4 } } } return list; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //清空list,防止反复添加 list.clear(); //获取外部文件所在地址:/storage/emulated/0/Android/data/com.example.video_list_demo1/cache String video_path = getExternalCacheDir().getAbsolutePath(); //获取所有视频及其信息,保存到list中 getVideo(this, video_path); /* //单例测试 info = new VideoInfo(); info.setTitle("111"); info.setDuration("222"); info.setId(bitmap); list.add(info);*/ //创建一个 YetAdapter ListView listView = (ListView) findViewById(R.id.listview); YetAdapter yetAdapter = new YetAdapter((ArrayList<VideoInfo>) list, getApplicationContext()); listView.setAdapter(yetAdapter); listView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getApplicationContext(), "你点击了第" + position + "项", Toast.LENGTH_SHORT).show(); //点击跳转到播放界面 // Intent intent } }