我试图用agora video call api从uvc相机流式传输视频。但它不起作用。但是 uvc 相机预览显示在 '''''' 上。
公共类 VideoChatViewActivity 扩展 AppCompatActivity 实现 CameraDialog.CameraDialogParent, CameraViewInterface.Callback{ private static final String TAG = VideoChatViewActivity.class.getSimpleName();
private static final int PERMISSION_REQ_ID = 22; // Permission WRITE_EXTERNAL_STORAGE is not mandatory // for Agora RTC SDK, just in case if you wanna save // logs to external sdcard. private static final String[] REQUESTED_PERMISSIONS = { Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA }; private RtcEngine mRtcEngine; private boolean mCallEnd; private boolean mMuted; private FrameLayout mLocalContainer; private RelativeLayout mRemoteContainer; private VideoCanvas mLocalVideo; private VideoCanvas mRemoteVideo; private ImageView mCallBtn; private ImageView mMuteBtn; private ImageView mSwitchCameraBtn; // Customized logger view private LoggerRecyclerView mLogView; private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() { @Override public void onJoinChannelSuccess(String channel, final int uid, int elapsed) { runOnUiThread(new Runnable() { @Override public void run() { mLogView.logI("Join channel success, uid: " + (uid & 0xFFFFFFFFL)); } }); } @Override public void onUserJoined(final int uid, int elapsed) { runOnUiThread(new Runnable() { @Override public void run() { mLogView.logI("First remote video decoded, uid: " + (uid & 0xFFFFFFFFL)); setupRemoteVideo(uid); } }); } @Override public void onUserOffline(final int uid, int reason) { runOnUiThread(new Runnable() { @Override public void run() { mLogView.logI("User offline, uid: " + (uid & 0xFFFFFFFFL)); onRemoteUserLeft(uid); } }); } }; private void setupRemoteVideo(int uid) { ViewGroup parent = mRemoteContainer; if (parent.indexOfChild(mLocalVideo.view) > -1) { parent = mLocalContainer; } if (mRemoteVideo != null) { return; } SurfaceView view = RtcEngine.CreateRendererView(getBaseContext()); view.setZOrderMediaOverlay(parent == mLocalContainer); parent.addView(view); mRemoteVideo = new VideoCanvas(view, VideoCanvas.RENDER_MODE_HIDDEN, uid); // Initializes the video view of a remote user. mRtcEngine.setupRemoteVideo(mRemoteVideo); } private void onRemoteUserLeft(int uid) { if (mRemoteVideo != null && mRemoteVideo.uid == uid) { removeFromParent(mRemoteVideo); // Destroys remote view mRemoteVideo = null; } } //usb private static final int DEFAULT_CAPTURE_WIDTH = 1280; private static final int DEFAULT_CAPTURE_HEIGHT = 720; @BindView(R.id.camer_view) public View mTextureView; private static final String TAG1 = "Debug"; private UVCCameraHelper mCameraHelper; private CameraViewInterface mUVCCameraView; private AlertDialog mDialog; private boolean isRequest; private boolean isPreview; private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() { @Override public void onAttachDev(UsbDevice device) { // request open permission if (!isRequest) { isRequest = true; if (mCameraHelper != null) { mCameraHelper.requestPermission(0); } } } @Override public void onDettachDev(UsbDevice device) { // close camera if (isRequest) { isRequest = false; mCameraHelper.closeCamera(); showShortMsg(device.getDeviceName() + " is out"); } } @Override public void onConnectDev(UsbDevice device, boolean isConnected) { if (!isConnected) { showShortMsg("fail to connect,please check resolution params"); isPreview = false; } else { isPreview = true; showShortMsg("connecting"); // initialize seekbar // need to wait UVCCamera initialize over new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2500); } catch (InterruptedException e) { e.printStackTrace(); } Looper.prepare(); if(mCameraHelper != null && mCameraHelper.isCameraOpened()) { } Looper.loop(); } }).start(); } } @Override public void onDisConnectDev(UsbDevice device) { showShortMsg("disconnecting"); } }; //usb @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_video_chat_view); ButterKnife.bind(this);//uvc initUI(); mUVCCameraView = (CameraViewInterface) mTextureView; mUVCCameraView.setCallback(this); //mLocalContainer.setCallback(this); mCameraHelper = UVCCameraHelper.getInstance(); mCameraHelper.setDefaultPreviewSize(1280,720); mCameraHelper.initUSBMonitor(this, mUVCCameraView, listener); mCameraHelper.setOnPreviewFrameListener(new AbstractUVCCameraHandler.OnPreViewResultListener() { @Override public void onPreviewResult(byte[] bytes) { try { AgoraVideoFrame frame = new AgoraVideoFrame(); frame.buf = bytes; frame.format = AgoraVideoFrame.FORMAT_NV21; frame.stride = DEFAULT_CAPTURE_WIDTH; frame.height = DEFAULT_CAPTURE_HEIGHT; frame.timeStamp = System.currentTimeMillis(); mRtcEngine.pushExternalVideoFrame(frame); }catch (Exception e){ e.printStackTrace(); } } }); // Ask for permissions at runtime. // This is just an example set of permissions. Other permissions // may be needed, and please refer to our online documents. if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) && checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID)) { initEngineAndJoinChannel(); } } private void initUI() { mLocalContainer = findViewById(R.id.local_video_view_container); mRemoteContainer = findViewById(R.id.remote_video_view_container); mCallBtn = findViewById(R.id.btn_call); mMuteBtn = findViewById(R.id.btn_mute); mSwitchCameraBtn = findViewById(R.id.btn_switch_camera); mLogView = findViewById(R.id.log_recycler_view); // Sample logs are optional. showSampleLogs(); } private void showSampleLogs() { mLogView.logI("Welcome to Agora 1v1 video call"); mLogView.logW("You will see custom logs here"); mLogView.logE("You can also use this to show errors"); } private boolean checkSelfPermission(String permission, int requestCode) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode); return false; } return true; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == PERMISSION_REQ_ID) { if (grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED || grantResults[2] != PackageManager.PERMISSION_GRANTED) { showLongToast("Need permissions " + Manifest.permission.RECORD_AUDIO + "/" + Manifest.permission.CAMERA); finish(); return; } // Here we continue only if all permissions are granted. // The permissions can also be granted in the system settings manually. initEngineAndJoinChannel(); } } private void showLongToast(final String msg) { this.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show(); } }); } private void initEngineAndJoinChannel() { initializeEngine(); setupVideoConfig(); setupLocalVideo(); joinChannel(); } private void initializeEngine() { try { mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRtcEventHandler); } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e)); } } private void setupVideoConfig() { mRtcEngine.enableVideo(); mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration( VideoEncoderConfiguration.VD_640x360, VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15, VideoEncoderConfiguration.STANDARD_BITRATE, VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT)); } private void setupLocalVideo() {
. SurfaceView 视图 = RtcEngine.CreateRendererView(getBaseContext()); view.setZOrderMediaOverlay(true); mLocalContainer.addView(view); mLocalVideo = new VideoCanvas(view, VideoCanvas.RENDER_MODE_HIDDEN, 0); mRtcEngine.setupLocalVideo(mLocalVideo); }
private void joinChannel() { String token = getString(R.string.agora_access_token); if (TextUtils.isEmpty(token) || TextUtils.equals(token, "#YOUR ACCESS TOKEN#")) { token = null; // default, no token } mRtcEngine.joinChannel(token, "streaming", "Extra Optional Data", 0); } @Override protected void onDestroy() { super.onDestroy(); if (!mCallEnd) { leaveChannel(); } RtcEngine.destroy(); } private void leaveChannel() { mRtcEngine.leaveChannel(); } public void onLocalAudioMuteClicked(View view) { mMuted = !mMuted; mRtcEngine.muteLocalAudioStream(mMuted); int res = mMuted ? R.drawable.btn_mute : R.drawable.btn_unmute; mMuteBtn.setImageResource(res); } public void onSwitchCameraClicked(View view) { mRtcEngine.switchCamera(); } public void onCallClicked(View view) { if (mCallEnd) { startCall(); mCallEnd = false; mCallBtn.setImageResource(R.drawable.btn_endcall); } else { endCall(); mCallEnd = true; mCallBtn.setImageResource(R.drawable.btn_startcall); } showButtons(!mCallEnd); } private void startCall() { setupLocalVideo(); joinChannel(); } private void endCall() { removeFromParent(mLocalVideo); mLocalVideo = null; removeFromParent(mRemoteVideo); mRemoteVideo = null; leaveChannel(); } private void showButtons(boolean show) { int visibility = show ? View.VISIBLE : View. SurfaceView view .GONE; mMuteBtn.setVisibility(visibility); mSwitchCameraBtn.setVisibility(visibility); } private ViewGroup removeFromParent(VideoCanvas canvas) { if (canvas != null) { ViewParent parent = canvas.view.getParent(); if (parent != null) { ViewGroup group = (ViewGroup) parent; group.removeView(canvas.view); return group; } } return null; } private void switchView(VideoCanvas canvas) { ViewGroup parent = removeFromParent(canvas); if (parent == mLocalContainer) { if (canvas.view instanceof SurfaceView) { ((SurfaceView) canvas.view).setZOrderMediaOverlay(false); } mRemoteContainer.addView(canvas.view); } else if (parent == mRemoteContainer) { if (canvas.view instanceof SurfaceView) { ((SurfaceView) canvas.view).setZOrderMediaOverlay(true); } mLocalContainer.addView(canvas.view); } } public void onLocalContainerClick(View view) { switchView(mLocalVideo); switchView(mRemoteVideo); } ///uvc @Override protected void onStart() { super.onStart(); // step.2 register USB event broadcast if (mCameraHelper != null) { mCameraHelper.registerUSB(); } } @Override protected void onStop() { super.onStop(); // step.3 unregister USB event broadcast if (mCameraHelper != null) { mCameraHelper.unregisterUSB(); } } private void showShortMsg(String msg) { // Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } @Override public USBMonitor getUSBMonitor(){ return mCameraHelper.getUSBMonitor(); } @Override public void onDialogResult(boolean canceled) { if (canceled) { showShortMsg("cancel"); } } @Override public void onSurfaceCreated(CameraViewInterface cameraViewInterface, Surface surface) { if (!isPreview && mCameraHelper.isCameraOpened()) { mCameraHelper.startPreview(mUVCCameraView); isPreview = true; } } @Override public void onSurfaceChanged(CameraViewInterface cameraViewInterface, Surface surface, int i, int i1) { } @Override public void onSurfaceDestroy(CameraViewInterface cameraViewInterface, Surface surface) { if (isPreview && mCameraHelper.isCameraOpened()) { mCameraHelper.stopPreview(); isPreview = false; } }
}
问问题
53 次
1 回答
0
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_chat_view);
initUI();
// Ask for permissions at runtime.
// This is just an example set of permissions. Other permissions
// may be needed, and please refer to our online documents.
if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID)) {
initEngineAndJoinChannel();
}
//xiaobing add
final View view = findViewById(R.id.camera_view);
mUVCCameraView = (CameraViewInterface)view;
mUSBMonitor = new USBMonitor(this, mOnDeviceConnectListener);
mUVCCameraView.setAspectRatio(previewWidth / (float)previewHeight);
mCameraHandler = UVCCameraHandler.createHandler(this,
mUVCCameraView, previewWidth,
previewHeight, BANDWIDTH_FACTORS[0],
firstDataCallBack);
}
//xiaobing add
private void startPreview() {
final SurfaceTexture st = mUVCCameraView.getSurfaceTexture();
mCameraHandler.startPreview(new Surface(st));
}
//xiaobing add
UvcCameraDataCallBack firstDataCallBack = new UvcCameraDataCallBack() {
@Override
public void getData(byte[] data) {
if (DEBUG) {
Log.v(TAG, "data callback:" + data.length);
}
AgoraVideoFrame frame = new AgoraVideoFrame();
frame.buf = data;
frame.format = AgoraVideoFrame.FORMAT_NV12;
frame.stride = previewWidth;
frame.height = previewHeight;
frame.timeStamp = System.currentTimeMillis();
mRtcEngine.pushExternalVideoFrame(frame);
}
};
//xiaobing add
@Override
protected void onStart() {
super.onStart();
if (DEBUG) Log.v(TAG, "onStart:");
mUSBMonitor.register();
if (mUVCCameraView != null)
mUVCCameraView.onResume();
if (!mCameraHandler.isOpened()) {
UsbManager um = (UsbManager) (getSystemService(Context.USB_SERVICE));
HashMap<String, UsbDevice> map = um.getDeviceList();
ArrayList<String> names = new ArrayList<>();
final ArrayList<UsbDevice> devices = new ArrayList<>();
for(Map.Entry<String, UsbDevice> item : map.entrySet()) {
String name = item.getValue().getProductName();
String vid = Integer.toHexString(item.getValue().getVendorId());
String pid = Integer.toHexString(item.getValue().getProductId());
String all = "" + name + " VID:" + vid
+ " PID:" + pid;
Log.v("xiaobing", "all:" + all);
names.add(all);
devices.add(item.getValue());
if(item.getValue().getProductId()==1383 && (item.getValue().getVendorId() == 3034)){
mDev = item.getValue();
mUSBMonitor.requestPermission(mDev);
//为了同时支持手机和眼镜,只有获得了眼镜的设备才选择本地视频
mRtcEngine.setExternalVideoSource(true, true, true);
mLogView.logI("使用USB摄像头!");
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
于 2022-02-08T03:09:14.250 回答