从视频库中选取视频

系统自带的相册既保存图片又保存视频,这意味着用户能够从中选择已有的视频。

打开视频库之前,需要指定数据类型为视频,相关代码代码示例如下:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);     // 创建一个内容获取动作的意图(准备跳到系统视频库)

intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);          // 是否允许多选

intent.setType("video/*");         // 类型为视频

startActivityForResult(intent, CHOOSE_CODE);                 // 打开系统视频库

============================================================================================================

布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:id="@+id/btn_choose"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="打开视频库选取视频"android:textColor="@color/black"android:textSize="16sp" /><Buttonandroid:id="@+id/btn_combine"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="录像或从视频库选取"android:textColor="@color/black"android:textSize="16sp" /></LinearLayout><TextViewandroid:id="@+id/tv_video"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingLeft="5dp"android:textColor="@color/black"android:textSize="17sp" /><RelativeLayoutandroid:id="@+id/rl_video"android:layout_width="match_parent"android:layout_height="300dp"android:visibility="gone"><ImageViewandroid:id="@+id/iv_video"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitCenter" /><ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitCenter"android:src="@drawable/play_video" /></RelativeLayout></LinearLayout>

MediaUtil
package com.example.myapplication.util;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;import java.io.File;@SuppressLint("DefaultLocale")
public class MediaUtil {private final static String TAG = "MediaUtil";// 格式化播放时长(mm:ss)public static String formatDuration(int milliseconds) {int seconds = milliseconds / 1000;int hour = seconds / 3600;int minute = seconds / 60;int second = seconds % 60;String str;if (hour > 0) {str = String.format("%02d:%02d:%02d", hour, minute, second);} else {str = String.format("%02d:%02d", minute, second);}return str;}// 获得音视频文件的缓存路径public static String getRecordFilePath(Context context, String dir_name, String extend_name) {String path = "";File recordDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/" + dir_name + "/");if (!recordDir.exists()) {recordDir.mkdirs();}try {File recordFile = File.createTempFile(DateUtil.getNowDateTime(), extend_name, recordDir);path = recordFile.getAbsolutePath();Log.d(TAG, "dir_name=" + dir_name + ", extend_name=" + extend_name + ", path=" + path);} catch (Exception e) {e.printStackTrace();}return path;}// 获取视频文件中的某帧图片public static Bitmap getOneFrame(Context ctx, Uri uri) {MediaMetadataRetriever retriever = new MediaMetadataRetriever();retriever.setDataSource(ctx, uri);// 获得视频的播放时长,大于1秒的取第1秒处的帧图,不足1秒的取第0秒处的帧图String duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);Log.d(TAG, "duration="+duration);int pos = (Integer.parseInt(duration)/1000)>1 ? 1 : 0;// 获取指定时间的帧图,注意getFrameAtTime方法的时间单位是微秒return retriever.getFrameAtTime(pos * 1000 * 1000);}
}

FileUtil
package com.example.myapplication.util;import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;import androidx.core.content.FileProvider;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;public class FileUtil {private final static String TAG = "FileUtil";// 把字符串保存到指定路径的文本文件public static void saveText(String path, String txt) {// 根据指定的文件路径构建文件输出流对象try (FileOutputStream fos = new FileOutputStream(path)) {fos.write(txt.getBytes()); // 把字符串写入文件输出流} catch (Exception e) {e.printStackTrace();}}// 从指定路径的文本文件中读取内容字符串public static String openText(String path) {String readStr = "";// 根据指定的文件路径构建文件输入流对象try (FileInputStream fis = new FileInputStream(path)) {byte[] b = new byte[fis.available()];fis.read(b); // 从文件输入流读取字节数组readStr = new String(b); // 把字节数组转换为字符串} catch (Exception e) {e.printStackTrace();}return readStr; // 返回文本文件中的文本字符串}// 把位图数据保存到指定路径的图片文件public static void saveImage(String path, Bitmap bitmap) {// 根据指定的文件路径构建文件输出流对象try (FileOutputStream fos = new FileOutputStream(path)) {// 把位图数据压缩到文件输出流中bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);} catch (Exception e) {e.printStackTrace();}}// 从指定路径的图片文件中读取位图数据public static Bitmap openImage(String path) {Bitmap bitmap = null; // 声明一个位图对象// 根据指定的文件路径构建文件输入流对象try (FileInputStream fis = new FileInputStream(path)) {// 从文件输入流中解码位图数据bitmap = BitmapFactory.decodeStream(fis);} catch (Exception e) {e.printStackTrace();}return bitmap; // 返回图片文件中的位图数据}// 检查文件是否存在,以及文件路径是否合法public static boolean checkFileUri(Context ctx, String path) {boolean result = true;File file = new File(path);if (!file.exists() || !file.isFile() || file.length() <= 0) {result = false;}try{Uri uri = Uri.parse(path); // 根据指定路径创建一个Uri对象// 兼容Android7.0,把访问文件的Uri方式改为FileProviderif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){//                // 通过FileProvider获得文件的Uri访问方式
//                uri = FileProvider.getUriForFile(ctx,
//                        ctx.getPackageName()+".fileProvider", new File(path));}}catch (Exception e)   // 该路径可能不存在{e.printStackTrace();result = false;}return result;}// 把指定uri保存为存储卡文件public static void saveFileFromUri(Context ctx, Uri src, String dest) {try (InputStream is = ctx.getContentResolver().openInputStream(src);OutputStream os = new FileOutputStream(dest);) {int byteCount = 0;byte[] bytes = new byte[8096];while ((byteCount = is.read(bytes)) != -1){os.write(bytes, 0, byteCount);}} catch (Exception e) {e.printStackTrace();}}// 从content://media/external/file/这样的Uri中获取文件路径public static String getPathFromContentUri(Context context, Uri uri) {String path = uri.toString();if (path.startsWith("content://")) {String[] proj = new String[]{ // 媒体库的字段名称数组MediaStore.Video.Media._ID, // 编号MediaStore.Video.Media.TITLE, // 标题MediaStore.Video.Media.SIZE, // 文件大小MediaStore.Video.Media.MIME_TYPE, // 文件类型MediaStore.Video.Media.DATA // 文件大小};try (Cursor cursor = context.getContentResolver().query(uri,proj, null, null, null)) {cursor.moveToFirst(); // 把游标移动到开头if (cursor.getString(4) != null) {path = cursor.getString(4);}Log.d(TAG, cursor.getLong(0) + " " + cursor.getString(1)+ " " + cursor.getLong(2) + " " + cursor.getString(3)+ " " + cursor.getString(4));} catch (Exception e) {e.printStackTrace();}}return path;}}

主代码:

package com.example.myapplication;import android.content.ClipData;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;import com.example.myapplication.util.FileUtil;
import com.example.myapplication.util.MediaUtil;public class MainActivity extends AppCompatActivity implements View.OnClickListener
{private final static String TAG = "VideoChooseActivity";private int CHOOSE_CODE = 3; // 只在视频库挑选图片的请求码private int COMBINE_CODE = 4; // 既可录像获得现场视频、也可在视频库挑选已有视频的请求码private TextView tv_video;private RelativeLayout rl_video;private ImageView iv_video;private Uri mVideoUri; // 视频文件的路径对象@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tv_video = findViewById(R.id.tv_video);rl_video = findViewById(R.id.rl_video);iv_video = findViewById(R.id.iv_video);findViewById(R.id.btn_choose).setOnClickListener(this);findViewById(R.id.btn_combine).setOnClickListener(this);findViewById(R.id.rl_video).setOnClickListener(this);}@Overridepublic void onClick(View v){if (v.getId() == R.id.btn_choose){// 创建一个内容获取动作的意图(准备跳到系统视频库)Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "video/*");startActivityForResult(intent, CHOOSE_CODE); // 打开系统视频库}else if (v.getId() == R.id.btn_combine){openSelectDialog(); // 打开选择对话框(要录像还是去视频库)}else if (v.getId() == R.id.rl_video){String realPath = FileUtil.getPathFromContentUri(this, mVideoUri);// 创建一个内容获取动作的意图(准备跳到系统播放器)Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(Uri.parse(realPath), "video/*"); // 类型为视频startActivity(intent); // 打开系统的视频播放器}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent intent){super.onActivityResult(requestCode, resultCode, intent);if (resultCode==RESULT_OK && requestCode==CHOOSE_CODE)  // 从视频库回来{if (intent.getData() != null)    // 选择一个视频{Uri uri = intent.getData(); // 获得已选择视频的路径对象showVideoFrame(uri); // 显示视频的某帧图片}else if (intent.getClipData() != null)     // 选择多个视频{ClipData videos = intent.getClipData(); // 获取剪切板数据if (videos.getItemCount() > 0)  // 至少选择了一个文件{Uri uri = videos.getItemAt(0).getUri();   // 取第一个视频showVideoFrame(uri);   // 显示视频的某帧图片}}}if (resultCode==RESULT_OK && requestCode==COMBINE_CODE)   // 从混合选择对话框回来{if (intent.getData() != null)  // 录像或者从视频库选择一个视频{Uri uri = intent.getData(); // 获得已选择视频的路径对象showVideoFrame(uri); // 显示视频的某帧图片}}}// 打开选择对话框(要录像还是去视频库)private void openSelectDialog(){// 声明摄像机的录像行为Intent recordIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);Intent[] intentArray = new Intent[] { recordIntent };// 声明视频库的打开行为Intent videoIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);videoIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "video/*");// 弹出含摄像机和视频库在内的列表对话框Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);chooserIntent.putExtra(Intent.EXTRA_TITLE, "请录像或选择视频");chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);chooserIntent.putExtra(Intent.EXTRA_INTENT, videoIntent);// 在页面底部弹出多种选择方式的列表对话框startActivityForResult(Intent.createChooser(chooserIntent, "选择视频"), COMBINE_CODE);}// 显示视频的某帧图片private void showVideoFrame(Uri uri){mVideoUri = uri;tv_video.setText("你选中的视频地址为:"+uri.toString());rl_video.setVisibility(View.VISIBLE);// 获取视频文件的某帧图片Bitmap bitmap = MediaUtil.getOneFrame(this, uri);iv_video.setImageBitmap(bitmap); // 设置图像视图的位图对象}}

多媒体——视频——从视频库中选取视频相关推荐

  1. Android Studio App开发之使用摄像机录制视频和从视频库中选取视频的讲解及实战(附源码)

    运行有问题或需要源码请点赞关注收藏后评论区留言~~~ 一.使用摄像机录制视频 与音频类似,通过系统摄像机可以很方便的录制视频,只要指定摄像动作为MediaStore.ACTION_VIDEO_CAPT ...

  2. java html中引入视频的格式_HTML中插入视频

    最常用的向HTML中插入视频的方法有两种,一种是古老的标签,一种是html5中的标签. 前者的兼容性没得说,但是使用起来不太方便,后者使用起来很方便,但是兼容性让人头疼. 虽然后者兼容性存在很多问题, ...

  3. 短视频系统开发时如何实现在iOS系统相册中选取视频

    作为优质的短视频系统开发者,提高产品性能和增强用户体验是非常重要的,除此之外,为了使用户能够对产品保有一定的新鲜感,在短视频系统中加入了点击个人相册即可选取上传视频的功能.虽然看似是很基础且简单的功能 ...

  4. Android 从系统媒体库中选择视频

    只需两步: 第一步:发送Intent action.会在onActivityResult方法中返回选中视频的uri: Intent i = new Intent(Intent.ACTION_PICK, ...

  5. HTML怎么在背景中加视频,css – 在div中嵌入视频作为背景(bootstrap)

    我试图在div中添加一个视频作为背景(.form-container),过去我对完整背景页面做同样的事情,但在这种情况下我只需要在div中,问题:dunno how要做到这一点,我正在玩宽度,但视频不 ...

  6. 怎么在html详情页加视频,如何在网页中插入视频(简单实用)

    很多人会问在网页中怎么插入视频,在HTML5中有新标签--video标签,但是兼容性可就没那么好了. 下面这段代码可以直接使用,里面的几个路径注意一下. 注意一下里面的几个参数. http://xwz ...

  7. ue4蓝图节点手册中文_在UE4中播放视频

    简介: 在日常使用UE4做项目时,会遇到在UE4里播放视频文件的需求,在UE4中可以使用媒体框架(Media Framework)来实现这一功能.这里介绍两种简单的方法来使用这一功能,分别是在场景里播 ...

  8. 智能视频内容生产中专业视频数据导出工具的研发

    点击上方"LiveVideoStack"关注我们 随着智能视频生产时代的到来,专业视频的制作将会变得更智能.更简单.智能视频生产中主要包含三大模块,他们分别是:视频SDK底层能力. ...

  9. 使用裁切技巧,去除视频上下黑边,保持视频画面不变形播放

    视频剪辑的技巧各有不同,最近很多人问如何将视频上黑边去除呢?载切掉黑边后,视频不会变形的哪种,那么这里就为大家分享这个操作技巧.下面用视频剪辑高手来操作. 先下载并安装视频剪辑高手,需要下载去电脑软件 ...

最新文章

  1. 多伦多到温莎_我想要freeCodeCamp Toronto的Twitter来发布报价,所以我做了一个免费的bot来做到这一点。...
  2. Ascend学习资源
  3. 关系类型总结和对应的注解
  4. C++ 测量程序运行时间 任务管理看内存
  5. 【学习笔记】利润中心会计初识
  6. Pycharm 2018 虚拟环境创建及解释器的设置(小白图解教程)
  7. boost::detail::lexical_cast_stream_traits用法的测试程序
  8. XMPPFramework导入
  9. qt利用QSplitter任意拆分窗口
  10. TCL多媒体2010年净盈余9.83亿港币
  11. 再读《SAP德国造》
  12. 我的c++学习(1)hello world!
  13. zabbix api 接口的自动化
  14. Program Variant Scheduling job
  15. Wireshark入门:第一次亲密接触
  16. 为SoC-FPGA添加TFT显示屏和USB键盘
  17. 页面显示\n\tat的问题
  18. linux最后一行awk,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  19. Mac Zoc设置
  20. 【目标检测】目标检测的评价指标(七个)

热门文章

  1. 操作系统开发系列—13.i.进程调度 ●
  2. java学习:模拟KTV点歌系统
  3. 怎么更改计算机用户为管理员账户,Win10如何更改为管理员账户,教您如何更改
  4. 抖音国庆小游戏是如何实现的?带你走近 Cocos
  5. WPS关闭不了后台一直运行的解决办法(wpscloudsvr.exe)
  6. PCB之分布电感分布电容
  7. 使用冒泡排序实现数字的升序排列
  8. windows 剪贴板监控
  9. 【翻译】WhatsApp 加密概述(技术白皮书)
  10. ios屏幕尺寸和分辨率