1.录像、推流 回调,关联摄像头
2.推流 startPush主线程(P2
3.
| | |
| | | private void startMedia(MediaArgu media) { |
| | | if (media == null) { |
| | | Timber.w("startMedia: media is null"); |
| | | notifyCallback(1, -1, "MediaArgu is null"); |
| | | notifyCallback(1, -1, "MediaArgu is null",1); |
| | | return; |
| | | } |
| | | |
| | |
| | | p2Service.startMedia(media); |
| | | } catch (RemoteException e) { |
| | | Timber.e(e, "startMedia forward to P2 failed"); |
| | | notifyCallback(1, -3, "启动P2服务失败: " + e.getMessage()); |
| | | notifyCallback(1, -3, "启动P2服务失败: " + e.getMessage(),2); |
| | | } |
| | | } else { |
| | | // 等待连接完成后执行 |
| | |
| | | usbCameraPushManager.startPush(media); |
| | | } else { |
| | | Timber.w("推流仅支持USB摄像头"); |
| | | notifyCallback(1, -4, "推流仅支持USB摄像头"); |
| | | notifyCallback(1, -4, "推流仅支持USB摄像头",1); |
| | | } |
| | | } else { |
| | | // 录像 |
| | |
| | | * @param type 类型:0-录像 1-推流 2-文件名类型等 |
| | | * @param errCode 错误码:0-成功,其他为错误码 |
| | | * @param message 消息内容 |
| | | * @param cameraId 0-android camera 1-P1 usb 2-P2 usb |
| | | */ |
| | | private void notifyCallback(int type, int errCode, String message) { |
| | | private void notifyCallback(int type, int errCode, String message,int cameraId) { |
| | | ResponseVO response = new ResponseVO(); |
| | | response.setType(type); |
| | | response.setCameraId(cameraId); |
| | | response.setErrCode(errCode); |
| | | response.setMessage(message); |
| | | notifyCallback(response); |
| | |
| | | */ |
| | | public class ResponseVO implements Parcelable { |
| | | private int type;//0-luxiang 1-推流 2-文件名类型(在message里面就是文件名) |
| | | |
| | | private int cameraId;// @param cameraId 0-内置摄像头(android camera) 1-P1 2-P2 |
| | | private String message;//提示信息 |
| | | private int errCode;//0-成功(正在推流或正在录像) 1,没有外置sd卡 2.长时间断网 3.短时间断网和网络切换 4.推流结束、或录像结束 -1usbCamera打不开,6-usbCamera实际使用的分辨率(包含在message) 7Dev(本机摄像)分辨率 8.录像时长 5-录像片段结束 err:-3 msg:SystemError |
| | | |
| | |
| | | this.type = type; |
| | | } |
| | | |
| | | public int getCameraId() { |
| | | return cameraId; |
| | | } |
| | | |
| | | public void setCameraId(int cameraId) { |
| | | this.cameraId = cameraId; |
| | | } |
| | | |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | |
| | | @Override |
| | | public void writeToParcel(Parcel dest, int flags) { |
| | | dest.writeInt(this.type); |
| | | dest.writeInt(this.cameraId); |
| | | dest.writeString(this.message); |
| | | dest.writeInt(this.errCode); |
| | | } |
| | |
| | | |
| | | protected ResponseVO(Parcel in) { |
| | | this.type = in.readInt(); |
| | | this.cameraId = in.readInt(); |
| | | this.message = in.readString(); |
| | | this.errCode = in.readInt(); |
| | | } |
| | |
| | | public String toString() { |
| | | return "ResponseVO{" + |
| | | "type=" + type + |
| | | "cameraId=" + cameraId + |
| | | ", message='" + message + '\'' + |
| | | ", errCode=" + errCode + |
| | | '}'; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 开始推流 |
| | | * 开始推流(对外接口) |
| | | * 注意:AlivcLivePusher 必须在主线程初始化,否则会抛出 |
| | | * "Can't create handler inside thread that has not called Looper.prepare()" |
| | | */ |
| | | public void startPush(MediaArgu media) { |
| | | // 确保在主线程执行实际的启动逻辑 |
| | | if (Looper.myLooper() == Looper.getMainLooper()) { |
| | | startPushInternal(media); |
| | | } else { |
| | | // 当前是 Binder 线程或其他后台线程,切到主线程 |
| | | mainHandler.post(() -> startPushInternal(media)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 真正的启动推流逻辑,必须在主线程调用 |
| | | */ |
| | | private void startPushInternal(MediaArgu media) { |
| | | if (media == null) { |
| | | notifyCallback(1, -1, "MediaArgu is null"); |
| | | return; |
| | |
| | | } |
| | | |
| | | try { |
| | | // 初始化推流SDK |
| | | // 初始化推流SDK(此时已保证在主线程) |
| | | initAlivcPusher(); |
| | | setWaterMask(); |
| | | pushStarted = false; |
| | |
| | | |
| | | cameraExists = true; |
| | | Timber.d("USB摄像头打开成功"); |
| | | |
| | | |
| | | notifyCallback(1, 0, "推流线程已启动,等待推流状态就绪"); |
| | | } catch (Exception e) { |
| | |
| | | response.setType(type); |
| | | response.setErrCode(errCode); |
| | | response.setMessage(message); |
| | | // 设置 cameraId:根据 usbCameraId 区分 P1(1) 和 P2(2) |
| | | if (mediaArgu != null) { |
| | | int usbCameraId = mediaArgu.getUsbCameraId(); |
| | | response.setCameraId(usbCameraId == 2 ? 2 : 1); // 2 -> P2, 其他 -> P1 |
| | | } else { |
| | | response.setCameraId(1); // 默认 P1 |
| | | } |
| | | callback.onResult(response); |
| | | } |
| | | } |
| | |
| | | response.setType(type); |
| | | response.setErrCode(errCode); |
| | | response.setMessage(message); |
| | | // 设置 cameraId:根据 usbCameraId 区分 P1(1) 和 P2(2) |
| | | if (mediaArgu != null) { |
| | | int usbCameraId = mediaArgu.getUsbCameraId(); |
| | | response.setCameraId(usbCameraId == 2 ? 2 : 1); // 2 -> P2, 其他 -> P1 |
| | | } else { |
| | | response.setCameraId(1); // 默认 P1 |
| | | } |
| | | callback.onResult(response); |
| | | } |
| | | } |