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

我的情况是这样的,拍摄好一段视频后,保存到本地,并且在上传之前判断时长,我这里是时长要不少于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");
                    }
                }
            }
        }
	}


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值