0
  • 我试图用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;
          }
      }
    

    }

4

1 回答 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 回答