已知本地视频地址,得到视频时长

来源:互联网 发布:日亚海淘转运公司知乎 编辑:程序博客网 时间:2024/05/17 04:55

我的情况是这样的,拍摄好一段视频后,保存到本地,并且在上传之前判断时长,我这里是时长要不少于5秒,不大于15秒,符合这个时长才能上传。


然后我开始转向度娘,真的搜了好久,百度上的资料我基本上看了一遍,stackflow也逛了一遍……


//判断视频时长是否符合private boolean judgeVideoTime(String vediopahth) {int seconds=0;String[] projection = new String[]{MediaStore.Video.Media.DURATION};    Cursor cursor = VedioFinishActivity.this.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI    , projection, MediaStore.Video.Media.DATA+"='"+vediopahth+"'", null, null);           if (cursor != null){         if(cursor.getCount()==1){         cursor.moveToFirst();         long duration=0;         if (cursor.moveToFirst()) {         do{          duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));          }while (cursor.moveToNext());         }         seconds=(int)duration/1000;         }else {         Mytoast.makeText(this, "视频文件出错", 1).show();}                }else {                 Mytoast.makeText(this, "cuesor为空", 1).show();}                  cursor.close();                  if(seconds>=5){         return true;         }else {         return false;}}



解释一下,这个是返回布尔值的一个方法,传入的参数videopath是视频拍完之后存到本地的地址。再解释一下query这个方法:首先要得到ContentResolver,

ContentResolver直译为内容解析器,代码里就是通过VedioFinishActivity.this.getContentResolver()来得到实例,Android中程序间数据的共享是通过Provider/Resolver进行的。提供数据(内容)的就叫Provider,Resovler提供接口对这个内容进行解读。

根据Android文档,

public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, StringsortOrder)

第一个参数,uri,rui是什么呢?好吧,上面我们提到了Android提供内容的叫Provider,那么在Android中怎么区分各个Provider?有提供联系人的,有提供图片的等等。所以就需要有一个唯一的标识来标识这个Provider,Uri就是这个标识,MediaStore.Video.Media.EXTERNAL_CONTENT_URI 这里我要查询视频,这个uri就是视频内容的提供者;


第二个参数,这个参数告诉Provider要返回的内容(列Column),我只要视频的时长,但是参数中是String[]格式,表示你可以拿到很多你想要的数据,比如视频的修改时间啊,文件大小,标题啊等等,我只要时长,所以String[] projection = new String[]{MediaStore.Video.Media.DURATION};


第三个参数,selection,设置条件。null表示不进行筛选。我有个视频的本地路径,这可以唯一表示一个视频;


第三个参数的地方我写MediaStore.Video.Media.DATA+"='"+vediopahth+"'",其中还有MediaStore.Video.Media.CONTENT_TYPE,MediaStore.Video.Media._ID,MediaStore.Video.Media.SIZE, MediaStore.Video.Media.TITLE等一些参数,看名字可以看出分别还能有内容类型,id,大小,标题这些,参数还有很多,但是我当时真心不知道data是指路径,于是郁闷了好久。


第四个参数,selectionArgs,这个参数是要配合第三个参数使用,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?跟sql语句很像,因为我有绝对路径,没有就是没有,所以我设置了null;


第五个参数,sortOrder,排序,相当于SQL语句中的Order by。如果想要结果按照ID的降序排列: 列明+升降序类型就行。例如MediaStore.Video.Media.SIZE+“DESC”。我这找到的话就只有一个,所以这个也设为null;


后来遇到一个问题,就是拍摄好的视频没办法及时更新到视频库。意思就是我用我的项目录好视频然后也拿到了视频的绝对路径,视频本身是已经存在了,但是我进入图库里,相应目录下没有找到这个视频。所以我在判断时长之前还要手动更新一下图库。

关于这个问题网上有很多方法:

这里我说三个方法:

先普及一下uri:

Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。Android平台而言,URI主要分三个部分:

  1. scheme

  2. authority 

  3. path

我们很经常需要解析Uri,并从Uri中获取数据。

方法一:更新相关文件

Intent scanIntent = new Intent(Intent.Intent.ACTION_MEDIA_MOUNTED);
        scanIntent.setData(Uri.parse(文件 ));
        this.sendBroadcast(scanIntent);

方法二:更新单个文件

前面提到我已经有了视频的路径,就是这里的filePath,所以我用了这个方法。要在判断时长之前;

Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        scanIntent.setData(Uri.fromFile(new File(filePath)));
        ctx.sendBroadcast(scanIntent);

在项目里的代码块:

public void scanFileAsync(Context ctx, String filePath) {        Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);        scanIntent.setData(Uri.fromFile(new File(filePath)));        ctx.sendBroadcast(scanIntent); }
方法三:提供一种思路和解决方案吧,试了一下报错了,但是为了能有技术成长(多凑字数),我先贴出来好吗


private MediaScannerConnection mediaScannerConnection= null;MediaScannerConnectionClient  client=new MediaScannerConnectionClient() {                public void onScanCompleted(String path, Uri uri) {            // TODO Auto-generated method stub            mediaScannerConnection.disconnect();            Log.d("tag", "onScanCompleted");        }                public void onMediaScannerConnected() {            // TODO Auto-generated method stub           Log.d("tag", "onMediaScannerConnected");        }    };     mediaScannerConnection=new MediaScannerConnection(this, client);//获取连接 mediaScannerConnection.connect(); //扫描指定路径下的文件到系统数据库中 scanfile(new File(Environment.getExternalStorageDirectory() + File.separator + "xxx"));   mediaScannerConnection.disconnect();private void scanfile(File f) {        if(f.isDirectory()){            File[] files=f.listFiles();//将指定文件夹下面的文件全部列出来            if(files!=null){                for(int i=0;i<files.length;i++){                    if(files[i].isDirectory()){                         scanfile(files[i]);                    }else                    {//调用mediaScannerConnection.scanFile()方法,更新指定类型的文件到数据库中                         mediaScannerConnection.scanFile(files[i].getAbsolutePath(), "audio/mpeg");                    }                }            }        }}


解决问题了,花了大半天……

0 0
原创粉丝点击