您好,登錄后才能下訂單哦!
小編給大家分享一下Android中視頻采集的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
Camera
它是API21(Android5.0)以前用來對攝像頭數據采集的的API,我們從開始到每個環節的關鍵內容記錄如下。
基礎知識
先來了解使用Camera有幾個相關聯的類。
Camera:API21以后老的API控制攝像頭設備
SurfaceView:顯示攝像頭預覽圖像給用戶
MediaRecorder:錄制攝像頭的視頻
權限聲明
攝像頭權限:我們要使用Camera設備必須要聲明一個權限
<uses-permission android:name="android.permission.CAMERA" />
但是當我們使用Intent來調用系統自己的Camera設備拍照錄像就不需要這個權限。
攝像頭特征:應用必須聲明使用攝像頭特性權限(這個不知道是啥意思的要了解uses-feature這個清單文件的意義)
<uses-feature android:name="android.hardware.camera" />
音頻錄制權限:當錄制視頻的時候我們還要音頻就要加上這個權限。
<uses-permission android:name="android.permission.RECORD_AUDIO" />
存儲權限:如果我們要保存相片和視頻在存儲設備那么就要加上這個權限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
定位權限:如果照片的標簽要GPS位置信息,我們就要如下權限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ... <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. --> <uses-feature android:name="android.hardware.location.gps" />
調用系統的攝像頭app來拍照和錄制視頻
拍照
請求攝像頭特征
<manifest ... > <uses-feature android:name="android.hardware.camera" android:required="true" /> ... </manifest>
這個權限可以讓GooglePlay來判斷是否設備支持下載我們的應用,如果設置required為true那么一定要有攝像頭硬件設備的才能下載,如果設置required為false,那么沒有攝像頭硬件設備的也可以下載,當然我們在程序里面就要判斷一下是否有攝像頭可用了。
使用默認Intent開始拍照
調用默認的開啟系統拍照App的Intent
static final int REQUEST_IMAGE_CAPTURE = 1; private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePictureIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE); } }
獲取拍照圖片
我們剛才通過startActivityForResult來拍照了,很自然的在onActivityResult來接受返回的數據,我們把圖片顯示在一個ImageView上面
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); mImageView.setImageBitmap(imageBitmap); } }
通過這種默認的拍照我們不需要在Android6.0以上的機器聲明任何權限就可以成功執行。
自定義保存相片圖片路徑
我們上面的操作,獲取來的是一個bitmap,我們的圖片信息都是在內存里面操作的,如果我們要保存拍照的圖片到存儲卡并且查看圖片,那么我們只要聲明一個寫存儲卡權限就OK。
<manifest ...> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ... </manifest>
開始重新請求拍照代碼
static final int REQUEST_TAKE_PHOTO = 1; private void dispatchTakePictureIntent() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // Ensure that there's a camera activity to handle the intent if (takePictureIntent.resolveActivity(getPackageManager()) != null) { // Create the File where the photo should go File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File ... } // Continue only if the File was successfully created if (photoFile != null) { Uri photoURI = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); } } } String mCurrentPhotoPath; private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File image = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = image.getAbsolutePath(); return image; }
上面的代碼我們使用了FileProvider.getUriForFile方法,它返回content://URI,這個API在Android7.0以上使用不做處理會拋出FileUriExposedException。我們要在清單文件注冊配置一個FileProvider
<application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.android.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data> </provider> ... </application>
在res/xml/file_paths配置文件
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" /> </paths>
添加照片到相冊
我們上面的照片保存位置根目錄為getExternalFilesDir(Environment.DIRECTORY_PICTURES);這個目錄下面多媒體掃描器是不能找到我們的照片的,因為它是我們App私有的。下面的代碼可以讓系統的多媒體掃描器添加我們的圖片到Media Provider's 數據庫,讓我們的圖片對系統相冊和其他應用都可以使用。
private void galleryAddPic() { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); File f = new File(mCurrentPhotoPath); try { MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), f.getName(), null); Log.d(TAG, "galleryAddPic: add to Media Scanner success"); } catch (FileNotFoundException e) { e.printStackTrace(); Log.e(TAG, "galleryAddPic: add to Media Scanner failed"); } Uri contentUri = Uri.fromFile(f); mediaScanIntent.setData(contentUri); this.sendBroadcast(mediaScanIntent); Toast.makeText(this, "Add to Gallery success", Toast.LENGTH_SHORT).show(); }
解碼縮放圖片
我們在把圖片ImageView上面,沒有做任何處理,如果圖片較大,會導致oom的,做一個縮放處理。
private void setPic() { // Get the dimensions of the View int targetW = mImageView.getWidth(); int targetH = mImageView.getHeight(); // Get the dimensions of the bitmap BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; // Determine how much to scale down the image int scaleFactor = Math.min(photoW/targetW, photoH/targetH); // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); mImageView.setImageBitmap(bitmap); }
demo代碼參考
錄像
錄制視頻播放的代碼很簡單,如果要對視頻播放器進行定制,那么久要多一些東西,我們現在只簡單的可以播放調用系統錄制的視頻。
開啟視頻錄制Intent
static final int REQUEST_VIDEO_CAPTURE = 1; private void dispatchTakeVideoIntent() { Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); if (takeVideoIntent.resolveActivity(getPackageManager()) != null) { startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE); } }
在onActivityResult里面接收視頻Uri來播放
@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK) { Uri videoUri = intent.getData(); Log.d(TAG, "onActivityResult: " + videoUri); mVideoView.setVideoURI(videoUri); mVideoView.requestFocus(); mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.setLooping(false);//設置視頻重復播放 } }); mVideoView.start();//播放視頻 MediaController mediaController = new MediaController(this);//顯示控制條 mVideoView.setMediaController(mediaController); mediaController.setMediaPlayer(mVideoView);//設置控制的對象 mediaController.show(); } }
以上是“Android中視頻采集的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。