Skip to content

接口文档

Camera SDK功能

初始化

在应用的 Application 中初始化 SDK:

java
public class MyApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        InstaCameraSDK.init(this);
    }
}

连接模块

判断相机是否连接

通过获取当前相机的连接类型来获知相机是否处于连接状态。

java
private boolean isCameraConnected() {
    int type = InstaCameraManager.getInstance().getCameraConnectedType();
    return type != InstaCameraManager.CONNECT_TYPE_NONE;
}

连接类型有以下四种结果:

  1. 未连接:InstaCameraManager.CONNECT_TYPE_NONE
  2. USB连接:InstaCameraManager.CONNECT_TYPE_USB
  3. Wi-Fi连接:InstaCameraManager.CONNECT_TYPE_WIFI
  4. 蓝牙连接:InstaCameraManager.CONNECT_TYPE_BLE

连接相机

您可以通过蓝牙、Wi-Fi或USB的方式连接相机。

注意:您必须在主线程上执行连接操作。

注意:相机与App建立连接后,如果App切换至后台,由于Android系统的原因,导致会断开连接。因此需要开启一个前台服务以防止与相机断开连接。这个前台服务器由开发者自行实现。相关代码可参考SDK Demo;

蓝牙连接

注意:蓝牙连接需要蓝牙相关的权限授权成功。

注意:蓝牙连接的情况下,不支持大数据传输。因此传输数据比较大的功能是不支持的。

不支持功能:直播、预览、获取支持列表、下载文件、固件升级、播放、导出图像。

  1. 发起蓝牙扫描
java
InstaCameraManager.getInstance().startBleScan();
  1. 设置蓝牙扫描监听
java
InstaCameraManager.getInstance().setScanBleListener(new IScanBleListener() {
    @Override
    public void onScanStartSuccess() {
        //蓝牙即将开始扫描
    }

    @Override
    public void onScanStartFail() {
        //蓝牙扫描失败
    }

    @Override
    public void onScanning(BleDevice bleDevice) {
        //扫描到一个新的蓝牙设备,可以在此处更新蓝牙设备列表
    }

    @Override
    public void onScanFinish(List<BleDevice> bleDeviceList) {
        //蓝牙扫描结束
    }
});
  1. 停止蓝牙扫描
java
InstaCameraManager.getInstance().stopBleScan();
  1. 判断是否正在蓝牙扫描中
java
InstaCameraManager.getInstance().isBleScanning();
  1. 与相机建立蓝牙连接
java
InstaCameraManager.getInstance().connectBle(bleDevice);
Wi-Fi连接

注意:必须保证手机已经连接上了相机的Wi-Fi。相机的Wi-Fi密码在相机中的设置菜单可以查看,或者通过蓝牙连接,调用读取相机Wi-Fi的名称和密码去自动连接。

java
InstaCameraManager.getInstance().openCamera(InstaCameraManager.CONNECT_TYPE_WIFI);
USB连接

注意:必须保证手机与相机已经建立了USB连接,并且相机需要切换到安卓模式。

java
InstaCameraManager.getInstance().openCamera(InstaCameraManager.CONNECT_TYPE_USB);

断开连接

当你想断开连接时,你可以调用下列代码。

java
InstaCameraManager.getInstance().closeCamera();

Wi-Fi管理模块

开启Wi-Fi

在蓝牙连接的情况下,可以通过下面的代码控制相机WI-Fi的开启和关闭。

java
ICameraOperateCallback callback = new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // 指令执行成功
    }

    @Override
    public void onFailed() {
        // 指令执行失败
    }

    @Override
    public void onCameraConnectError() {
        // 相机发生断连或未连接
    }
};
// 打开相机wifi, 使用相机默认信道
InstaCameraManager.getInstance().openCameraWifi(callback);
// 指定信道打开相机wifi
InstaCameraManager.getInstance().openCameraWifi(int countryChannel ,callback);

// 关闭相机wifi
InstaCameraManager.getInstance().closeCameraWifi(callback)

// 重启相机Wi-Fi,内含关闭和开启2个操作,使用相机默认信道开启
InstaCameraManager.getInstance().resetCameraWifi(callback)
// 指定信道重启相机Wi-Fi
InstaCameraManager.getInstance().resetCameraWifi(int countryChannel callback)

Wi-Fi信息获取

java
// 获取相机Wi-Fi信息
WifiInfo wifiInfo = InstaCameraManager.getInstance().getWifiInfo();

// Wi-Fi名称
String ssid = wifiInfo.getSsid();

// Wi-Fi密码
String ssid = wifiInfo.getPwd();

// 密码版本
int pwdVersion= wifiInfo.getPwdVersion();

// Wi-Fi信道
int channel= wifiInfo.getChannel();

// mac地址
String address = wifiInfo.getMacAddress();

// 获取Wi-Fi国家码
Strin country = InstaCameraManager.getInstance().getWifiCountry();

切换Wi-Fi频段

java
// 获取当前国家码和Wi-Fi信道
InstaCameraManager.getInstance().fetchWifiChannel((countryCode, cameraChannel) -> {
    // 获取国家码和当前Wi-Fi信道
});

// 设置Wi-Fi国家码
InstaCameraManager.getInstance().setWifiCountry("CN", new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
         // 设置成功
    }

    @Override
    public void onFailed() {
        // 设置失败
    }

    @Override
    public void onCameraConnectError() {
        // 相机连接错误
    }
});

// 获取当前支持的信道列表
int[] channelList = InstaCameraManager.getInstance().getWifiChannelList();

信息获取模块

同步相机参数

同步相机参数意味着一次性读取相机内部的所有参数,并在应用程序中进行缓存。调用下述代码即可同步所有相机参数(所有参数状态的同步)。

java
InstaCameraManager.getInstance().fetchCameraOptions(new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // 相机参数同步成功
    }

    @Override
    public void onFailed() {
        // 相机参数同步失败
    }

    @Override
    public void onCameraConnectError() {
        // 相机连接失败,可能发生相机断连事件
    }
});

获取相机支持列表

X4及以后相机的拍摄模式和拍摄属性都是以支持列表中所配置的属性为准。不同相机所支持的拍摄模式有所不同,且不同拍摄模式下所支持的拍摄属性亦存在差别,在拍摄前需要同步相机的支持列表(Json文件)。

初始化支持列表

当进入拍摄页或切换镜头时,需对支持列表进行初始化。可通过调用下述代码实现:

java
InstaCameraManager.getInstance().initCameraSupportConfig(success -> {
    // success:是否初始化成功
});
拍摄模式支持

相机的每个镜头所支持的拍摄模式均存在差异,需通过以下代码获取其支持的拍摄模式。

java
// 获取所有支持的拍摄模式
List<CaptureMode> support = InstaCameraManager.getInstance().getSupportCaptureMode();
拍摄属性支持

每种拍摄模式所支持的拍摄属性亦存在差异,需通过以下代码获取其支持的拍摄属性。

java
// 参数传入指定的拍摄模式
List<CaptureSetting> support = InstaCameraManager.getInstance().getSupportCaptureSettingList(CaptureMode.CAPTURE_NORMAL);
拍摄属性的取值范围

拍摄属性的取值范围同样是在支持列表中所配置的,需通过以下代码获取其支持的拍摄属性的取值范围。

java
// 获取CaptureSetting.RECORD_DURATION的属性值取值范围,返回一个List<RecordDuration>列表
InstaCameraManager.getInstance().getSupportRecordDurationList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.RECORD_RESOLUTION的属性值取值范围,返回一个List<RecordResolution>列表
InstaCameraManager.getInstance().getSupportRecordResolutionList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.PHOTO_RESOLUTION的属性值取值范围,返回一个List<PhotoResolution>列表
InstaCameraManager.getInstance().getSupportPhotoResolutionList(CaptureMode.CAPTURE_NORMAL);

// 获取CaptureSetting.INTERVAL的属性值取值范围,返回一个List<Interval>列表
InstaCameraManager.getInstance().getSupportIntervalList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.HDR_STATUS的属性值取值范围,返回一个List<HdrStatus>列表
InstaCameraManager.getInstance().getSupportHdrStatusList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.PHOTO_HDR_TYPE的属性值取值范围,返回一个List<PhotoHdrType>列表
InstaCameraManager.getInstance().getSupportPhotoHdrTypeList(CaptureMode.CAPTURE_NORMAL);

// 获取CaptureSetting.GAMMA_MODE的属性值取值范围,返回一个List<GammaMode>列表
InstaCameraManager.getInstance().getSupportGammaModeList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.RAW_TYPE的属性值取值范围,返回一个List<RawType>列表
InstaCameraManager.getInstance().getSupportRawTypeList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.PANO_EXPOSURE_MODE的属性值取值范围,返回一个List<PanoExposureMode>列表
InstaCameraManager.getInstance().getSupportPanoExposureList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.EXPOSURE的属性值取值范围,返回一个List<Exposure>列表
InstaCameraManager.getInstance().getSupportExposureList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.ISO的属性值取值范围,返回一个List<ISO>列表
InstaCameraManager.getInstance().getSupportISOList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.ISO_TOP_LIMIT的属性值取值范围,返回一个List<ISOTopLimit>列表
InstaCameraManager.getInstance().getSupportISOTopLimitList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.SHUTTER_MODE的属性值取值范围,返回一个List<ShutterMode>列表
InstaCameraManager.getInstance().getSupportShutterModeList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.SHUTTER的属性值取值范围,返回一个List<Shutter>列表
InstaCameraManager.getInstance().getSupportShutterList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.EV的属性值取值范围,返回一个List<Ev>列表
InstaCameraManager.getInstance().getSupportEVList(CaptureMode.CAPTURE_NORMAL);

// 获取CaptureSetting.EV_INTERVAL的属性值取值范围,返回一个List<EVInterval>列表
InstaCameraManager.getInstance().getSupportEVIntervalList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.AEB的属性值取值范围,返回一个List<AEB>列表
InstaCameraManager.getInstance().getSupportAEBList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.WB的属性值取值范围,返回一个List<WB>列表
InstaCameraManager.getInstance().getSupportWBList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.INTERNAL_SPLICING的属性值取值范围,返回一个List<InternalSplicing>列表
InstaCameraManager.getInstance().getSupportInternalSplicingList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.DARK_EIS_ENABLE的属性值取值范围,返回一个List<DarkEisType>列表
InstaCameraManager.getInstance().getSupportDarkEisList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.BURST_CAPTURE的属性值取值范围,返回一个List<BurstCapture>列表
InstaCameraManager.getInstance().getSupportBurstCaptureList(CaptureMode.TIMELAPSE);

// 获取CaptureSetting.I_LOG的属性值取值范围,返回一个List<ILogStatus>列表
InstaCameraManager.getInstance().getSupportILogStatusList(CaptureMode.TIMELAPSE);

信息获取

相机型号
java
// 获取相机类型  如:Insta360 X4
String cameraType = InstaCameraManager.getInstance().getCameraType();
// 获取枚举
CameraType type = CameraType.getForType(cameraType);
相机序列号
java
InstaCameraManager.getInstance().getCameraSerial();
固件版本号
java
// 获取相机固件版本  如:0.9.24
String fwVersion = InstaCameraManager.getInstance().getCameraVersion();
激活时间
java
// 获取相机激活时间,未激活时间为0.
long activeTime = InstaCameraManager.getInstance().getActiveTime();
SD卡总容量
java
// 获取SD卡总容量大小
long totalSpace = InstaCameraManager.getInstance().getCameraStorageTotalSpace();
SD卡剩余容量
java
// 获取SD卡可用空间大小
long freeSpace = InstaCameraManager.getInstance().getCameraStorageFreeSpace();

// 获取SD卡余量(如果是拍照,则单位是张,如果是录像,则返回可持续录制的时间)
int remaining= InstaCameraManager.getInstance().getRemaining(CaptureMode captureMode);
电池电量信息
java
// 获取电池类型
// THICK = 0;       //厚电池
// THIN = 1;        //薄电池(相机默认值)
// VERTICAL;        //竖拍电池
// NONE;            //未插电池只有USB供电的情况
InstaCameraManager.getInstance().getBatteryType();

// 获取当前电量 : 0-100
int level = InstaCameraManager.getInstance().getCameraCurrentBatteryLevel();
相机系统时间
java
// 获取相机系统时间
long mediaTime = InstaCameraManager.getInstance().getMediaTime();

相机状态获取

是否在充电状态
java
// 是否正在充电
boolean isCharging = InstaCameraManager.getInstance().isCameraCharging();
是否工作中
java
// 相机是否工作中
boolean isWorking = InstaCameraManager.getInstance().isCameraWorking();

//指定的拍摄模式是否正在工作中
boolean isNormalCapturing = InstaCameraManager.getInstance().isCameraWorking(CaptureMode.CAPTURE_NORMAL);
SD卡是否可用
java
// SD卡是否可用
boolean isEnable = InstaCameraManager.getInstance().isSdCardEnabled();

通知模块

您可以在多个页面上注册/注销ICameraChangedCallback,以监视相机状态的变化。

java
public abstract class BaseObserveCameraActivity extends AppCompatActivity implements ICameraChangedCallback {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InstaCameraManager.getInstance().registerCameraChangedCallback(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        InstaCameraManager.getInstance().unregisterCameraChangedCallback(this);
    }

    /**
     * 相机状态变化
     *
     * @param enabled:相机是否可用
     * @param connectType:连接类型
     */
    @Override
    public void onCameraStatusChanged(boolean enabled, int connectType) {
    }

    /**
     * 相机连接失败
     * <p>
     * 一种常见的情况是,
     * 其他手机或这款手机的其他应用程序已经与该摄像机建立连接导致该建立失败,
     * 其他手机需要先断开与此摄像头的连接。
     * @param errorCode:错误码  参考相机连接错误码
     */
    @Override
    public void onCameraConnectError(int errorCode) {
    }

    /**
     * SD卡插入通知
     *
     * @param enabled: 当前SD卡是否可用
     */
    @Override
    public void onCameraSDCardStateChanged(boolean enabled) {
    }

    /**
     * SD卡存储状态已更改
     *
     * @param freeSpace:  当前可用容量大小
     * @param totalSpace: 总容量大小
     */
    @Override
    public void onCameraStorageChanged(long freeSpace, long totalSpace) {
    }

    /**
     * 低电量通知
     */
    @Override
    public void onCameraBatteryLow() {
    }

    /**
     * 相机电源更改通知
     *
     * @param batteryLevel: 当前功率(0-100,充电时始终返回100)
     * @param isCharging:   相机是否正在充电
     */
    @Override
    public void onCameraBatteryUpdate(int batteryLevel, boolean isCharging) {
    }

    /**
     * 相机温度变化通知
     *
     * @param tempLevel: 温度等级
     */
    @Override
    public void onCameraTemperatureChanged(TemperatureLevel tempLevel) {
    }
}

镜头控制模块

相机镜头分为以下三种:

  1. 全景镜头:SensorMode.PANORAMA
  2. 前镜头:SensorMode.FRONT
  3. 后镜头:SensorMode.REAR

镜头判断

java
// 获取当前的镜头模式
SensorMode sensorMode = InstaCameraManager.getInstance().getCurrentSensorMode();

// 判断是否是单镜头
InstaCameraManager.getInstance().isCameraSingleSensorMode();

// 判断是否是双镜头
InstaCameraManager.getInstance().isCameraDualSensorMode();

切换镜头

注意:SDK目前只支持全景镜头,非全景镜头可能会出现未知的问题,请切换至全景镜头下使用SDK。

java
// 切换到相机全景镜头
InstaCameraManager.getInstance().switchPanoramaSensorMode(new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // 镜头切换成功
    }

    @Override
    public void onFailed() {
        // 镜头切换失败
    }

    @Override
    public void onCameraConnectError() {
        // 相机连接错误
    }
});

预览模块

注意:需要跟Media SDK一起使用

开启预览流

成功连接相机后,您可以像这样操纵相机预览流。

如果相机被动断开连接,或者在预览过程中直接调closeCamera(),SDK将自动关闭预览流处理相关状态,而无需调用closePreviewStream()

注意:下面的代码只是开启了预览流,并不能显示预览内容。需要结合MediaSDK的InstaCapturePlayerView控件显示预览内容。

java
public class PreviewActivity extends BaseObserveCameraActivity implements IPreviewStatusListener {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_preview);
        // 打开预览
        InstaCameraManager.getInstance().setPreviewStatusChangedListener(this);
        InstaCameraManager.getInstance().startPreviewStream(PreviewStreamResolution.STREAM_1440_720_30FPS, InstaCameraManager.PREVIEW_TYPE_NORMAL);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (isFinishing()) {
            // 关闭预览
            InstaCameraManager.getInstance().setPreviewStatusChangedListener(null);
            InstaCameraManager.getInstance().closePreviewStream();
        }
    }

    @Override
    public void onOpening() {
        // 预览流正在打开      
    }

    @Override
    public void onOpened() {
        // 预览流已打开,可以播放
    }

    @Override
    public void onIdle() {
        // 预览流已停止
    }

    @Override
    public void onError() {
        // 预览失败
    }
        
        @Override
    public void onExposureData(ExposureData exposureData) {
        // 回调频率500Hz
        // exposureData.timestamp: 相机打开后的时间
        // exposureData.exposureTime: 滚动快门曝光时间
    }

    @Override
    public void onGyroData(List<GyroData> gyroList) {
        // 回调频率10Hz, 每组50个数据
        // gyroData.timestamp: 相机打开后的时间
        // gyroData.ax, gyroData.ay, gyroData.az: 三轴加速度
        // gyroData.gx, gyroData.gy, gyroData.gz: 三轴陀螺仪
    }

    @Override
    public void onVideoData(VideoData videoData) {
        // 回调频率500Hz
        // videoData.timestamp: 相机打开后的时间
        // videoData.data: 每帧预览原始流数据
        // videoData.size: 每帧数据的长度
    }

}

获取当前预览流状态

java
int previewStatus = InstaCameraManager.getInstance().getPreviewStatus();

// 预览状态
// InstaCameraManager.PREVIEW_STATUS_IDLE:预览流未开启
// InstaCameraManager.PREVIEW_STATUS_OPENING:预览流正在打开
// InstaCameraManager.PREVIEW_STATUS_OPENED:预览流已打开

设置预览参数

预览流有以下三种类型:

  1. PREVIEW_TYPE_NORMAL:用于正常预览或拍摄
  2. PREVIEW_TYPE_RECORD:仅用于记录
  3. PREVIEW_TYPE_LIVE:直播
预览分辨率设置

您需要通过下面代码,获得实时支持的相机分辨率

java
List<PreviewStreamResolution> supportedList = InstaCameraManager.getInstance().getSupportedPreviewStreamResolution(InstaCameraManager.PREVIEW_TYPE_LIVE);

注意:对于X4、X5,预览流分辨率无法调整,X4默认设置为2880x1440,X5默认设置为2656x1328。X3可以手动设置分辨率为3840x1920/1440x720。

java
//设置分辨率和预览流类型
InstaCameraManager.getInstance().startPreviewStream(
    PreviewStreamResolution.STREAM_368_368_30FPS,
    InstaCameraManager.PREVIEW_TYPE_LIVE
);
预览音频

您可以设置预览时是否开启音频:

java
PreviewParamsBuilder builder = new PreviewParamsBuilder()
        .setStreamResolution(PreviewStreamResolution.STREAM_368_368_30FPS)
        .setPreviewType(InstaCameraManager.PREVIEW_TYPE_LIVE)
        // 是否开启音频
        .setAudioEnabled(true);
InstaCameraManager.getInstance().startPreviewStream(builder);

拍摄控制模块

获取当前拍摄模式

java
CaptureMode captureMode = InstaCameraManager.getInstance().getCurrentCaptureMode();
// 当前SDK支持以下几种拍摄模式,不同的相机会存在一些区别,具体以相机屏幕显示为准:
普通拍照:CaptureMode.CAPTURE_NORMAL
HDR拍照:CaptureMode.HDR_CAPTURE
超级夜景:CaptureMode.NIGHT_SCENE
连续拍照:CaptureMode.BURST
间隔拍照:CaptureMode.INTERVAL_SHOOTING
星空模式:CaptureMode.STARLAPSE_SHOOTING
普通录像:CaptureMode.RECORD_NORMAL
HDR录像:CaptureMode.HDR_RECORD
子弹时间:CaptureMode.BULLETTIME
延时摄影:CaptureMode.TIMELAPSE
移动延时:CaptureMode.TIME_SHIFT
循环录影:CaptureMode.LOOPER_RECORDING
超级录像:CaptureMode.SUPER_RECORD
慢动作:CaptureMode.SLOW_MOTION
跟拍模式:CaptureMode.SELFIE_RECORD
夜景录像:CaptureMode.PURE_RECORD
直播:CaptureMode.LIVE

模式切换

java
InstaCameraManager.getInstance().setCaptureMode(captureMode, errorCode -> {
    if (errorCode == 0) {
        // 切换成功
    } else {
        // 切换失败
    }
});

拍摄状态通知

注意:X3以及X3之前的相机录制视频超过30分钟的部分会分为2次录制,相机会自动停止录制第一段视频之后开始录制第二段视频。

java
InstaCameraManager.getInstance().setCaptureStatusListener(new ICaptureStatusListener() {
    @Override
    public void onCaptureCountChanged(int captureCount) {
        // 间隔拍照,星空模式等模式的拍摄张数,
    }

    @Override
    public void onCaptureStarting() {
        // 拍摄即将开始
    }

    @Override
    public void onCaptureStopping() {
        // 拍摄即将结束
    }
    
    @Override
    public void onCaptureTimeChanged(long captureTime) {
       // 录制时间回调,只有录像模式下才有
    }

    @Override
    public void onCaptureWorking() {
        // 拍摄中
    }

    @Override
    public void onCaptureFinish(String[] filePaths) {
        // 拍摄结束,返回成片路径
    }
    
    @Override
    public void onCaptureError(int errorCode) {
        // 拍摄失败 error参考 拍摄失败错误码
    }
});

参数设置

拍摄参数

当前SDK支持的拍摄属性如下:

  • 曝光模式:CaptureSetting.EXPOSURE
text
FULL_AUTO     = Exposure.FULL_AUTO,     // 全自动曝光
AUTO          = Exposure.AUTO,          // 自动曝光
ISO_FIRST     = Exposure.ISO_FIRST,     // ISO优先
SHUTTER_FIRST = Exposure.SHUTTER_FIRST, // 快门优先
MANUAL        = Exposure.MANUAL,        // 手动曝光
ADAPTIVE      = Exposure.ADAPTIVE       // 全景独立曝光
  • 全⾃动曝光:Exposure.FULL_AUTO

  • 自动曝光:Exposure.AUTO

  • ISO优先:Exposure.ISO_FIRST

  • 快门优先:Exposure.SHUTTER_FIRST

  • ⼿动曝光:Exposure.MANUAL

  • 全景独立曝光:Exposure.ADAPTIVE

  • EV:CaptureSetting.EV

  • EV间隔:CaptureSetting.EV_INTERVAL

  • 快门速度:CaptureSetting.SHUTTER

  • 快门模式:CaptureSetting.SHUTTER_MODE

text
AUTO   = ShutterMode.AUTO,   // 自动
SPORT  = ShutterMode.SPORT,  // 室内暗光防抖
FASTER = ShutterMode.FASTER  // 极快
  • ISO:CaptureSetting.ISO

  • 最大ISO:CaptureSetting.ISO_TOP_LIMIT

  • 录像分辨率&帧率:CaptureSetting.RECORD_RESOLUTION

  • 拍照分辨率:CaptureSetting.PHOTO_RESOLUTION

  • 白平衡:CaptureSetting.WB

  • AEB:CaptureSetting.AEB

  • 间隔时长:CaptureSetting.INTERVAL

  • 色彩:CaptureSetting.GAMMA_MODE

text
STAND  = GammaMode.STAND,  // 标准
VIVID  = GammaMode.VIVID,  // LOG
LOG    = GammaMode.LOG,    // 鲜艳
FLAT   = GammaMode.FLAT    // 灰调
  • 照片格式:CaptureSetting.RAW_TYPE
text
JPG           = RawType.OFF,          // JPG
JPG_RAW       = RawType.DNG,          // JPG & RAW
PURESHOT      = RawType.PURESHOT,     // PURESHOT
PURESHOT_RAW  = RawType.PURESHOT_RAW, // PURESHOT & RAW
INSP          = RawType.INSP,         // INSP
INSP_RAW      = RawType.INSP_RAW      // RAW & INSP
  • 录像时长:CaptureSetting.RECORD_DURATION

  • 暗光增稳:CaptureSetting.DARK_EIS_ENABLE

  • 全景独立曝光:CaptureSetting.PANO_EXPOSURE_MODE

text
OFF       = PanoExposureMode.OFF,       // 关闭
ON        = PanoExposureMode.ON,        // 独立曝光
LIGHT     = PanoExposureMode.LIGHT,     // 标准
LSOLATED  = PanoExposureMode.LSOLATED   // 高

注意:Insta360 X4相机之前的相机只有开(ON)和关(OFF)2种状态,X4之后的相机的开状态分成了LIGHT、LSOLATED

  • 连拍张数:CaptureSetting.BURST_CAPTURE

  • 机内拼接:CaptureSetting.INTERNAL_SPLICING

text
ON  = InternalSplicing.ON,   // 开
OFF = InternalSplicing.OFF   // 关
  • 录像HDR模式:**CaptureSetting.HDR_STATUS
text
ON  = HdrStatus.ON,   // 开
OFF = HdrStatus.OFF   // 关

注意:从Insta360 X5相机开始,取消DHR录像*CaptureMode.HDR_RECORD,增加CaptureSetting.HDR_STATUS*属性设置以替代。

  • 拍照HDR模式:CaptureSetting.PHOTO_HDR_TYPE
text
开:PhotoHdrType.HDR_ON
关:PhotoHdrType.HDR_OFF
AEB:PhotoHdrType.HDR_AEB

注意:从Insta360 X5相机开始,取消HDR拍照*CaptureMode.HDR_CAPTURE,增加CaptureSetting.PHOTO_HDR_TYPE*属性设置以替代。

  • I-LOG:CaptureSetting.I_LOG
text
ON  = ILogStatus.ON,   // 开
OFF = ILogStatus.OFF   // 关
  • 拍照倒计时:CaptureSetting.LATENCY

注意:仅X5支持

获取当前拍摄参数

您可以通过*InstaCameraManager.getInstance().getXxx(CaptureMode)*方法来获取对应的拍摄属性;

方法参数返回值说明
getRecordDuration()CaptureModeRecordDuration获取录制时长
getRecordResolution()CaptureModeRecordResolution获取录像分辨率,帧率
getPhotoResolution()CaptureModePhotoResolution获取拍照分辨率
getInterval()CaptureModeInterval获取拍摄间隔时长
getHdrStatus()CaptureModeHdrStatus获取普通录像中HDR开关
getPhotoHdrType()CaptureModePhotoHdrType获取普通拍照中HDR开关
getGammaMode()CaptureModeGammaMode获取色彩
getRawType()CaptureModeRawType获取照片格式
getPanoExposureMode()CaptureModePanoExposureMode获取全景独立曝光开关
getExposure()CaptureModeExposure获取曝光模式
getISO()CaptureModeISO获取ISO
getISOTopLimit()CaptureModeISOTopLimit获取ISO上限值
getShutterMode()CaptureModeShutterMode获取快门类型
getShutter()CaptureModeShutter获取快门速度
getEv()CaptureModeEv获取EV
getEVInterval()CaptureModeEVInterval获取EV间隔
getAEB()CaptureModeAEB获取AEB
getWB()CaptureModeWB获取白平衡
getInternalSplicingEnable()CaptureModeInternalSplicing获取机内拼接开关
getDarkEisType()CaptureModeDarkEisType获取暗光增稳开关
getBurstCapture()CaptureModeBurstCapture获取连拍参数
getILogStatus()CaptureModeILogStatus获取I-LOG开关
getLatency()CaptureModeLatency获取拍照倒计时
设置拍摄属性

您可以通过*InstaCameraManager.getInstance().setXxx(CaptureMode)*方法来获取对应的拍摄属性。

方法参数1参数2返回值说明
setRecordDuration()CaptureModeRecordDurationvoid设置录制时长
setRecordResolution()CaptureModeRecordResolutionvoid设置录像分辨率,帧率
setPhotoResolution()CaptureModePhotoResolutionvoid设置拍照分辨率
setInterval()CaptureModeIntervalvoid设置拍摄间隔时长
setHdrStatus()CaptureModeHdrStatusvoid设置普通录像中HDR开关
setPhotoHdrType()CaptureModePhotoHdrTypevoid设置普通拍照中HDR开关
setGammaMode()CaptureModeGammaModevoid设置色彩
setRawType()CaptureModeRawTypevoid设置照片格式
setPanoExposureMode()CaptureModePanoExposureModevoid设置全景独立曝光开关
setExposure()CaptureModeExposurevoid设置曝光模式
setISO()CaptureModeISOvoid设置ISO
setISOTopLimit()CaptureModeISOTopLimitvoid设置ISO上限值
setShutterMode()CaptureModeShutterModevoid设置快门类型
setShutter()CaptureModeShuttervoid设置快门速度
setEv()CaptureModeEvvoid设置EV
setEVInterval()CaptureModeEVIntervalvoid设置EV间隔
setAEB(CaptureModeCaptureModeAEBvoid设置AEB
setWB()CaptureModeWBvoid设置白平衡
setInternalSplicingEnable()CaptureModeInternalSplicingvoid设置机内拼接开关
setDarkEisType()CaptureModeDarkEisTypevoid设置暗光增稳开关
setBurstCapture()CaptureModeBurstCapturevoid设置连拍参数
setILogStatusCaptureModeILogStatusvoid设置I-LOG开关
setLatency()CaptureModeLatencyvoid设置拍照倒计时
批量设置拍摄属性
java
//开始批量设置拍摄属性
InstaCameraManager.getInstance().beginSettingOptions();

InstaCameraManager.getInstance().setEv(captureMode, EV.EV_0);
InstaCameraManager.getInstance().setShutter(captureMode, Shutter.SHUTTER_1_2);
...
InstaCameraManager.getInstance().setWB(captureMode, WB.WB_2200K);

//提交批量设置以生效
InstaCameraManager.getInstance().commitSettingOptions();
拍摄属性之间的依赖关系

不同的拍摄属性之间存在相互影响的关系。当设置 A 属性时,可能会对 B 属性的**支持列表**产生影响。例如快门速度和FPS之间的影响。因此,在设置属性之后,有必要对其影响的其他属性进行检查。

注意:因为回调函数可能会回调多次,每次回调中的CaptureSetting列表元素都可能不一样

示例代码如下:

java
// 示例中仅展示setPhotoHdrType的案例,其他属性设置与此相同;
InstaCameraManager.getInstance().setPhotoHdrType(captureMode, photoHdrType, new InstaCameraManager.IDependChecker() {
    @Override
    public void check(List<CaptureSetting> captureSettings) {
        // captureSettings:受到影响拍摄属性列表
        // 可在此处更新UI
    }
});

拍照

判断是否拍照模式
java
boolean isPhotoMode = CaptureMode.PURE_RECORD.isPhotoMode();
开始拍照
text
// 开始普通拍照
InstaCameraManager.getInstance().startNormalCapture();

// 开始HDR拍照
InstaCameraManager.getInstance().startHDRCapture();

// 开始超级夜景
InstaCameraManager.getInstance().startNightScene();

// 开始连续拍照
InstaCameraManager.getInstance().startBurstCapture();

// 开始间隔拍照
InstaCameraManager.getInstance().startIntervalShooting();
// 停止间隔拍照
InstaCameraManager.getInstance().stopIntervalShooting();

// 开始星空模式
InstaCameraManager.getInstance().startStarLapseShooting();
// 停止星空模式
InstaCameraManager.getInstance().stopStarLapseShooting();

录像

判断是否是录像模式
java
boolean isVideoMode = CaptureMode.PURE_RECORD.isVideoMode();
开始/停止录像
text
// 开始普通录像
InstaCameraManager.getInstance().startNormalRecord();
// 停止普通录像
InstaCameraManager.getInstance().stopNormalRecord();

// 开始HDR录像
InstaCameraManager.getInstance().startHDRRecord();
// 停止HDR录像
InstaCameraManager.getInstance().stopHDRRecord();

// 开始子弹时间
InstaCameraManager.getInstance().startBulletTime();
// 停止子弹时间
InstaCameraManager.getInstance().stopBulletTime();

// 开始延时摄影
InstaCameraManager.getInstance().startTimeLapse();
// 停止延时摄影
InstaCameraManager.getInstance().stopTimeLapse();

// 开始移动延时
InstaCameraManager.getInstance().startTimeShift();
// 停止移动延时
InstaCameraManager.getInstance().stopTimeShift();

// 开始循环录影
InstaCameraManager.getInstance().startLooperRecord();
// 停止循环录影
InstaCameraManager.getInstance().stopLooperRecord();

// 开始超级录像
InstaCameraManager.getInstance().startSuperRecord();
// 停止超级录像
InstaCameraManager.getInstance().stopSuperRecord();

// 开始慢动作
InstaCameraManager.getInstance().startSlowMotionRecord();
// 停止慢动作
InstaCameraManager.getInstance().stopSlowMotionRecord();

// 开始跟拍模式
InstaCameraManager.getInstance().startSelfieRecord();
// 停止跟拍模式
InstaCameraManager.getInstance().stopSelfieRecord();

// 开始夜景录像
InstaCameraManager.getInstance().startPureRecord();
// 停止夜景录像
InstaCameraManager.getInstance().stopPureRecord();

直播模块

注意:需要跟Media SDK一起使用

判断是否是直播模式

java
boolean isLiveMode = CaptureMode.PURE_RECORD.isLiveMode();

开始直播

注意:预览流关闭之后,相机会自动把拍摄模式切换至普通录像。开支直播之前需要先检查当前拍摄模式是否是直播。

具体的参数(分辨率)需要使用CaptureSetting设置

java
InstaCameraManager.getInstance().startLive(rtmp, netid, new ILiveStatusListener() {

    @Override
    public void onLiveFpsUpdate(int fps) {
        // fps:当前直播帧率
    }

    @Override
    public void onLivePushError(int error, String desc) {
        // 直播推流失败
    }

    @Override
    public void onLivePushFinished() {
        // 直播推流结束
    }

    @Override
    public void onLivePushStarted() {
        // 直播推流开始
    }
});

结束直播

java
InstaCameraManager.getInstance().stopLive();

文件管理模块

获取相机套接字地址

java
// 返回值示例:http://192.168.42.1:80
InstaCameraManager.getInstance().getCameraHttpPrefix();

获取文件URL

java
// 返回值示例:[/DCIM/Camera01/VID_20250326_184618_00_001.insv]
List<String> usls = InstaCameraManager.getInstance().getAllUrlList();

// 包含录像中文件
List<String> usls = InstaCameraManager.getInstance().getAllUrlListIncludeRecording();

文件删除

java
// 删除单个相机文件
InstaCameraManager.getInstance().deleteFile(String filePath,new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // 删除成功
    }

    @Override
    public void onFailed() {
       // 删除失败
    }

    @Override
    public void onCameraConnectError() {
      // 相机连接错误
    }
});

// 批量删除相机文件
InstaCameraManager.getInstance().deleteFileList(List<String> fileUrlList,new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // 删除成功
    }

    @Override
    public void onFailed() {
       // 删除失败
    }

    @Override
    public void onCameraConnectError() {
      // 相机连接错误
    }
});

日志记录模块

设置日志路径

SDK的日志系统支持将日志保存到本地文件中,调用如下代码给日志设置保存位置。

java
// 设置日志缓存路径,如不设置,则不缓存
LogManager.instance.setLogRootPath(StorageUtils.getInternalRootPath() + "/log");

日志开关

开启全局日志实时抓取功能,该功能会抓取所有日志,包括SDK日志,系统日志,宿主APP日志等,并保存在指上面指定的目录中。

java
// 开启日志实时抓取功能
LogManager.instance.startLogDumper();

// 停止日志实时抓取功能
LogManager.instance.stopLogDumper();

GPS数据模块

拍照模式下设置

java
// android.location.Location 类,开发者调用系统api自行获取
Location location;

// 拍照时设置GPS数据
GpsData gpsData = new GpsData();
gpsData.setLatitude(location.getLatitude());
gpsData.setLongitude(location.getLongitude());
gpsData.setAltitude(location.getAltitude());
InstaCameraManager.getInstance().startNormalCapture(gpsData.simpleGpsDataToByteArray());
不同拍照模式下传入GPS数据接口
text
// 开始普通拍照,并传入GPS数据
InstaCameraManager.getInstance().startNormalCapture(byte[]);

// 开始HDR拍照,并传入GPS数据
InstaCameraManager.getInstance().startHDRCapture(byte[]);

// 开始连续拍照,并传入GPS数据
InstaCameraManager.getInstance().startBurstCapture(byte[]);

// 开始间隔拍照,并传入GPS数据
InstaCameraManager.getInstance().stopIntervalShooting(byte[]);

录像模式下设置

录像设置GPS数据分为以下2种情况:

停止录像时

停止录像时和拍照一样,示例代码如下:

java
// android.location.Location 类,开发者调用系统api自行获取
Location location;

// 停止录像时设置GPS数据
GpsData gpsData = new GpsData();
gpsData.setLatitude(location.getLatitude());
gpsData.setLongitude(location.getLongitude());
gpsData.setAltitude(location.getAltitude());
InstaCameraManager.getInstance().stopNormalRecord(gpsData.simpleGpsDataToByteArray());
录像中

录像中可以在的任意时刻设置GPS数据。录像中设置GPS数据,一般是用来制作相机的运动轨迹。因此建议每次设置GPS的时间间隔尽量相同。示例代码如下:

java
// 100ms获取一次gps数据,累计20个gps数据,就设置给相机

private Handler mMainHandler = new Handler(Looper.getMainLooper());
// GPS数据列表
private List<GpsData> mCollectGpsDataList = new ArrayList<GpsData>();

private Runnable mCollectGpsDataRunnable = new Runnable() {
    @Override
    public void run() {
        // android.location.Location 类,开发者调用系统api自行获取
        Location location;
        if (location != null) {
            GpsData gpsData = new GpsData();
            gpsData.setLatitude(location.getLatitude());
            gpsData.setLongitude(location.getLongitude());
            gpsData.setSpeed(location.getSpeed());
            gpsData.setBearing(location.getBearing());
            gpsData.setAltitude(location.getAltitude());
            gpsData.setUTCTimeMs(location.getTime());
            gpsData.setVaild(true);
            mCollectGpsDataList.add(gpsData);
            if (mCollectGpsDataList.size() >= 20) {
                InstaCameraManager.getInstance().setGpsData(GpsData.gpsDataToByteArray(mCollectGpsDataList));
                mCollectGpsDataList.clear();
            }
        }
        mMainHandler.postDelayed(this, 100);
    }
};

// 开始收集GPS数据
mMainHandler.post(mCollectGpsDataRunnable);
不同录像模式下传入GPS数据接口
text
// 停止普通录像,并传入GPS数据
InstaCameraManager.getInstance().stopNormalRecord(byte[]);

// 停止HDR录像,并传入GPS数据
InstaCameraManager.getInstance().stopHDRRecord(byte[]);

// 停止子弹时间,并传入GPS数据
InstaCameraManager.getInstance().stopBulletTime(byte[]);

// 停止延时摄影,并传入GPS数据
InstaCameraManager.getInstance().stopTimeLapse(byte[]);

// 停止移动延时,并传入GPS数据
InstaCameraManager.getInstance().stopTimeShift(byte[]);

// 停止超级录像,并传入GPS数据
InstaCameraManager.getInstance().stopSuperRecord(byte[]);

// 停止循环录影,并传入GPS数据
InstaCameraManager.getInstance().stopLooperRecord(byte[]);

// 停止夜景录像,并传入GPS数据
InstaCameraManager.getInstance().stopPureRecord(byte[]);

// 停止跟拍模式,并传入GPS数据
InstaCameraManager.getInstance().stopSelfieRecord(byte[]);

其它功能模块

激活相机

激活相机需要用到appIdsecretKey这两个数据。这两个数据需要向Insta360官方申请。

注意:激活需要用到网络权限

注意:Nano S 相机不支持此功能。

示例代码如下:

java
String appid = "xxxxxxxx";
String mSecretKey = "xxxxxxx";
InstaCameraManager.getInstance().activateCamera(new SecretInfo(appid , mSecretKey), new InstaCameraManager.IActivateCameraCallback() {
    @Override
    public void onStart() {
        // 开始激活
    }

    @Override
    public void onSuccess() {
        // 激活成功
    }

    @Override
    public void onFailed(String message) {
        // 激活失败  
    }
});

关闭提示音

注意:Nano S 相机不支持获取提示音开关,但支持设置。

相机提示音的开关,示例代码如下:

java
// 打开相机提示音
InstaCameraManager.getInstance().setCameraBeepSwitch(true);

// 判断相机是否开启提示音
boolean isBeep = InstaCameraManager.getInstance().isCameraBeep();

格式化SD卡

java
InstaCameraManager.getInstance().formatStorage(new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // SD卡格式化成功
    }

    @Override
    public void onFailed() {
        // SD卡格式化失败
    }

    @Override
    public void onCameraConnectError() {
        // 相机连接错误
    }
});

相机锁屏

注意:仅支持X4、X5

相机锁屏之后用户无法操作相机屏幕,示例代码如下:

java
// true:锁屏   false:解除锁屏
InstaCameraManager.getInstance().setCameraLockScreen(true);

关闭相机

控制相机关机的指令,示例代码如下:

注意:仅Insta360X5以及之后的相机支持该功能;

java
InstaCameraManager.getInstance().shutdownCamera();

陀螺仪校准

注意:Nano S 相机不支持此功能。

当相机连接到Wi-Fi时,应使用此功能。校准前,请确保相机垂直放置在稳定水平的表面上。

java
InstaCameraManager.getInstance().calibrateGyro(new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
    }

    @Override
    public void onFailed() {
    }

    @Override
    public void onCameraConnectError() {
    }
});

固件升级

通过FwUpgradeManager类去进行固件版本的升级,示例代码如下:

注意:Nano S 相机不支持此功能。

注意:请确保将正确的文件上传到相机,以防止任何潜在的损坏。例如,不要将ONE X固件升级包上传到ONE X2相机。

java
// 判断是否正在升级
FwUpgradeManager.getInstance().isUpgrading();

// 取消升级
FwUpgradeManager.getInstance().cancelUpgrade();

String fwFilePath = "/xxx/InstaOneXFW.bin";
// 升级固件
FwUpgradeManager.getInstance().startUpgrade(fwFilePath, new FwUpgradeListener() {
    @Override
    public void onUpgradeSuccess() {
        // 升级成功回调
    }

    @Override
    public void onUpgradeFail(int errorCode, String message) {
         // 升级失败回调
         // 固件升级错误码
    }

    @Override
    public void onUpgradeCancel() {
         // 升级取消回调
    }

    @Override
    public void onUpgradeProgress(double progress) {
        // 升级进度回调:0-1
    }
});

锐度设置(目前不支持)

错误码

相机连接错误码

错误码解释
-122蓝牙设备断连
501蓝牙发生断连
2201系统报错 BleException.ERROR_CODE_SYSTEM_STATUS_133
2002打开相机超时
2206系统报错 BleException.ERROR_CODE_NOTIFY_FAILURE
2207系统报错 BleException.ERROR_CODE_SHAKE_HAND
3201socket连接失败
3205socket连接超时
3206socket重连超时
4001系统报错 BleException.ERROR_CODE_SYNC_PACK
4101相机类型错误
4103相机同步参数超时
4402相机操作系统错误
4403相机被占用
4405解析proto失败
4406相机同步参数重试超时
4407相机数据异常
4414唤醒蓝牙失败
4417操作过程中相机断开连接
4504连接时摄像头断开连接
4505蓝牙绑定被拒绝
4507蓝牙写入失败
4508设备蓝牙繁忙
4602设备Wi-Fi繁忙
4605USB错误
4606socket因脏数据断连
-14169同步相机参数失败,原因是蓝牙挂了导致的

固件升级错误码

错误码解释
-1000已在升级中
-1001相机未连接
-1002当相机的电池电量低于12%时,升级将失败,请确保相机的电池电量充足
-14004Http服务器错误
400Http服务器错误
500Http服务器错误
-14005套接字IO异常

拍摄失败错误码

错误码解释
-14161电量过低
-14162超过最大录制时长限制
-14163SD卡已满
-14165超过文件数量限制
-14166SD卡速度低
-14167编码异常
-14168帧丢失
-14180文件碎片过多
-14181相机温度过高
-14182低功率启动
-14183存储偏转启动
-14184高温启动
-14164其他情况

相机激活错误码

错误码解释
400参数错误,可能是相机类型或者序列号没有获取到
401接口签名验证失败
402数据加密验证失败
403nonce凭证已经被使用过
406timestamp已经过期
429接口请求频繁
500系统内部异常
3001设备序列号和设备类型不匹配
3002相机已被激活
3003拒绝激活,激活ip不在合法区域内
3004无法生成可用序列号
3005系统不支持激活该型号的设备
3006序列号被后台锁定,不允许激活
429激活ip被限流,限流策略:45次/ip/天

Media SDK功能

预览模块

如果您已经集成了Camera SDK,则可以打开并显示预览内容。

预览控件初始化

您需要将*InstaCapturePlayerView*放入您的XML文件中,并且绑定Activity的生命周期:

xml
<com.arashivision.sdkmedia.player.capture.InstaCapturePlayerView
    android:id="@+id/player_capture"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/darker_gray"
/>
@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_preview);
    mCapturePlayerView.setLifecycle(getLifecycle());
}

显示预览画面

Camera SDK的*IPreviewStatusListener.onOpen()*回调中显示预览画面

java
@Override
public void onOpened() {
    InstaCameraManager.getInstance().setStreamEncode();
    mCapturePlayerView.setPlayerViewListener(new PlayerViewListener() {
        @Override
        public void onLoadingFinish() {
            // 固定写法
            InstaCameraManager.getInstance().setPipeline(mCapturePlayerView.getPipeline());
        }
        
        @Override
        public void onLoadingStatusChanged(boolean isLoading) {
            // loading状态改变
        }

        @Override
        public void onFail(String desc) {
        }
        
        @Override
        public void onFirstFrameRender() {
            // 首帧有效渲染
        }
    });
    // 设置参数,后面会详细描述
    mCapturePlayerView.prepare(createParams());
    // 播放
    mCapturePlayerView.play();
    // 保持屏幕常亮
    mCapturePlayerView.setKeepScreenOn(false);
}

释放资源

当关闭预览流时,需要释放掉*InstaCapturePlayerView*

java
@Override
protected void onStop() {
    super.onStop();
    if (isFinishing()) {
        InstaCameraManager.getInstance().setPreviewStatusChangedListener(null);
        InstaCameraManager.getInstance().closePreviewStream();
        mCapturePlayerView.destroy();
    }
}

// yilanli
@Override
public void onIdle() {
    mCapturePlayerView.destroy();
    mCapturePlayerView.setKeepScreenOn(false);
}

设置预览参数

java
private CaptureParamsBuilderV2createParams() {
    CaptureParamsBuilderV2builder = new CaptureParamsBuilderV2()
            // (可选) 设置您的分辨率和帧率,默认值由SDK内部智能生成
            .setWidth(int width)
            .setHeight(int height)
            .setFps(int fps) //最大30fps
            // (可选) 消色差  默认值为true
            .setImageFusionEnabled(boolean enable)
            // (可选) 设置手势开关,默认值由SDK内部智能生成
            .setGestureEnabled(boolean enable)
            // (可选) 设置防抖缓存帧数,缓存帧数越多,防抖效果越好,但画面延迟也会越高
            .setStabCacheFrameNum(5)
            // (可选) 设置防抖类型,默认值由SDK内部智能生成
            .setStabType(@InstaStabType.StabType int mStabType)
            //(可选)设置渲染模式,默认值为"RenderModel.AUTO"
            .setRenderModel(RenderModel.PLANE_STITCH)
            //(可选)设置屏幕比例。如9:16这种,默认值由SDK内部智能生成
            // 如果渲染模式类型为“PLANE_STITCH”,建议设置比为2:1
            .setScreenRatio(int,int)
            //(可选)设置自定义Surface信息
            .setCameraRenderSurfaceInfo(CameraRenderSurfaceInfo);
    return builder;
}

切换渲染模式

java
// 普通
mCapturePlayerView.switchNormalMode();
// 鱼眼
mCapturePlayerView.switchFisheyeMode();
// 透视
mCapturePlayerView.switchPerspectiveMode();

视角视距

您可以根据自己的喜好自定义视角和视距。

Fov:视角范围 0~180

Distance:视距范围 0~∞

java
mCapturePlayerView.setConstraint(float minFov, float maxFov, float defaultFov, float minDistance, float maxDistance, float defaultDistance);

手势操作

您可以将*PlayerGestureListener*设置为观察手势操作:

java
mCapturePlayerView.setGestureListener(new PlayerGestureListener() {
    @Override
    public boolean onDown(MotionEvent e) {
        // 用户手指按下事件
        return PlayerGestureListener.super.onDown(e);
    }

    @Override
    public boolean onTap(MotionEvent e) {
        // 用户手指单击事件,类似于View.OnClickListener.OnClick(v)
        return PlayerGestureListener.super.onTap(e);
    }

    @Override
    public void onUp() {
        // 用户手指抬起事件
        PlayerGestureListener.super.onUp();
    }

    @Override
    public void onLongPress(MotionEvent e) {
         // 用户长按事件
        PlayerGestureListener.super.onLongPress(e);
    }

    @Override
    public void onZoom() {
        // 用户双指缩放事件
        PlayerGestureListener.super.onZoom();
    }

    @Override
    public void onZoomAnimation() {
        // 缩放达到最大或最小是的回弹动画
        PlayerGestureListener.super.onZoomAnimation();
    }

    @Override
    public void onZoomAnimationEnd() {
        // 缩放回弹动画结束
        PlayerGestureListener.super.onZoomAnimationEnd();
    }

    @Override
    public void onScroll() {
        // 用户手指滑动事件
        PlayerGestureListener.super.onScroll();
    }

    @Override
    public void onFlingAnimation() {
        // 快速滑动动画
        PlayerGestureListener.super.onFlingAnimation();
    }

    @Override
    public void onFlingAnimationEnd() {
         // 快速滑动动画结束
        PlayerGestureListener.super.onFlingAnimationEnd();
    }
});

WorkWrapper

WorkWrapper是一次拍摄所有数据的一个集合,例如:连拍会生成多个文件,这些文件就会被封装成一个WorkWrapper来统一处理,后续对文件的播放、导出和信息获取都是对WorkWrapper对象操作实现的。

如何获取WorkWrapper

您可以从相机或本地目录扫描媒体文件以获取List<WorkWrapper>

注意:这是一个耗时的操作,需要在子线程中处理。

java
// 从相机中获取
List<WorkWrapper> list = WorkUtils.getAllCameraWorks();

// 从本地文件中获取
List<WorkWrapper> list = WorkUtils.getAllLocalWorks(String dirPath);

// 如果您有媒体文件的url,您也可以自己创建WorkWrapper
String[] urls = {img1.insv, img2.insv, img3.insv};
WorkWrapper workWrapper = new WorkWrapper(urls);

加载文件尾数据

调用*WorkWrapper.loadExtraData()*函数加载文件尾数据。加载文件尾数据之后才可以使用播放导出功能。

调用*WorkWrapper.isExtraDataLoaded()*函数可以判断文件尾数据是否已经加载过。

注意:该方法是耗时操作,需要放在IO线程中执行。

读取WorkWrapper的内容

您可以从*WorkWrapper*获取到的信息如下:

方法参数返回值类型说明
getIdenticalKey()-String用于Glide或其他的DiskCacheKey
getUrls()-String[]获取媒体文件URL
getUrls()booleanString[]获取媒体文件URL。设置true/false以决定是否包含dng文件路径
getAllUrls()-String[]获取所有文件路径,用来下载和删除等操作
getWidth()-int获取宽度
getHeight()-int获取高度
getBitrate()-int获取视频比特率,如果是照片,则返回0
getFps()-double获取视频帧率,如果是照片,则返回0
isPhoto()-boolean是否为照片
isHDRPhoto()-boolean是否为HDR照片
supportPureShot()-boolean是否支持PureShot算法
isVideo()-boolean是否为视频
isHDRVideo()-boolean是否为HDR视频
isCameraFile()-boolean媒体文件是否来源于相机设备
isLocalFile()-boolean媒体文件是否来源于手机设备
getCreationTime()-long获取媒体文件拍摄时间戳,单位:ms
getFirstFrameTimeOffset()-long获取拍摄媒体文件时时间戳相对于相机启动的偏移量,用于匹配陀螺仪、曝光和其他数据,单位:ms
getGyroInfo()-GyroInfo[]获取媒体文件的陀螺仪数据
getExposureData()-ExposureData[]获取媒体文件的曝光数据
loadThumbnail()-Bitmap加载缩略图(耗时操作)
loadExtraData()--加载文件尾数据(耗时操作)
isExtraDataLoaded()-boolean是否加载过文件尾数据

图片播放器

如果要播放图像或视频,必须先创建WorkWrapper

播放器初始化

将*InstaImagePlayerView*放入xml文件中,并且绑定Activity的生命周期。

xml
<com.arashivision.sdkmedia.player.image.InstaImagePlayerView
    android:id="@+id/player_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
/>
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_preview);
    mImagePlayerView.setLifecycle(getLifecycle());
}

设置播放参数

java
ImageParamsBuilder builder = new ImageParamsBuilder()
      // (可选) 是否启用动态拼接,默认为true
      .setDynamicStitch(boolean dynamicStitch)
      // (可选) 设置防抖类型,默认为InstaStabType.STAB_TYPE_OFF
      .setStabType(@InstaStabType.StabType int mStabType)
      // (可选) 设置播放代理文件,如拼接生成的HDR.jpg,默认为空
      .setUrlForPlay(String url)
      // (可选) 设置渲染模型类型,默认值为`RenderModel.AUTO`
      .setRenderModel(RenderModel.PLANE_STITCH)
      // (可选) 设置屏幕的纵横比,默认为全屏显示
      //如果渲染模式类型为“RenderModel.PLANE_STITCH”,建议的设置比率为2:1
      .setScreenRatio(int ratioX, int ratioY)
      // (可选) 消除图像拼接的色差,默认为false
      .setImageFusion(boolean imageFusion)
      // (可选) 设置保护镜类型,默认为 OffsetType.ORIGINAL
      .setOffsetType(OffsetType offsetType)
      // (可选) 设置色彩增强开关,默认为false
      .setColorPlusEnable(boolean enabled);
      // (可选) 设置色彩增强强度,默认为1,取值范围 0-1
      .setColorPlusFilterIntensity(float colorPlusFilterIntensity);
      // (可选) 是否允许手势操作,默认为true
      .setGestureEnabled(boolean enabled);
      // (可选) 缩略图缓存文件夹, 默认为 getCacheDir() + "/work_thumbnail"
      .setCacheWorkThumbnailRootPath(String path)
      // (可选) 防抖数据缓存文件夹, 默认为 getCacheDir() + "/stabilizer"
      .setStabilizerCacheRootPath(String path)
      // (可选) 缓存文件夹, 默认为 getExternalCacheDir() + "/template_blender"
      .setCacheTemplateBlenderRootPath(String path)
      // (可选) 星空模式图片缓存文件夹, 默认为 getCacheDir() + "/cut_scene"
      .setCacheCutSceneRootPath(String path);

开始播放

播放前需要设置*WorkWrapper*和播放参数;

java
// 设置 WorkWrapper 和 播放参数
mImagePlayerView.prepare(workWrapper, new ImageParamsBuilder());
// 开始播放
mImagePlayerView.play();

释放资源

当Activity被销毁时,释放*InstaImagePlayerView*。

java
@Override
protected void onDestroy() {
    super.onDestroy();
    mImagePlayerView.destroy();
}

切换渲染模式

注意:若您想在平铺模式和其他模式之间切换,必须先重启播放器;

如果您使用的渲染模式为RENDER_MODE_AUTO,则可以在以下模式之间切换。

java
// 切换至普通模式
mImagePlayerView.switchNormalMode();

// 切换至鱼眼模式
mImagePlayerView.switchFisheyeMode();

// 切换至透视模式
mImagePlayerView.switchPerspectiveMode();

// 切换至平铺模式,则需要重启播放器
ImageParamsBuilder builder = new ImageParamsBuilder();
builder.setRenderModelType(ImageParamsBuilder.RENDER_MODE_PLANE_STITCH);
builder.setScreenRatio(2, 1);
mImagePlayerView.prepare(mWorkWrapper, builder);
mImagePlayerView.play();

视角视距

您可以根据自己的喜好自定义视角和视距。

Fov:视角范围 0~180

Distance:视距范围 0~∞

java
mImagePlayerView.setConstraint(float minFov, float maxFov, float defaultFov, float minDistance, float maxDistance, float defaultDistance);

设置监听

您可以设置*PlayerViewListener*来观察播放器状态的变化。

java
mImagePlayerView.setPlayerViewListener(new PlayerViewListener() {
    @Override
    public void onLoadingStatusChanged(boolean isLoading) {
        // 播放器加载状态改变
        //isLoading:是否加载中
    }

    @Override
    public void onLoadingFinish() {
        // 播放器加载完成
    }

    @Override
    public void onFail(int errorCode, String errorMsg) {
        // if GPU not support, errorCode is -10003 or -10005 or -13020
        // 播放器错误
    }
    
    @Override
    public void onFirstFrameRender() {
        // 首帧有效渲染
    }
});

手势操作

您可以将*PlayerGestureListener*设置为观察手势操作。

typescript
mImagePlayerView.setGestureListener(new PlayerGestureListener() {
    @Override
    public boolean onDown(MotionEvent e) {
        // 用户手指按下事件
        return PlayerGestureListener.super.onDown(e);
    }

    @Override
    public boolean onTap(MotionEvent e) {
        // 用户手指单击事件,类似于View.OnClickListener.OnClick(v)
        return PlayerGestureListener.super.onTap(e);
    }

    @Override
    public void onUp() {
        // 用户手指抬起事件
        PlayerGestureListener.super.onUp();
    }

    @Override
    public void onLongPress(MotionEvent e) {
         // 用户长按事件
        PlayerGestureListener.super.onLongPress(e);
    }

    @Override
    public void onZoom() {
        // 用户双指缩放事件
        PlayerGestureListener.super.onZoom();
    }

    @Override
    public void onZoomAnimation() {
        // 缩放达到最大或最小是的回弹动画
        PlayerGestureListener.super.onZoomAnimation();
    }

    @Override
    public void onZoomAnimationEnd() {
        // 缩放回弹动画结束
        PlayerGestureListener.super.onZoomAnimationEnd();
    }

    @Override
    public void onScroll() {
        // 用户手指滑动事件
        PlayerGestureListener.super.onScroll();
    }

    @Override
    public void onFlingAnimation() {
        // 快速滑动动画
        PlayerGestureListener.super.onFlingAnimation();
    }

    @Override
    public void onFlingAnimationEnd() {
         // 快速滑动动画结束
        PlayerGestureListener.super.onFlingAnimationEnd();
    }
});

视频播放器

播放器初始化

将*InstaVideoPlayerView *放入xml文件中,并且绑定Activity的生命周期。

xml
<com.arashivision.sdkmedia.player.video.InstaVideoPlayerView
   android:id="@+id/player_video"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
/>
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_preview);
    mVideoPlayerView.setLifecycle(getLifecycle());
}

设置播放参数

java
VideoParamsBuilder builder = new VideoParamsBuilder()
      // (可选) 加载图标,默认为空
      .setLoadingImageResId(int resId)
      // (可选) 加载时的背景颜色,默认为黑色
      .setLoadingBackgroundColor(int color)
      // (可选) 是否自动播放
      .setAutoPlayAfterPrepared(boolean autoPlayAfterPrepared)
      // (可选) 设置防抖类型,默认为InstaStabType.STAB_TYPE_OFF
      .setStabType(@InstaStabType.StabType int stabType)
      // (可选) 是否循环播放,默认为true
      .setIsLooping(boolean isLooping)
      // (可选) 设置是否副码流播放
      .setLrvEnable(boolean isLrvEnable)
      // (可选) 是否启用动态拼接,默认为true
      .setDynamicStitch(boolean dynamicStitch)
      // (可选) 消除图像拼接的色差,默认为false
      .setImageFusion(boolean imageFusion)
      // (可选) 设置保护镜类型,默认为 OffsetType.ORIGINAL
      .setOffsetType(OffsetType offsetType)
      // (可选) 去紫边,默认值为false,需要添加算法文件
      .setDePurpleFilterOn(boolean isDePurpleFilterOn)
      // (可选) 设置色彩增强开关,默认为false
      .setColorPlusEnable(boolean enabled);
      // (可选) 设置色彩增强强度,默认为1,取值范围 0-1
      .setColorPlusFilterIntensity(float colorPlusFilterIntensity);
      // (可选) 设置渲染模型类型,默认值为`RenderModel.AUTO`
      .setRenderModel(RenderModel.PLANE_STITCH)
      // (可选) 设置屏幕的宽高比,默认为全屏显示。
      // 如果渲染模式类型为“RenderModel.PLANE_STITCH”,建议设置比为2:1
      .setScreenRatio(int ratioX, int ratioY)
      // (可选) 是否允许手势操作,默认为true
      .setGestureEnabled(boolean enabled)
      // (可选) 缩略图缓存文件夹,默认为 getCacheDir() + "/work_thumbnail"
      .setCacheWorkThumbnailRootPath(String path)
      // (可选) 星空模式图片缓存文件夹,默认为 getCacheDir() + "/cut_scene"
      .setCacheCutSceneRootPath(String path);

开始播放

播放前需要设置*WorkWrapper*和播放参数;

java
mVideoPlayerView.prepare(workWrapper, new VideoParamsBuilder());
mVideoPlayerView.play();

释放资源

当Activity被销毁时,释放*InstaVideoPlayerView* 。

java
@Override
protected void onDestroy() {
    super.onDestroy();
    mVideoPlayerView.destroy();
}

播放控制

您可以通过调用*VideoPlayerView*中的代码,来控制视频的播放进度,暂停/恢复,播放音量等。

方法参数返回值说明
isPlaying-boolean视频是否正在播放
isLooping-boolean是否循环播放
setLoopingbooleanvoid设置是否循环播放
setVolumefloat (范围0-1)void设置播放音量
pause-void暂停播放
resume-void恢复播放
seekTolongvoid快进到指定进度播放
isSeeking-boolean是否快进中
getVideoCurrentPosition-long获取视频当前播放进度
getVideoTotalDuration-long获取视频总长

切换渲染模式

注意:若您想在平铺模式和其他模式之间切换,必须先重启播放器;

如果您使用的渲染模式为RENDER_MODE_AUTO,则可以在以下模式之间切换。

java
// 切换至普通模式
mVideoPlayerView.switchNormalMode();

// 切换至鱼眼模式
mVideoPlayerView.switchFisheyeMode();

// 切换至透视模式
mVideoPlayerView.switchPerspectiveMode();

// 切换至平铺模式,则需要重启播放器
VideoParamsBuilder builder = new VideoParamsBuilder();
builder.setRenderModelType(ImageParamsBuilder.RENDER_MODE_PLANE_STITCH);
builder.setScreenRatio(2, 1);
mImagePlayerView.prepare(mWorkWrapper, builder);
mImagePlayerView.play();

视角视距

您可以根据自己的喜好自定义视角和视距。

Fov:视角范围 0~180

Distance:视距范围 0~∞

java
mVideoPlayerView.setConstraint(float minFov, float maxFov, float defaultFov, float minDistance, float maxDistance, float defaultDistance);

设置监听

您可以设置*PlayerViewListener*来观察播放器状态的变化。

java
mVideoPlayerView.setPlayerViewListener(new PlayerViewListener() {
    @Override
    public void onLoadingStatusChanged(boolean isLoading) {
        // 播放器加载状态改变
        //isLoading:是否加载中
    }

    @Overrid
    epublic void onLoadingFinish() {
        // 播放器加载完成
    }

    @Override
    public void onFail(int errorCode, String errorMsg) {
        // if GPU not support, errorCode is -10003 or -10005 or -13020
        // 播放器错误
    }
    
    @Override
    public void onFirstFrameRender() {
        // 首帧有效渲染
    }
});

您可以设置*VideoStatusListener*来观察视频状态的变化。

java
mVideoPlayerView.setVideoStatusListener(new VideoStatusListener() {
    @Override
    public void onProgressChanged(long position, long length) {
        // 播放进度回调
        // position:已播放长度
        // length:视频总长
    }

    @Override
    public void onPlayStateChanged(boolean isPlaying) {
        // 视频播放状态回调
        // isPlaying:是否正在播放
    }

    @Override
    public void onSeekComplete() {
        // 快进完成
    }

    @Override
    public void onCompletion() {
        // 视频播放完成
    }
});

手势操作

您可以将*PlayerGestureListener*设置为观察手势操作。

typescript
mVideoPlayerView.setGestureListener(new PlayerGestureListener() {
    @Override
    public boolean onDown(MotionEvent e) {
        // 用户手指按下事件
        return PlayerGestureListener.super.onDown(e);
    }

    @Override
    public boolean onTap(MotionEvent e) {
        // 用户手指单击事件,类似于View.OnClickListener.OnClick(v)
        return PlayerGestureListener.super.onTap(e);
    }

    @Override
    public void onUp() {
        // 用户手指抬起事件
        PlayerGestureListener.super.onUp();
    }

    @Override
    public void onLongPress(MotionEvent e) {
         // 用户长按事件
        PlayerGestureListener.super.onLongPress(e);
    }

    @Override
    public void onZoom() {
        // 用户双指缩放事件
        PlayerGestureListener.super.onZoom();
    }

    @Override
    public void onZoomAnimation() {
        // 缩放达到最大或最小是的回弹动画
        PlayerGestureListener.super.onZoomAnimation();
    }

    @Override
    public void onZoomAnimationEnd() {
        // 缩放回弹动画结束
        PlayerGestureListener.super.onZoomAnimationEnd();
    }

    @Override
    public void onScroll() {
        // 用户手指滑动事件
        PlayerGestureListener.super.onScroll();
    }

    @Override
    public void onFlingAnimation() {
        // 快速滑动动画
        PlayerGestureListener.super.onFlingAnimation();
    }

    @Override
    public void onFlingAnimationEnd() {
         // 快速滑动动画结束
        PlayerGestureListener.super.onFlingAnimationEnd();
    }
});

导出图片

导出图片参数

如果你想导出图片,你需要先了解图片导出参数*ExportImageParamsBuilder*。

java
ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
    // (必须) 导出文件路径
    .setTargetPath(String path)
    // (可选) 设置导出图像的宽度,默认值为从WorkWapper获取。
    .setWidth(int width)
    // (可选) 设置导出图像的高度,默认值为从WorkWapper获取。
    .setHeight(int height)
    // (可选) 设置导出模式, default is `PANORAMA`
    // ExportMode.PANORAMA: 导出全景图片
    // ExportMode.SPHERE: 导出平面缩略图
    .setExportMode(ExportUtils.ExportMode mode)
    // (可选)是否启用动态拼接,默认为true。
    .setDynamicStitch(boolean dynamicStitch)
    // (可选)设置防抖类型,默认为InstaStabType.STAB_TYPE_OFF。
    .setStabType(@InstaStabType.StabType int stabType)
    // (可选) 消除图像拼接的色差,默认为false
    .setImageFusion(boolean imageFusion)
    // (可选) 去紫边,默认为false,需要添加算法文件
    .setDePurpleFilterOn(boolean isDePurpleFilterOn)
    // (可选) 设置保护镜类型,默认为 OffsetType.ORIGINAL
    .setOffsetType(OffsetType offsetType)
    // (可选) 设置如HDR.jpg通过拼接生成,默认为null
    .setUrlForExport(String url)
    // (可选) 设置使用软件解码器,默认为false
    .setUseSoftwareDecoder(boolean useSoftwareDecoder)
    // (可选) 设置相机角度。建议在导出缩略图时使用。
    //当前显示的角度参数可以从`PlayerView.getXXX()`中获得。
    .setFov(float fov)
    .setDistance(float distance)
    .setYaw(float yaw)
    .setPitch(float pitch)
    //(可选)缓存文件夹,默认为 getCacheDir() + "/work_thumbnail"
    .setCacheWorkThumbnailRootPath(String path)
    //(可选)缓存文件夹,默认为 getCacheDir() + "/stabilizer"
    .setStabilizerCacheRootPath(String path)
    //(可选)缓存文件夹,默认为 getCacheDir() + "/cut_scene"
    .setCacheCutSceneRootPath(String path);

导出全景图片

使用图片导出参数:

java
ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
        .setExportMode(ExportUtils.ExportMode.PANORAMA)
        .setTargetPath(path)
        .setWidth(2048)
        .setHeight(1024);
int exportId = ExportUtils.exportImage(WorkWrapper, builder, new IExportCallback() {
            @Override
            public void onSuccess() {       
                // 导出成功        
            }

            @Override
            public void onFail() {
                // 导出失败
            }

            @Override
            public void onCancel() {
                // 取消导出
            }

            @Override
            public void onProgress(float progress) {
                // 导出进度
            }
        });

导出图片缩略图

使用图片导出参数:

java
ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
        .setExportMode(ExportUtils.ExportMode.SPHERE)
        .setTargetPath(path)
        .setWidth(512)
        .setHeight(512)
        .setFov(mImagePlayerView.getFov())
        .setDistance(mImagePlayerView.getDistance())
        .setYaw(mImagePlayerView.getYaw())
        .setPitch(mImagePlayerView.getPitch());
int exportId = ExportUtils.exportImage(WorkWrapper, builder, new IExportCallback() {
           @Override
            public void onSuccess() {       
                // 导出成功        
            }

            @Override
            public void onFail() {
                // 导出失败
            }

            @Override
            public void onCancel() {
                // 取消导出
            }

            @Override
            public void onProgress(float progress) {
                // 导出进度
            }
        });

导出视频

导出视频参数

导出视频,需要先了解视频导出参数*ExportVideoParamsBuilder* 。

java
ExportVideoParamsBuilder builder = new ExportVideoParamsBuilder()
    // (必须) 导出文件路径
    .setTargetPath(String path)
    // (可选) 设置导出视频的宽度。它必须是2的幂,默认值是从WorkWapper获取。
    .setWidth(int width)
    // (可选)设置导出视频的高度。它必须是2的幂,默认值是从WorkWapper获取。
    .setHeight(int height)
    // (可选) 设置导出视频的比特率,默认值为从WorkWapper获取。
    .setBitrate(int bitrate)
    // (可选) 设置导出视频的fps,默认值为从WorkWapper获取。
    .setFps(int fps)
    // (可选) 设置导出模式, default is `PANORAMA`
    // ExportMode.PANORAMA: 导出全景图片
    // ExportMode.SPHERE: 导出平面缩略图
    .setExportMode(ExportUtils.ExportMode mode)
    // (可选) 去紫边,默认为false,需要添加算法文件
    .setDePurpleFilterOn(boolean isDePurpleFilterOn)
    // (可选) 是否启用降噪 (导出图片默认启用降噪,降噪开关仅导出视频支持)
    // 需要提前调用ExportUtils.supportDenoise(WorkWrapper)方法判断是否支持降噪
    // 支持降噪则设置有效,反之设置无效
    .setDenoise(true)
    // (可选) 消除图像拼接的色差,默认为false
    .setImageFusion(boolean imageFusion)
    // (可选) 设置保护镜类型,默认为 OffsetType.ORIGINAL
    .setOffsetType(OffsetType offsetType)
    //(可选)是否启用动态拼接,默认为true。
    .setDynamicStitch(boolean dynamicStitch)
    // (可选)设置防抖类型,默认为InstaStabType.STAB_TYPE_OFF。
    .setStabType(@InstaStabType.StabType int stabType)
    // (可选) 设置使用软件解码器,默认为false
    .setUseSoftwareDecoder(boolean useSoftwareDecoder)
    // (可选) 缓存文件夹,默认为 getCacheDir() + "/work_thumbnail"
    .setCacheWorkThumbnailRootPath(String path)
    // (可选) 缓存文件夹,默认为 getCacheDir() + "/cut_scene"
    .setCacheCutSceneRootPath(String path)
    // (可选) 设置视角场
    .setFov(float fov)
    // (可选) 设置视距
    .setDistance(float distance)
    //(可选) 设置欧拉角-俯仰角
    .setPitch(float pitch)
    //(可选) 设置欧拉角-偏航角
    .setYaw(float yaw)
    //(可选) 设置欧拉角-滚转角
    .setRoll(float roll);

导出全景视频

使用视频导出参数;

java
ExportVideoParamsBuilder builder = new ExportVideoParamsBuilder()
        .setExportMode(ExportUtils.ExportMode.PANORAMA)
        .setTargetPath(path)
        .setWidth(2048)
        .setHeight(1024)
        .setBitrate(20 * 1024 * 1024)
        .setFps(30);
int exportId = ExportUtils.exportVideo(WorkWrapper, builder, new IExportCallback() {
            @Override
            public void onSuccess() {       
                // 导出成功        
            }

            @Override
            public void onFail() {
                // 导出失败
            }

            @Override
            public void onCancel() {
                // 取消导出
            }

            @Override
            public void onProgress(float progress) {
                // 导出进度
            }
        });

导出视频缩略图

导出的结果是图片,因此使用图片导出参数:

java
ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
        .setExportMode(ExportUtils.ExportMode.SPHERE)
        .setTargetPath(path)
        .setWidth(512)
        .setHeight(512)
        .setFov(mVideoPlayerView.getFov())
        .setDistance(mVideoPlayerView.getDistance())
        .setYaw(mVideoPlayerView.getYaw())
        .setPitch(mVideoPlayerView.getPitch());
int exportId = ExportUtils.exportVideoToImage(WorkWrapper, builder, new IExportCallback() {
           @Override
            public void onSuccess() {       
                // 导出成功        
            }

            @Override
            public void onFail() {
                // 导出失败
            }

            @Override
            public void onCancel() {
                // 取消导出
            }

            @Override
            public void onProgress(float progress) {
                // 导出进度
            }
        });

停止导出

java
ExportUtils.stopExport(exportId);

其它

生成HDR图片

如果您有HDR图像的*WorkWrapper*,则可以通过HDR拼接将其生成为一个图像文件。

注意:这是一个耗时的操作,需要在子线程中处理。

java
boolean isSuccessful = StitchUtils.generateHDR(WorkWrapper workWrapper, String hdrOutputPath);

*generateHDR*调用成功后,outputPath可以作为代理播放或设置为导出url。

java
// 设置为播放代理
ImageParamsBuilder builder = new ImageParamsBuilder()
        // 如果HDR拼接成功,则将其设置为播放代理
        .setUrlForPlay(isSuccessful ? hdrOutputPath : null);
mImagePlayerView.prepare(workWrapper, builder);
mImagePlayerView.play();

// 设置为导出url
ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
        .setExportMode(ExportUtils.ExportMode.PANORAMA)
        .setTargetPath(exportPath)
        // 如果HDR拼接成功,则将其设置为导出url
        .setUrlForExport(hdrOutputPath);

生成PureShot图像

如果您有PureShot图片的*WorkWrapper*,则可以通过PureShot拼接将其生成为一个图像文件。

注意:这是一个耗时的操作,需要在子线程中处理。

java
boolean isSuccessful = StitchUtils.generatePureShot(WorkWrapper workWrapper, String pureshotOutputPath, String algoFolderPath);

注意:生成PureShot图像需要算法模型文件,请向我们的技术支持人员索取与sdk版本对应的算法模型文件。

algoFolderPath是算法模型文件的目录,可以是LocalStoragePath或AssetsRelativePath,SDK会在需要的时候加载这些文件。

*generatePureShot*调用成功后,outputPath可以作为代理播放或设置为导出url。

java
// 设置为播放代理
ImageParamsBuilder builder = new ImageParamsBuilder()
        // 如果PureShot拼接成功,则将其设置为播放代理
        .setUrlForPlay(isSuccessful ? pureshotOutputPath : null);
mImagePlayerView.prepare(workWrapper, builder);
mImagePlayerView.play();

// 设置为导出url
ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
        .setExportMode(ExportUtils.ExportMode.PANORAMA)
        .setTargetPath(exportPath)
        // 如果PureShot拼接成功,则将其设置为导出url
        .setUrlForExport(pureshotOutputPath);

算法文件

部分功能需要依赖算法文件。算法文件在demo中的assets文件夹中获取,文件路径和demo中保持一致即可。 下面是功能和其所需要的算法对应表:

功能模型文件路径说明
去紫边defringe_lr_dynamic_e28c1212.ins defringe_hr_dynamic_7b56e80f.ins固定路径 file:///android_assets/insta360/model/
色彩增强lut_7a79b17a_32.ins固定路径 file:///android_assets/insta360/model/
PureShot合成Pmdenoise_raw_plus.insraw_denoising_abeda57d.ins283fish.ilp283wide.ilp577.ilp586.ilpX3.ilp开发者自定义路径由StitchUtils.generatePureShot函数传递进来

错误码

图片/视频导出错误码

错误码解释
-31000正在导出中
-31010停止导出
-31011加载防抖数据失败
-31012EXPORT_TERMINATED_BY_WORK_REFERENCE_RELEASABLE
-31016EXPORT_POST_EXECUTE_FAILED
-31017原始缩略图LRV找不到
-31018原始缩略图LRV加载失败
-31019EXPORT_VIDEO_TO_IMAGE_SEQUENCE_CANCEL
-13016导出超时
-13017取消导出
-13018SHADOW_EXPORT_INIT_SHADOW_CLONE_FAIL
-13019SHADOW_EXPORT_PREPARE_EXPORT_INFO_FAIL
-13021打开硬件编码失败
-13022SHADOW_EXPORT_FAIL_TARGET_TIME_NULL
-13023SHADOW_EXPORT_PREPRARE_FRAME_EXPORTER_FAIL
-13024SHADOW_EXPORT_INPUT_TARGET_FAIL
-13025STOP_MOTION_SELECT_POSE_CLIP_NULL
-13026STOP_MOTION_SELECT_CLIP_NOT_MATCH
-13027STOP_MOTION_SELECT_LOAD_STABILIZER_FAIL
-13028STOP_MOTION_SELECT_KEY_NULL
-13029SHADOW_EXPORT_TRACK_TARGET_EMPTY
-13031帧导出器准备失败
-13033反向解析视频失败
-13034双流帧格式不同
-13035缩略图防抖错误
-13036视频帧率等于0
-13038视频宽度等于0
-13039视频高度等于0
-13040降噪模型等于null
-13041视频源帧率等于0
-13042视频源时长等于0
-13043图片降噪文件移动错误
-13034双流帧格式不同
-13044加载AAA参数失败
-13045创建降噪数据失败
-13046图片宽度等于0
-13047图片高度等于0

常见问题

Q1:连接相机时,无法访问互联网怎么办?

一般这种情况指的是通过Wi-Fi与相机建立连接的情况。App与相机的通信方式分为两种,一种是socket,另一种是http。下面是是两种通讯方式对应的功能:

  • Socket:预览流,读取相机参数,设置相机参数,读取拍摄参数,设置拍摄参数等。// TODO 支持的功能待完善
  • Http 初始化支持列表,下载相机文件。// TODO 支持的功能待完善

出现这个问题的根本原因是因为在与相机建立socket连接的时候,调用了ConnectivityManager#bindProcessToNetwork(network) 方法,把当前进程和相机WI-FI网络进行绑定。

因此在Wi-Fi连接成功之后,调用ConnectivityManager#bindProcessToNetwork(4GNetWork) 方法绑定可用的网络(如4G网络),即可解决无法访问互联网的问题。此时已经连接Socket连接,解绑之后,依然可以使用Socket支持的功能。

但这样做会有一个问题。因为当前进程与相机Wi-Fi之间未绑定,在使用依赖http通信的功能时,会出现如下报错:

start download http://192.168.42.1:80/DCIM/Camera01/VID_20250623_120439_00_003.insv download failed code=-1 body=null exception=javaa.net.SocketTimeoutException: failed to connect to/192.168.42.1 (port 80) from /10.0.134.179 (port 56028) after 60000ms

解决这个问题有2种方案:

  1. 在使用Http通信方式相关的功能时,调用bindProcessToNetwork(camera)方法绑定至相机Wi-Fi。在相关功能结束时,调用bindProcessToNetwork(4g)切换回可用的4G网络。
    1. 优点:实现简单
    2. 缺点:会短暂的断开与互联网的连接
  2. 开启一个新的进程,命名为download。调用bindProcessToNetwork(camera)方法将download进程与相机Wi-Fi网络进行绑定。所有与Http通讯相关的功能放在download进程中进行。
    1. 优点:完美解决无法访问互联网的问题
    2. 缺点:实现复杂

Q2:VideoData对象中的数据格式是什么?

H.264格式,包含pps和sps两帧数据。

Q3:c++_shared冲突怎么办?

升级版本到1.8.1_build_05及以上

Q4:关于okGo的问题如何处理?

implementation("com.github.jeasonlzy.okhttp-OkGo:okgo:v3.0.4")

implementation("com.arashivision.sdk:sdkcamera:1.8.0_build_11"){

exclude("com.github.jeasonlzy","okhttp-OkGo")

}

Q5:连接时报错-2110203的问题?

socket读失败,一般是Wi-Fi被系统切掉,去系统设置页手动连接Wi-Fi,可降低被系统自动切掉的概率。

Q6:关于华为部分手机播放黑屏的问题?

照片宽度16386,超过了华为部分手机的的渲染尺寸8192。

Q7:集成了SDK后提交到谷歌商店因.so库不满足16K被拒绝怎么办?

在Maven仓库中下载1.8.2-build4这个版本。

然后,把以下的库在打包中排除(不会影响SDK功能),在上架谷歌商店即可

libSnpeHtpV68Skel.so(AI 加速相关的辅助组件)

libSnpeHtpV69Skel.so(AI 加速相关的辅助组件)

libSnpeHtpV73Skel.so(AI 加速相关的辅助组件)

iibSnpeHtpV75Skel.so(AI 加速相关的辅助组件)

libSnpeHtpV7.9Skel.so(AI 加速相关的辅助组件)

libcalculator_skel.so(AI 加速相关的辅助组件)

x86_64/libmobvoidsp.so(X86的库,打包选择X64不会带上)