最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

复制视频,并通知系统图库更新,浏览文件夹,视频转换

网站源码admin1浏览0评论

复制视频,并通知系统图库更新,浏览文件夹,视频转换

复制视频,并通知系统图库更新,浏览文件夹,视频转换

1、创建文件夹

    /*** 判断目录是否存在,不存在则判断是否创建成功** @param file 文件* @return {@code true}: 存在或创建成功<br>{@code false}: 不存在或创建失败*/public static boolean createOrExistsDir(File file) {// 如果存在,是目录则返回true,是文件则返回false,不存在则返回是否创建成功return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());}

2、复制视频

 /*** 复制单个文件** @param oldPath$Name String 原文件路径+文件名 如:data/user/0/com.test/files/abc.txt* @param newPath$Name String 复制后路径+文件名 如:data/user/0/com.test/cache/abc.txt* @return <code>true</code> if and only if the file was copied;* <code>false</code> otherwise*/public  static  boolean copyFile(String oldPath$Name, String newPath$Name) {try {File oldFile = new File(oldPath$Name);if (!oldFile.exists()) {Log.e("--Method--", "copyFile:  oldFile not exist.");return false;} else if (!oldFile.isFile()) {Log.e("--Method--", "copyFile:  oldFile not file.");return false;} else if (!oldFile.canRead()) {Log.e("--Method--", "copyFile:  oldFile cannot read.");return false;}/* 如果不需要打log,可以使用下面的语句if (!oldFile.exists() || !oldFile.isFile() || !oldFile.canRead()) {return false;}*/FileInputStream fileInputStream = new FileInputStream(oldPath$Name);    //读入原文件FileOutputStream fileOutputStream = new FileOutputStream(newPath$Name);byte[] buffer = new byte[1024];int byteRead;while ((byteRead = fileInputStream.read(buffer)) != -1) {fileOutputStream.write(buffer, 0, byteRead);}fileInputStream.close();fileOutputStream.flush();fileOutputStream.close();return true;} catch (Exception e) {e.printStackTrace();return false;}}

3、创建文件夹,复制视频,通知系统图库更新

 private void saveVideoToSDCard(File videoFile, String name) {String gpname = "123";if (TextUtils.isEmpty(gpname)){gpname="公棚";}String dir = Environment.getExternalStorageDirectory().toString() + File.separator + "我的APP" + File.separator + "视频集锦" + File.separator + "" + gpname;LogUtils.i("创建目录=" + dir);File dirFile = new File(dir);if (FileUtils.createOrExistsDir(dirFile)) {String target = dir + File.separator + "" + name+ ".mp4";LogUtils.i("移动文件=" + target);if (FileUtils.copyFile(videoFile.getAbsolutePath(), target)) {
//                showShortToast("视频已保存:" + target);LogUtils.i("视频已保存:" + target);
//                zipVideo(target);//通知系统图片更新int duration;try {MediaMetadataRetriever mmr = new MediaMetadataRetriever();mmr.setDataSource(target);duration = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));AlbumNotifyHelper.insertVideoToMediaStore(this, target, 0, duration);} catch (Exception e) {e.printStackTrace();AlbumNotifyHelper.insertVideoToMediaStore(this, target, 0, 0);}LogUtils.i("移动视频成功");} else {showShortToast("移动视频失败");}} else {showShortToast("创建文件夹失败");}refreshFiles();}
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;import java.io.File;
import java.util.ArrayList;/*** CreateAt : 2017/5/24* Describe : 相册更新通知帮助类* 创建时间单位ms* 视频时长单位ms**/
public class AlbumNotifyHelper {public static final String TAG = AlbumNotifyHelper.class.getSimpleName();///// 下面是对外公开的重载的方法///public static void notifyScanDcim(Context context, String filePath) {scanFile(context, filePath);}public static void insertVideoToMediaStore(Context context, String filePath, long dateTaken, long duration) {insertVideoToMediaStore(context, filePath, dateTaken, 0, 0, duration);}/*   public static void insertVideoToMediaStore(Context context, VideoUtil.VideoInfo videoInfo) {insertVideoToMediaStore(context, videoInfo.originalVideoFilePath, videoInfo.dateTaken, videoInfo.width, videoInfo.height, videoInfo.duringTime);}*/public static void insertImageToMediaStore(Context context, String filePath, long createTime) {insertImageToMediaStore(context, filePath, createTime, 0, 0);}///// 扫描系统相册核心方法////*** 针对系统文夹只需要扫描,不用插入内容提供者,不然会重复** @param context  上下文* @param filePath 文件路径*/public static void scanFile(Context context, String filePath) {if (!checkFile(filePath))return;Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);intent.setData(Uri.fromFile(new File(filePath)));context.sendBroadcast(intent);}///// 非系统相册像MediaContent中插入数据,核心方法////*** 针对非系统文件夹下的文件,使用该方法* 插入时初始化公共字段** @param filePath 文件* @param time     ms* @return ContentValues*/private static ContentValues initCommonContentValues(String filePath, long time) {ContentValues values = new ContentValues();File saveFile = new File(filePath);long timeMillis = getTimeWrap(time);values.put(MediaStore.MediaColumns.TITLE, saveFile.getName());values.put(MediaStore.MediaColumns.DISPLAY_NAME, saveFile.getName());values.put(MediaStore.MediaColumns.DATE_MODIFIED, timeMillis);values.put(MediaStore.MediaColumns.DATE_ADDED, timeMillis);values.put(MediaStore.MediaColumns.DATA, saveFile.getAbsolutePath());values.put(MediaStore.MediaColumns.SIZE, saveFile.length());return values;}/*** 保存到照片到本地,并插入MediaStore以保证相册可以查看到,这是更优化的方法,防止读取的照片获取不到宽高** @param context    上下文* @param filePath   文件路径* @param createTime 创建时间 <=0时为当前时间 ms* @param width      宽度* @param height     高度*/public static void insertImageToMediaStore(Context context, String filePath, long createTime, int width, int height) {if (!checkFile(filePath))return;createTime = getTimeWrap(createTime);ContentValues values = initCommonContentValues(filePath, createTime);values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, createTime);values.put(MediaStore.Images.ImageColumns.ORIENTATION, 0);values.put(MediaStore.Images.ImageColumns.ORIENTATION, 0);if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {if (width > 0) values.put(MediaStore.Images.ImageColumns.WIDTH, 0);if (height > 0) values.put(MediaStore.Images.ImageColumns.HEIGHT, 0);}values.put(MediaStore.MediaColumns.MIME_TYPE, getPhotoMimeType(filePath));context.getApplicationContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);}/*** 保存到视频到本地,并插入MediaStore以保证相册可以查看到,这是更优化的方法,防止读取的视频获取不到宽高** @param context    上下文* @param filePath   文件路径* @param createTime 创建时间 <=0时为当前时间 ms* @param duration   视频长度 ms* @param width      宽度* @param height     高度*/public static void insertVideoToMediaStore(Context context, String filePath, long createTime, int width, int height, long duration) {if (!checkFile(filePath))return;createTime = getTimeWrap(createTime);ContentValues values = initCommonContentValues(filePath, createTime);values.put(MediaStore.Video.VideoColumns.DATE_TAKEN, createTime);if (duration > 0)values.put(MediaStore.Video.VideoColumns.DURATION, duration);if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {if (width > 0) values.put(MediaStore.Video.VideoColumns.WIDTH, width);if (height > 0) values.put(MediaStore.Video.VideoColumns.HEIGHT, height);}values.put(MediaStore.MediaColumns.MIME_TYPE, getVideoMimeType(filePath));context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);}// 是不是系统相册private static boolean isSystemDcim(String path) {return path.toLowerCase().contains("dcim") || path.toLowerCase().contains("camera");}// 获取照片的mine_typeprivate static String getPhotoMimeType(String path) {String lowerPath = path.toLowerCase();if (lowerPath.endsWith("jpg") || lowerPath.endsWith("jpeg")) {return "image/jpeg";} else if (lowerPath.endsWith("png")) {return "image/png";} else if (lowerPath.endsWith("gif")) {return "image/gif";}return "image/jpeg";}// 获取video的mine_type,暂时只支持mp4,3gpprivate static String getVideoMimeType(String path) {String lowerPath = path.toLowerCase();if (lowerPath.endsWith("mp4") || lowerPath.endsWith("mpeg4")) {return "video/mp4";} else if (lowerPath.endsWith("3gp")) {return "video/3gp";}return "video/mp4";}// 获得转化后的时间private static long getTimeWrap(long time) {if (time <= 0) {return System.currentTimeMillis();}return time;}// 检测文件存在private static boolean checkFile(String filePath) {//boolean result = FileUtil.fileIsExist(filePath);boolean result = false;File mFile = new File(filePath);if (mFile.exists()) {result = true;}Log.e(TAG, "文件不存在 path = " + filePath);return result;}}

4、浏览文件夹

private void refreshFiles() {String gpname = MasterApplication.getInstance().getCurrentUser().shopname;String dir = Environment.getExternalStorageDirectory().toString() + File.separator + "我的APP" + File.separator + "视频集锦" + File.separator + "" + gpname;LogUtils.i("创建目录=" + dir);File dirFile = new File(dir);if (FileUtils.createOrExistsDir(dirFile)) {List<String> files = FileUtils.getFilesAllName(dir);if (ListUtils.isEmpty(files)) {return;}for (int i = 0; i < files.size(); i++) {String fileName = files.get(i);String suffix = fileName.substring(0, fileName.lastIndexOf("."));LogUtils.i("文件名=" + fileName);LogUtils.i("suffix=" + suffix);if (!TextUtils.isEmpty(suffix)) {String[] arrs = suffix.split("/");if (arrs != null && arrs.length > 1) {suffix = arrs[arrs.length - 1];LogUtils.i("文件名=" + suffix);for (int j = 0; j < lists.size(); j++) {if (suffix.equals(lists.get(j).getZh())) {lists.get(j).setLocalVideo(fileName);}}}}}mAdapter.setDataAndRefreshUI(lists);} else {LogUtils.e("创建文件夹失败");}}
    public static List<String> getFilesAllName(String path) {File file=new File(path);File[] files=file.listFiles();if (files == null){Log.e("error","空目录");return null;}List<String> s = new ArrayList<>();for(int i =0;i<files.length;i++){s.add(files[i].getAbsolutePath());}return s;}

5、必要时还可以对视频进行压缩,使用的是VideoCompress:

  class VideoCompressAsyncTask extends AsyncTask<String, String, String> {Context mContext;public VideoCompressAsyncTask(Context context) {mContext = context;}@Overrideprotected void onPreExecute() {super.onPreExecute();showProgressDialog("正在处理视频...");}@Overrideprotected String doInBackground(String... paths) {LogUtils.e("paths[0]=" + paths[0]);LogUtils.e("paths[1]=" + paths[1]);String filePath = null;try {int outWidth = 0;int outHeight = 0;//                        if (mOriginalWidth > mOriginalHeight) {
//                            //横屏
//                            outWidth = 720;
//                            outHeight = 480;
//                        } else {
//                            //竖屏
//                            outWidth = 480;
//                            outHeight = 720;
//                        }//默认竖屏
//                outWidth = 480;
//                outHeight = 720;
//                filePath = SiliCompressor.with(KSListActivity.this)
//                        pressVideo(paths[0], paths[1], outWidth, outHeight, 900000);//                720poutWidth = 720;outHeight = 1280;filePath = SiliCompressor.with(KSListActivity.this)pressVideo(paths[0], paths[1], outWidth, outHeight, 1500000);//                SiliCompressor.with(mContext)pressVideo(
//                        paths[0], paths[1]);//                //This bellow is just a temporary solution to test that method call works
//                boolean b = Boolean.parseBoolean(paths[0]);
//                if (b) {
//                    filePath = SiliCompressor.with(mContext)pressVideo(paths[1], paths[2]);
//                } else {
//                    Uri videoContentUri = Uri.parse(paths[1]);
//                    // Example using the bitrate and video size parameters
//                    /*filePath = SiliCompressor.with(mContext)pressVideo(
//                            videoContentUri,
//                            paths[2],
//                            1280,
//                            720,
//                            1500000);*/
//                    filePath = SiliCompressor.with(mContext)pressVideo(
//                            videoContentUri,
//                            paths[2]);
//                }} catch (Exception e) {showShortToast("视频处理失败");dismissProgressDialog();e.printStackTrace();}return filePath;}@Overrideprotected void onPostExecute(String compressedFilePath) {super.onPostExecute(compressedFilePath);LogUtils.e("compressVideo onSuccess=========" + compressedFilePath);String gpname = MasterApplication.getInstance().getCurrentUser().shopname;String dir = Environment.getExternalStorageDirectory().toString() + File.separator + "xxx" + File.separator + "视频" + File.separator + "" + gpname;final String destPath = dir + File.separator + "" + zuhuanhao + ".mp4";File destFile = FileUtils.renameFile(compressedFilePath, destPath);dismissProgressDialog();showMessage("视频已保存:" + destFile.getAbsolutePath());//复制文件//通知系统更新int duration;try {MediaMetadataRetriever mmr = new MediaMetadataRetriever();mmr.setDataSource(destFile.getAbsolutePath());duration = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));AlbumNotifyHelper.insertVideoToMediaStore(KSListActivity.this, destFile.getAbsolutePath(), 0, duration);} catch (Exception e) {e.printStackTrace();AlbumNotifyHelper.insertVideoToMediaStore(KSListActivity.this, destFile.getAbsolutePath(), 0, 0);}Log.i("Silicompressor", "Path: " + compressedFilePath);}}

文件改名:

 /*** oldPath 和 newPath必须是新旧文件的绝对路径*/public static  File renameFile(String oldPath, String newPath) {if (TextUtils.isEmpty(oldPath)) {return null;}if (TextUtils.isEmpty(newPath)) {return null;}File oldFile = new File(oldPath);File newFile = new File(newPath);boolean b = oldFile.renameTo(newFile);File file2 = new File(newPath);return file2;}

使用方法:

            new VideoCompressAsyncTask(this).execute(inputDir, dir);

6、压缩视频效果并不理想,很模糊,可以使用RxFFmpeg进行格式转换,mp4转flv,24mb的视频可以变成10mb,并且清晰度还不错。缺点是包内存急速增加。
文章
FFmpeg手撕视频(Android端)

使用此项目很快捷使用
RxFFmpeg 是基于 ( FFmpeg 4.0 + X264 + mp3lame + fdk-aac ) 编译的适用于 Android 平台的音视频编辑、视频剪辑的快速处理框架,包含以下功能(视频拼接,转码,压缩,裁剪,片头片尾,分离音视频,变速,添加静态贴纸和gif动态贴纸,添加字幕,添加滤镜,添加背景音乐,加速减速视频,倒放音视频,音频裁剪,变声,混音,图片合成视频,视频解码图片,抖音首页,视频播放器等主流特色功能

一句代码:

ffmpeg -i /storage/emulated/0/xxx.mp4 -b:v 4000k -y /storage/emulated/0/xxx.flv

4000k是码率,根据自己需要调整,值越大越清晰

发布评论

评论列表(0)

  1. 暂无评论