當前位置:編程學習大全網 - 編程語言 - android app 如何與uvc攝像頭通訊

android app 如何與uvc攝像頭通訊

來看看是怎麽操作UVC攝像頭的吧.我們實現了壹個專門檢測UVC攝像頭的服務:UVCCameraService類,主要代碼如下:

監聽

mUSBMonitor = new USBMonitor(this, new USBMonitor.OnDeviceConnectListener() { @Override

public void onAttach(final UsbDevice device) {

Log.v(TAG, "onAttach:" + device);

mUSBMonitor.requestPermission(device);

} @Override

public void onConnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock, final boolean createNew) {

releaseCamera(); if (BuildConfig.DEBUG) Log.v(TAG, "onConnect:"); try { final UVCCamera camera = new MyUVCCamera();

camera.open(ctrlBlock);

camera.setStatusCallback(new IStatusCallback() { // ... uvc 攝像頭鏈接成功

Toast.makeText(UVCCameraService.this, "UVCCamera connected!", Toast.LENGTH_SHORT).show(); if (device != null)

cameras.append(device.getDeviceId(), camera);

}catch (Exception ex){

ex.printStackTrace();

}

} @Override

public void onDisconnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock) { // ... uvc 攝像頭斷開鏈接

if (device != null) {

UVCCamera camera = cameras.get(device.getDeviceId()); if (mUVCCamera == camera) {

mUVCCamera = null;

Toast.makeText(UVCCameraService.this, "UVCCamera disconnected!", Toast.LENGTH_SHORT).show();

liveData.postValue(null);

}

cameras.remove(device.getDeviceId());

}else {

Toast.makeText(UVCCameraService.this, "UVCCamera disconnected!", Toast.LENGTH_SHORT).show();

mUVCCamera = null;

liveData.postValue(null);

}

} @Override

public void onCancel(UsbDevice usbDevice) {

releaseCamera();

} @Override

public void onDettach(final UsbDevice device) {

Log.v(TAG, "onDettach:");

releaseCamera();// AppContext.getInstance().bus.post(new UVCCameraDisconnect());

}

});123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657

這個類主要實現UVC攝像頭的監聽\鏈接\銷毀\反監聽.當有UVC攝像頭鏈接成功後,會創建壹個mUVCCamera對象.

然後在MediaStream裏, 我們改造了switchCamera,當參數傳2時,表示要切換到UVCCamera(0,1分別表示切換到後置\前置攝像頭).

創建

在創建攝像頭時,如果是要創建uvc攝像頭,那直接從服務裏面獲取之前創建的mUVCCamera實例:

if (mCameraId == 2) {

UVCCamera value = UVCCameraService.liveData.getValue(); if (value != null) { // uvc camera.

uvcCamera = value;

value.setPreviewSize(width, height,1, 30, UVCCamera.PIXEL_FORMAT_YUV420SP,1.0f); return; // value.startPreview();

}else{

Log.i(TAG, "NO UVCCamera");

uvcError = new Exception("no uvccamera connected!"); return;

} // mCameraId = 0;

}123456789101112131415

預覽

在預覽時,如果uvc攝像頭已經創建了,那執行uvc攝像頭的預覽操作:

UVCCamera value = uvcCamera;if (value != null) {

SurfaceTexture holder = mSurfaceHolderRef.get(); if (holder != null) {

value.setPreviewTexture(holder);

} try {

value.setFrameCallback(uvcFrameCallback, UVCCamera.PIXEL_FORMAT_YUV420SP/*UVCCamera.PIXEL_FORMAT_NV21*/);

value.startPreview();

cameraPreviewResolution.postValue(new int[]{width, height});

}catch (Throwable e){

uvcError = e;

}

}1234567891011121314

這裏我們選的colorFormat為PIXEL_FORMAT_YUV420SP 相當於標準攝像頭的NV21格式.

關閉預覽

同理,關閉時,調用的是uvc攝像頭的關閉.

UVCCamera value = uvcCamera; if (value != null) {

value.stopPreview();

}1234

銷毀

因為我們這裏並沒有實質性的創建,所以銷毀時也僅將實例置為null就可以了.

UVCCamera value = uvcCamera;if (value != null) { // value.destroy();

uvcCamera = null;

}12345

有了這些操作,我們看看上層怎麽調用,

首先需要在Manifest裏面增加若幹代碼,具體詳見UVCCamera工程說明.如下:

<activity android:name=".UVCActivity" android:launchMode="singleInstance">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

<intent-filter>

<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />

</intent-filter>

<intent-filter>

<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />

</intent-filter>

<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"

android:resource="@xml/device_filter" />

</activity>1234567891011121314151617181920

然後,的代碼在UVCActivity裏,這個類可以在library分支的myapplication工程裏找到.即這裏.

啟動或者停止UVC攝像頭推送:

public void onPush(View view) { // 異步獲取到MediaStream對象.

getMediaStream().subscribe(new Consumer<MediaStream>() { @Override

public void accept(final MediaStream mediaStream) throws Exception { // 判斷當前的推送狀態.

MediaStream.PushingState state = mediaStream.getPushingState(); if (state != null && state.state > 0) { // 當前正在推送,那終止推送和預覽

mediaStream.stopStream();

mediaStream.closeCameraPreview();

}else{ // switch 0表示後置,1表示前置,2表示UVC攝像頭

// 異步開啟UVC攝像頭

RxHelper.single(mediaStream.switchCamera(2), null).subscribe(new Consumer<Object>() { @Override

public void accept(Object o) throws Exception { // 開啟成功,進行推送.

// ...

mediaStream.startStream("cloud.easydarwin.org", "554", id);

}

}, new Consumer<Throwable>() { @Override

public void accept(final Throwable t) throws Exception { // ooop...開啟失敗,提示下...

t.printStackTrace();

runOnUiThread(new Runnable() { @Override

public void run() {

Toast.makeText(UVCActivity.this, "UVC攝像頭啟動失敗.." + t.getMessage(), Toast.LENGTH_SHORT).show();

}

});

}

});

}

}

});

}12345678910111213141516171819202122232425262728293031323334353637

這樣,整個推送就完成了.如果壹切順利,應當能在VLC播放出來UVC攝像頭的視頻了~~

我們再看看如何錄像.也非常簡單…

public void onRecord(View view) { // 開始或結束錄像.

final TextView txt = (TextView) view;

getMediaStream().subscribe(new Consumer<MediaStream>() { @Override

public void accept(MediaStream mediaStream) throws Exception { if (mediaStream.isRecording()){ // 如果正在錄像,那停止.

mediaStream.stopRecord();

txt.setText("錄像");

}else { // 沒在錄像,開始錄像...

// 表示最大錄像時長為30秒,30秒後如果沒有停止,會生成壹個新文件.依次類推...

// 文件格式為test_uvc_0.mp4,test_uvc_1.mp4,test_uvc_2.mp4,test_uvc_3.mp4

String path = getExternalFilesDir(Environment.DIRECTORY_MOVIES) + "/test_uvc.mp4";

mediaStream.startRecord(path, 30000); final TextView pushingStateText = findViewById(R.id.pushing_state);

pushingStateText.append("\n錄像地址:" + path);

txt.setText("停止");

}

}

});

}123456789101112131415161718192021

UVC攝像頭還支持後臺推送,即不預覽的情況下進行推送,同時再切換到前臺繼續預覽.只需要調用壹個接口即可實現,如下:

@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {

ms.setSurfaceTexture(surfaceTexture); // 設置預覽的surfaceTexture}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {

ms.setSurfaceTexture(null); // 設置預覽窗口為null,表示關閉預覽功能

return true;

}123456789

如果要徹底退出uvc攝像頭的預覽\推送,那只需要同時退出服務即可.

public void onQuit(View view) { // 退出

finish(); // 終止服務...

Intent intent = new Intent(this, MediaStream.class);

stopService(intent);

}1234567

## 獲取更多信息 ##

  • 上一篇:大學自我評估
  • 下一篇:瑪瑙珠子怎麽編手鏈教程
  • copyright 2024編程學習大全網