Skip to content

Android SDK enables integration of Insta360 360 cameras into Android apps for control and media management.

Notifications You must be signed in to change notification settings

Insta360Develop/Android-SDK

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 

Repository files navigation

Note:

Currently on V1.9.4 branch. To view other versions, please switch branches.

32-bit library (armeabi-v7a) is no longer maintained, please use 64-bit library (arm64-v8a) to build!

FAQ

How to get?

Please visit https://www.insta360.com/sdk/apply to apply for the latest SDK.

Support

Developers' Page: https://www.insta360.com/developer/home
Insta360 Enterprise: https://www.insta360.com/enterprise
Issue Report: https://insta.jinshuju.com/f/hZ4aMW

Overview

The Android SDK is mainly used for connecting, setting and obtaining camera parameters, controlling the camera for taking photos and recording, downloading files, firmware upgrades, and supporting video and image exports.

Supported models: X5, X4, X3, ONE X2, ONE X, ONE RS, ONE RS 1-Inch.

Table of contents

Camera SDK Function

Environmental Preparation

Add the Maven repository to the build file (the build.gradle file in the project root):

allprojects {
    repositories {
        ...
        maven {
            url 'x.x.x'             // see sdk demo
            credentials {
                // see sdk demo
                username = '***'
                password = '***'
            } 
        }
    }
}
  • Import the dependency library in the build.gradle file located in the Demo directory:
dependencies {
    implementation 'com.arashivision.sdk:sdkcamera:x.x.x' // see sdk demo
}
  • Initialize the SDK in the application
public class MyApp extends Application {

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

Connection Module

Determine if the Camera is Connected

You can determine if the camera is connected by obtaining the current camera connection type.

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

The connection types have the following four outcomes:

  1. Not connected:InstaCameraManager.CONNECT_TYPE_NONE
  2. USB connection:InstaCameraManager.CONNECT_TYPE_USB
  3. Wi-Fi connection:InstaCameraManager.CONNECT_TYPE_WIFI
  4. Bluetooth connection:InstaCameraManager.CONNECT_TYPE_BLE

Connecting the Camera

You can connect to the camera via Bluetooth, Wi-Fi, or USB

Note: You must perform the connection operation on the main thread.

Note: When the camera is connected, if the app switches to the background, it will disconnect due to the characteristics of the Android system. Therefore, it is necessary to enable a foreground service to prevent disconnection from the camera. This foreground server is implemented by the developer themselves. The relevant code can refer to the SDK Demo.

Bluetooth Connection

Note: Bluetooth connection requires successful authorization of Bluetooth-related permissions.

Note: In the case of a Bluetooth connection, large data transmission is not supported. Therefore, functions that transmit large amounts of data are not supported.

For example: live streaming, preview, support list, firmware upgrade, playback, export, etc.

  1. Initialize Bluetooth Scanning
InstaCameraManager.getInstance().startBleScan();
  1. Set the Bluetooth Scanning Listener
InstaCameraManager.getInstance().setScanBleListener(new IScanBleListener() {
    @Override
    public void onScanStartSuccess() {
        //Bluetooth is about to start scanning
    }

    @Override
    public void onScanStartFail() {
        //Bluetooth scanning failed
    }

    @Override
    public void onScanning(BleDevice bleDevice) {
        //A new Bluetooth device has been scanned; you can update the Bluetooth device list here
    }

    @Override
    public void onScanFinish(List<BleDevice> bleDeviceList) {
        //Bluetooth scanning finished
    }
});
  1. Stopping Bluetooth Scanning
InstaCameraManager.getInstance().stopBleScan();
  1. Checking if Bluetooth is Scanning
InstaCameraManager.getInstance().isBleScanning();
  1. Establishing a Bluetooth Connection with the Camera
InstaCameraManager.getInstance().connectBle(bleDevice);

Wi-Fi Connection

Note: Ensure that the phone is already connected to the camera’s Wi-Fi.The Wi-Fi password of the camera can be viewed in the settings menu of the camera, or by connecting via Bluetooth and calling to read the Wi-Fi information (SSID and password) of the camera.

InstaCameraManager.getInstance().openCamera(InstaCameraManager.CONNECT_TYPE_WIFI);

USB Connection

Note: Ensure that the phone and camera have established a USB connection, and the camera must be switched to Android mode.

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

Disconnecting the Camera

When you want to disconnect the camera, you can call the following code.

InstaCameraManager.getInstance().closeCamera();

Wi-Fi Management Module

Camera Wi-Fi On and Off

When connected to Bluetooth, the camera's Wi-Fi can be turned on and off using the following code.

ICameraOperateCallback callback = new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // The command was executed successfully
    }

    @Override
    public void onFailed() {
        // Command execution failed
    }

    @Override
    public void onCameraConnectError() {
        // The camera is disconnected or not connected
    }
};
// Turn on the camera's wifi and use the camera's default channel
InstaCameraManager.getInstance().openCameraWifi(callback);
// Open the camera wifi on the specified channel
InstaCameraManager.getInstance().openCameraWifi(int countryChannel ,callback);

// Turn off camera wifi
InstaCameraManager.getInstance().closeCameraWifi(callback)

// Restart the camera Wi-Fi, including two operations: turn off and turn on, use the camera's default channel to turn on
InstaCameraManager.getInstance().resetCameraWifi(callback)
// Restart the camera Wi-Fi by specifying a channel
InstaCameraManager.getInstance().resetCameraWifi(int countryChannel callback)

Get Wi-Fi Information

// Get camera Wi-Fi information
WifiInfo wifiInfo = InstaCameraManager.getInstance().getWifiInfo();

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

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

// Password version
int pwdVersion= wifiInfo.getPwdVersion();

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

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

// Get the Wi-Fi country code
Strin country = InstaCameraManager.getInstance().getWifiCountry();

Switch Wi-Fi Channel

// Get current country code and Wi-Fi channel
InstaCameraManager.getInstance().fetchWifiChannel((countryCode, cameraChannel) -> {
    // Get country code and current Wi-Fi channel
});

//  Set Wi-Fi country code
InstaCameraManager.getInstance().setWifiCountry("CN", new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
         // Setup successful
    }

    @Override
    public void onFailed() {
        // Setup failed
    }

    @Override
    public void onCameraConnectError() {
        // Camera connection error
    }
});

// Get Wi-Fi channel list
int[] channelList = InstaCameraManager.getInstance().getWifiChannelList();

Information Acquisition Module

Synchronizing Camera Parameters

Synchronizing camera parameters means reading all the internal camera parameters at once and caching them in the application. Call the following code to synchronize all camera parameters (Synchronization of all parameters and status).

InstaCameraManager.getInstance().fetchCameraOptions(new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // Camera parameters synchronized successfully
    }

    @Override
    public void onFailed() {
        // Camera parameter synchronization failed
    }

    @Override
    public void onCameraConnectError() {
        // Camera connection failed, which may indicate a camera disconnection event
    }
});

Get the Camera Support List

For X4 and later cameras, the capturing mode and capturing properties of the camera are based on the properties configured in the support list. Different cameras support different capturing modes, and there are also differences in the capturing properties supported under different capturing modes. Before capturing, synchronize the camera's supported list (Json file).

Initialize Support List

When entering the prep page or switching lenses, the support list needs to be initialized. This can be achieved by calling the following code:

InstaCameraManager.getInstance().initCameraSupportConfig(success -> {
    // success: Whether initialization was successful
});

Capturing Mode Support

Each lens of the camera supports different capturing modes. You need to use the following code to obtain its supported capturing modes.

// Get all supported capturing modes
List<CaptureMode> support = InstaCameraManager.getInstance().getSupportCaptureMode();

Capturing Attribute Support

Each capturing mode supports different capturing attributes. You need to use the following code to obtain the supported capturing attributes.

// Pass in the specified capturing mode as parameters
List<CaptureSetting> support = InstaCameraManager.getInstance().getSupportCaptureSettingList(CaptureMode.CAPTURE_NORMAL);

The Range of Values for Capturing Attributes

The value range of the capturing attribute is also configured in the support list. You need to use the following code to obtain the value range of the supported capturing attribute.

// Gets the property value range of CaptureSetting.RECORD_DURATION, returns a List < RecordDuration >
InstaCameraManager.getInstance().getSupportRecordDurationList(CaptureMode.TIMELAPSE);

// Get the value range of the property value of CaptureSetting.RECORD_RESOLUTION and return a List < RecordResolution >
InstaCameraManager.getInstance().getSupportRecordResolutionList(CaptureMode.TIMELAPSE);

// Get the value range of the property value of CaptureSetting.PHOTO_RESOLUTION and return a List < PhotoResolution >
InstaCameraManager.getInstance().getSupportPhotoResolutionList(CaptureMode.CAPTURE_NORMAL);

// Get the range of property values of CaptureSetting. INTERVAL and return a List < Interval > list
InstaCameraManager.getInstance().getSupportIntervalList(CaptureMode.TIMELAPSE);

// Get the value range of the property value of CaptureSetting.HDR_STATUS and return a List < HdrStatus >
InstaCameraManager.getInstance().getSupportHdrStatusList(CaptureMode.TIMELAPSE);

// Get the value range of the property value of CaptureSetting.PHOTO_HDR_TYPE and return a List < PhotoHdrType >
InstaCameraManager.getInstance().getSupportPhotoHdrTypeList(CaptureMode.CAPTURE_NORMAL);

// Get the value range of the property value of CaptureSetting.GAMMA_MODE and return a List < GammaMode >
InstaCameraManager.getInstance().getSupportGammaModeList(CaptureMode.TIMELAPSE);

// Get the value range of the property value of CaptureSetting.RAW_TYPE and return a List < RawType >
InstaCameraManager.getInstance().getSupportRawTypeList(CaptureMode.TIMELAPSE);

// Get the value range of the property value of CaptureSetting.PANO_EXPOSURE_MODE and return a List < PanoExposureMode >
InstaCameraManager.getInstance().getSupportPanoExposureList(CaptureMode.TIMELAPSE);

// Get the property value range of CaptureSetting. EXPOSURE and return a List < Exposure >
InstaCameraManager.getInstance().getSupportExposureList(CaptureMode.TIMELAPSE);

// Get the value range of the CaptureSetting. ISO property and return a List < ISO >
InstaCameraManager.getInstance().getSupportISOList(CaptureMode.TIMELAPSE);

// Gets the value range of the CaptureSetting.ISO_TOP_LIMIT property and returns a List < ISOTopLimit >
InstaCameraManager.getInstance().getSupportISOTopLimitList(CaptureMode.TIMELAPSE);

// Gets the value range of the CaptureSetting.SHUTTER_MODE property and returns a List < ShutterMode >
InstaCameraManager.getInstance().getSupportShutterModeList(CaptureMode.TIMELAPSE);

// Get the value range of the property value of CaptureSetting. SHUTTER and return a List < Shutter >
InstaCameraManager.getInstance().getSupportShutterList(CaptureMode.TIMELAPSE);

// Get the value range of the attribute value of CaptureSetting. EV and return a List < Ev >
InstaCameraManager.getInstance().getSupportEVList(CaptureMode.CAPTURE_NORMAL);

// Get the value range of the property value of CaptureSetting.EV_INTERVAL and return a List < EVInterval >
InstaCameraManager.getInstance().getSupportEVIntervalList(CaptureMode.TIMELAPSE);

// Get the value range of the attribute value of CaptureSetting. AEB and return a List < AEB >
InstaCameraManager.getInstance().getSupportAEBList(CaptureMode.TIMELAPSE);

// Get the value range of the CaptureSetting. WB attribute and return a List < WB >
InstaCameraManager.getInstance().getSupportWBList(CaptureMode.TIMELAPSE);

// Gets the property value range of CaptureSetting.INTERNAL_SPLICING and returns a List < InternalSplicing >
InstaCameraManager.getInstance().getSupportInternalSplicingList(CaptureMode.TIMELAPSE);

// Gets the value range of the CaptureSetting.DARK_EIS_ENABLE property and returns a List < DarkEisType >
InstaCameraManager.getInstance().getSupportDarkEisList(CaptureMode.TIMELAPSE);

// Gets the property value range of CaptureSetting.BURST_CAPTURE, returns a List < BurstCapture >
InstaCameraManager.getInstance().getSupportBurstCaptureList(CaptureMode.TIMELAPSE);

// Get the property value range of CaptureSetting.I_LOG and return a List<ILogStatus> list
InstaCameraManager.getInstance().getSupportILogStatusList(CaptureMode.TIMELAPSE);

Camera Information Acquisition

Camera Type

// Get the camera type, such as: Insta360 X4
String cameraType = InstaCameraManager.getInstance().getCameraType();
// Get enumeration
CameraType type = CameraType.getForType(cameraType);

Camera Serial Number

InstaCameraManager.getInstance().getCameraSerial();

Firmware Version

// Get the camera firmware version, e.g. 0.9.24
String fwVersion = InstaCameraManager.getInstance().getCameraVersion();

Camera Activation Time

// Get the camera activation time; the inactive time is 0.
long activeTime = InstaCameraManager.getInstance().getActiveTime();

SD Card Total Storage Capacity

// Get the total space size of the SD card
long totalSpace = InstaCameraManager.getInstance().getCameraStorageTotalSpace();

SD Card Available Storage Capacity

// Get the free space size of the SD card
long freeSpace = InstaCameraManager.getInstance().getCameraStorageFreeSpace();

// Get the remaining space size of the SD card (for photos, the unit is shots; for videos, the return value is the remaining recording time)
int remaining= InstaCameraManager.getInstance().getRemaining(CaptureMode captureMode);

Battery

// Get battery type
// THICK = 0;       //Thick battery
// THIN = 1;        //Thin battery (camera default)
// VERTICAL;        //Vertical shot battery
// NONE;            //Only USB power supply without battery
InstaCameraManager.getInstance().getBatteryType();

// Get current battery: 0-100
int level = InstaCameraManager.getInstance().getCameraCurrentBatteryLevel();

Camera System Time

// Get camera system time
long mediaTime = InstaCameraManager.getInstance().getMediaTime();

Get Camera Status

Determine if the Camera is Charging

// Check if the camera is charging
boolean isCharging = InstaCameraManager.getInstance().isCameraCharging();

Determine if the Camera is Working

// Check if the camera is working
boolean isWorking = InstaCameraManager.getInstance().isCameraWorking();

//Check if the specified capturing mode is currently working
boolean isNormalCapturing = InstaCameraManager.getInstance().isCameraWorking(CaptureMode.CAPTURE_NORMAL);

Determine if the SD Card is Usable

// Check if the SD card is usable
boolean isEnable = InstaCameraManager.getInstance().isSdCardEnabled();

Notification Module

You can register/unregister theICameraChangedCallback on multiple pages to monitor changes in the camera status.

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);
    }

    /**
     * Camera status change
     *
     * @param enabled: whether the camera is available
     * @param connectType: connection type
     */
    @Override
    public void onCameraStatusChanged(boolean enabled, int connectType) {
    }

    /**
     * Camera coneection failure
     * <p>
     * A common scenario is that another phone or another application on this phone has already established a connection with the camera, leading to a failure in establishing the connection, in which case, other phones must first disconnect from this camera.
     * @param errorCode: Error code, refer to the camera connection error code
     */
    @Override
    public void onCameraConnectError(int errorCode) {
    }

    /**
     * SD card insertion notification
     *
     * @param enabled: whether the current SD card is available
     */
    @Override
    public void onCameraSDCardStateChanged(boolean enabled) {
    }

    /**
     * SD card storage status change
     *
     * @param freeSpace:  the current available capacity
     * @param totalSpace: the total capacity
     */
    @Override
    public void onCameraStorageChanged(long freeSpace, long totalSpace) {
    }

    /**
     * Low battery notification
     */
    @Override
    public void onCameraBatteryLow() {
    }

    /**
     * Camera power change notification
     *
     * @param batteryLevel: current power level(0-100,always returns 100 when charging)
     * @param isCharging:   whether the camera is charging
     */
    @Override
    public void onCameraBatteryUpdate(int batteryLevel, boolean isCharging) {
    }

    /**
     * Camera temperature change notification
     *
     * @param tempLevel: temperature level
     */
    @Override
    public void onCameraTemperatureChanged(TemperatureLevel tempLevel) {
    }
}

Camera Lens Control Module

Camera lenses are divided into the following three types:

  1. Panoramic lens: SensorMode.PANORAMA
  2. Front camera: SensorMode.FRONT
  3. Rear lens: SensorMode.REAR

Determine the Sensor Mode

// Get the current sensor mode
SensorMode sensorMode = InstaCameraManager.getInstance().getCurrentSensorMode();

// Determine whether it is single sensor mode
InstaCameraManager.getInstance().isCameraSingleSensorMode();

// Determine whether it is dual sensor mode
InstaCameraManager.getInstance().isCameraDualSensorMode();

Switch Camera Lenses

Note: The SDK currently only supports panoramic lenses. Unknown issues may occur with non-panoramic lenses. Please switch to using the SDK under panoramic lenses.

// Switch to camera panorama lens
InstaCameraManager.getInstance().switchPanoramaSensorMode(new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // Lens switch successful
    }

    @Override
    public void onFailed() {
        // Lens switch failed
    }

    @Override
    public void onCameraConnectError() {
        // Camera connection error
    }
});

Preview Module

Note: Must be used with Media SDK.

Open Preview Stream

After successfully connecting the camera, you can manipulate the camera preview stream like this.

If the camera is passively disconnected, or if closeCamera() is called directly during the preview, the SDK will automatically turn off the preview stream processing related state without calling closePreviewStream()

Note: The following code only enables the preview stream and cannot display the preview content. You need to use the InstaCapturePlayerView control of MediaSDK to display the preview content.

public class PreviewActivity extends BaseObserveCameraActivity implements IPreviewStatusListener {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_preview);
        // Open 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()) {
            // Close preview
            InstaCameraManager.getInstance().setPreviewStatusChangedListener(null);
            InstaCameraManager.getInstance().closePreviewStream();
        }
    }

    @Override
    public void onOpening() {
        // Preview stream is opening      
    }

    @Override
    public void onOpened() {
        // The preview stream has been opened and can be played
    }

    @Override
    public void onIdle() {
        // Preview stream has stopped
    }

    @Override
    public void onError() {
        // Preview failed
    }
        
        @Override
    public void onExposureData(ExposureData exposureData) {
        // Callback frequency 500Hz
        // exposureData.timestamp: Time after the camera is turned on
        // exposureData.exposureTime: Rolling shutter exposure time
    }

    @Override
    public void onGyroData(List<GyroData> gyroList) {
        // Callback frequency 10Hz, 50 data per group
        // gyroData.timestamp: Time after the camera is turned on
        // gyroData.ax, gyroData.ay, gyroData.az: Triaxial acceleration
        // gyroData.gx, gyroData.gy, gyroData.gz: Three-axis gyroscope
    }

    @Override
    public void onVideoData(VideoData videoData) {
        // Callback frequency 500Hz
        // videoData.timestamp: Time after the camera is turned on
        // videoData.data: Preview raw stream data per frame
        // videoData.size: Length of each frame of data
    }

}

Get Preview Status

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

// Preview status
// InstaCameraManager.PREVIEW_STATUS_IDLE:Preview stream is not opening
// InstaCameraManager.PREVIEW_STATUS_OPENING:Preview stream is opening
// InstaCameraManager.PREVIEW_STATUS_OPENED:The preview stream has been opened

Set Preview Parameters

There are three types of preview streams:

  1. PREVIEW_TYPE_NORMAL:For normal preview or capturing
  2. PREVIEW_TYPE_RECORD:Only for recording
  3. PREVIEW_TYPE_LIVE:LIVE

Preview Resolution

You need to use the following code to get real-time support for camera resolution

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

Note: For X4 and X5, the preview stream resolution cannot be adjusted. The default setting for X4 is 2880x1440, and the default setting for X5 is 2656x1328. The X3 can be manually set to 3840x1920/1440x720.

//Set resolution and preview stream type
InstaCameraManager.getInstance().startPreviewStream(
    PreviewStreamResolution.STREAM_368_368_30FPSInstaCameraManager.PREVIEW_TYPE_LIVE
);

Preview Audio

You can set whether to turn on audio during preview.

PreviewParamsBuilder builder = new PreviewParamsBuilder()
        .setStreamResolution(PreviewStreamResolution.STREAM_368_368_30FPS)
        .setPreviewType(InstaCameraManager.PREVIEW_TYPE_LIVE)
        // Whether to turn on audio
        .setAudioEnabled(true);
InstaCameraManager.getInstance().startPreviewStream(builder);

Capture Control Module

Get the Current Capturing Mode

CaptureMode captureMode = InstaCameraManager.getInstance().getCurrentCaptureMode();
// The current SDK supports the following capturing modes. Specific camera models may exhibit slight variations; refer to your camera's display for exact details:
Normal CaptureCaptureMode.CAPTURE_NORMAL
HDR CaptureCaptureMode.HDR_CAPTURE
Night SceneCaptureMode.NIGHT_SCENE
Burst ModeCaptureMode.BURST
Interval ShootingCaptureMode.INTERVAL_SHOOTING
Starlapse ShootingCaptureMode.STARLAPSE_SHOOTING
Normal Video RecordingCaptureMode.RECORD_NORMAL
HDR RecordingCaptureMode.HDR_RECORD
Bullet TimeCaptureMode.BULLETTIME
Timelapse ModeCaptureMode.TIMELAPSE
Time Shift ModeCaptureMode.TIME_SHIFT
Loop Recording ModeCaptureMode.LOOPER_RECORDING
Super RecordingCaptureMode.SUPER_RECORD
Slow MotionCaptureMode.SLOW_MOTION
Selfie Tracking ModeCaptureMode.SELFIE_RECORD
Pure Video Mode (Night Scene):CaptureMode.PURE_RECORD
LIVECaptureMode.LIVE

Switching Capturing Mode

InstaCameraManager.getInstance().setCaptureMode(captureMode, errorCode -> {
    if (errorCode == 0) {
        // Switching successful
    } else {
        // Switching failed
    }
});

Capturing Status Notification

Note: For the X3 and earlier camera models, videos exceeding 30 minutes will be split into two recordings. The camera will automatically stop recording the first segment and begin recording the second segment.

InstaCameraManager.getInstance().setCaptureStatusListener(new ICaptureStatusListener() {
    @Override
    public void onCaptureCountChanged(int captureCount) {
        // Number of shots captured for modes such as interval shooting and starry sky mode,
    }

    @Override
    public void onCaptureStarting() {
        // Capture is about to start
    }

    @Override
    public void onCaptureStopping() {
        // Capture is about to stop
    }
    
    @Override
    public void onCaptureTimeChanged(long captureTime) {
       // Recording time callback, applicable only in video recording mode
    }

    @Override
    public void onCaptureWorking() {
        // Capturing in progress
    }

    @Override
    public void onCaptureFinish(String[] filePaths) {
        // Capture finished, returns the file paths of the final products
    }
    
    @Override
    public void onCaptureError(int errorCode) {
        // capturing failed error reference capturing failed error code
    }
});

Parameter Settings

Capturing Properties

The current SDK supports the following capturing properties:

  • Exposure Mode: CaptureSetting.EXPOSURE
FULL_AUTO     = Exposure.FULL_AUTO,     // Full Auto
AUTO          = Exposure.AUTO,          // Auto
ISO_FIRST     = Exposure.ISO_FIRST,     // ISO Priority
SHUTTER_FIRST = Exposure.SHUTTER_FIRST, // Shutter Priority
MANUAL        = Exposure.MANUAL,        // Manual
ADAPTIVE      = Exposure.ADAPTIVE       // Panorama Adaptive Exposure
  • Full Auto: Exposure.FULL_AUTO

  • Auto: Exposure.AUTO

  • ISO Priority: Exposure.ISO_FIRST

  • Shutter Priority: Exposure.SHUTTER_FIRST

  • Manual: Exposure.MANUAL

  • Panorama Adaptive Exposure: Exposure.ADAPTIVE

  • EV:CaptureSetting.EV

  • EV Interval: CaptureSetting.EV_INTERVAL

  • Shutter Speed: CaptureSetting.SHUTTER

  • Shutter Mode: CaptureSetting.SHUTTER_MODE

AUTO   = ShutterMode.AUTO,   // Auto
SPORT  = ShutterMode.SPORT,  // Indoor Low-light Stabilization
FASTER = ShutterMode.FASTER  // Extra Fast
  • ISO: CaptureSetting.ISO

  • Max ISO: CaptureSetting.ISO_TOP_LIMIT

  • Video Resolution & Frame Rate: CaptureSetting.RECORD_RESOLUTION

  • Photo Resolution: CaptureSetting.PHOTO_RESOLUTION

  • White Balance: CaptureSetting.WB

  • AEB: CaptureSetting.AEB

  • Interval Duration: CaptureSetting.INTERVAL

  • Color Mode: CaptureSetting.GAMMA_MODE

STAND  = GammaMode.STAND,  // Standard
VIVID  = GammaMode.VIVID,  // LOG
LOG    = GammaMode.LOG,    // Vivid
FLAT   = GammaMode.FLAT    // Flat
  • Photo Format: CaptureSetting.RAW_TYPE
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
  • Recording Duration: CaptureSetting.RECORD_DURATION

  • Low Light Stabilization: CaptureSetting.DARK_EIS_ENABLE

  • Panorama Adaptive Exposure: CaptureSetting.PANO_EXPOSURE_MODE

OFF       = PanoExposureMode.OFF,       // Off
ON        = PanoExposureMode.ON,        // Independent Exposure
LIGHT     = PanoExposureMode.LIGHT,     // Standard
LSOLATED  = PanoExposureMode.LSOLATED   // High

Note: For cameras prior to Insta360 X4, only ON and OFF were supported. From X4 onwards, ON is split into LIGHT and LSOLATED.

  • Burst Capture Count: CaptureSetting.BURST_CAPTURE

  • In-camera Splicing: CaptureSetting.INTERNAL_SPLICING

ON  = InternalSplicing.ON,   // On
OFF = InternalSplicing.OFF   // Off
  • Video HDR Mode: CaptureSetting.HDR_STATUS
ON  = HdrStatus.ON,   // On
OFF = HdrStatus.OFF   // Off

Note: From Insta360 X5 onwards, CaptureMode.HDR_RECORD is removed. Use CaptureSetting.HDR_STATUS instead.

  • Photo HDR Mode: CaptureSetting.PHOTO_HDR_TYPE
On: PhotoHdrType.HDR_ON
Off: PhotoHdrType.HDR_OFF
AEB: PhotoHdrType.HDR_AEB

Note: From Insta X5 onwards, CaptureMode.HDR_CAPTURE is removed. Use CaptureSetting.PHOTO_HDR_TYPE instead.

  • I-LOG: CaptureSetting.I_LOG
ON  = ILogStatus.ON,   // On
OFF = ILogStatus.OFF   // Off
  • Photo Countdown:CaptureSetting.LATENCY

Note: Only supported on X5

Get Capturing Parameters

You can use the InstaCameraManager.getInstance().getXxx(CaptureMode) method to retrieve the corresponding capturing properties.

Method Parameter Return Type Description
getRecordDuration() CaptureMode RecordDuration Get recording duration
getRecordResolution() CaptureMode RecordResolution Get video resolution and frame rate
getPhotoResolution() CaptureMode PhotoResolution Get photo resolution
getInterval() CaptureMode Interval Get capturing interval duration
getHdrStatus() CaptureMode HdrStatus Get HDR status for normal video recording
getPhotoHdrType() CaptureMode PhotoHdrType Get HDR status for normal photo capture
getGammaMode() CaptureMode GammaMode Get color mode
getRawType() CaptureMode RawType Get photo format
getPanoExposureMode() CaptureMode PanoExposureMode Get panorama independent exposure status
getExposure() CaptureMode Exposure Get exposure mode
getISO() CaptureMode ISO Get ISO value
getISOTopLimit() CaptureMode ISOTopLimit Get ISO upper limit
getShutterMode() CaptureMode ShutterMode Get shutter mode
getShutter() CaptureMode Shutter Get shutter speed
getEv() CaptureMode Ev Get EV value
getEVInterval() CaptureMode EVInterval Get EV interval
getAEB() CaptureMode AEB Get AEB
getWB() CaptureMode WB Get white balance
getInternalSplicingEnable() CaptureMode InternalSplicing Get in-camera stitching status
getDarkEisType() CaptureMode DarkEisType Get low-light stabilization status
getBurstCapture() CaptureMode BurstCapture Get burst mode parameters
getILogStatus() CaptureMode ILogStatus Get the I-LOG Switch
getLatency() CaptureMode Latency Get the photo countdown

Set Capturing Properties

You can use the*InstaCameraManager.getInstance().setXxx(CaptureMode)* method to set the corresponding capturing properties.

Method Parameter 1 Parameter 2 Return Type Description
setRecordDuration() CaptureMode RecordDuration void Set recording duration
setRecordResolution() CaptureMode RecordResolution void Set video resolution and frame rate
setPhotoResolution() CaptureMode PhotoResolution void Set photo resolution
setInterval() CaptureMode Interval void Set capturing interval duration
setHdrStatus() CaptureMode HdrStatus void Set HDR status for normal video
setPhotoHdrType() CaptureMode PhotoHdrType void Set HDR status for normal photo
setGammaMode() CaptureMode GammaMode void Set color mode
setRawType() CaptureMode RawType void Set photo format
setPanoExposureMode() CaptureMode PanoExposureMode void Set panorama independent exposure status
setExposure() CaptureMode Exposure void Set exposure mode
setISO() CaptureMode ISO void Set ISO value
setISOTopLimit() CaptureMode ISOTopLimit void Set ISO upper limit
setShutterMode() CaptureMode ShutterMode void Set shutter mode
setShutter() CaptureMode Shutter void Set shutter speed
setEv() CaptureMode Ev void Set EV value
setEVInterval() CaptureMode EVInterval void Set EV interval
setAEB(CaptureMode CaptureMode AEB void Set AEB
setWB() CaptureMode WB void Set white balance
setInternalSplicingEnable() CaptureMode InternalSplicing void Set in-camera stitching
setDarkEisType() CaptureMode DarkEisType void Set low-light stabilization
setBurstCapture() CaptureMode BurstCapture void Set burst mode parameters
setILogStatus CaptureMode ILogStatus void Setting the I-LOG switch
setLatency() CaptureMode Latency void Set a photo countdown

Batch Set Capturing Properties

//Start batch setting of capturing properties
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);

//Submit batch settings to take effect
InstaCameraManager.getInstance().commitSettingOptions();

Dependency between Capturing Properties

There are interdependencies among different capturing properties. Setting property A may affect the support list of property B. Therefore, after setting a property, it is necessary to check the other affected properties.

Note: Since the callback function may be invoked multiple times, the elements in the CaptureSetting list may differ each time it is called.

Example:

// The example only demonstrates setting PhotoHdrType; other property settings follow the same pattern;
InstaCameraManager.getInstance().setPhotoHdrType(captureMode, photoHdrType, new InstaCameraManager.IDependChecker() {
    @Override
    public void check(List<CaptureSetting> captureSettings) {
        // captureSettings:list of affected capturing properties
        // UI updates can be handled here
    }
});

Photo Capture

Determine whether the Camera is in Photo Mode

boolean isPhotoMode = CaptureMode.PURE_RECORD.isPhotoMode();

Start Capturing

// Start Normal capture
InstaCameraManager.getInstance().startNormalCapture();

// Start HDR capture
InstaCameraManager.getInstance().startHDRCapture();

// Start super night scene
InstaCameraManager.getInstance().startNightScene();

// Start burst capture
InstaCameraManager.getInstance().startBurstCapture();

// Start Interval Shooting
InstaCameraManager.getInstance().startIntervalShooting();
// Stop interval shooting
InstaCameraManager.getInstance().stopIntervalShooting();

// Start starlapse shooting
InstaCameraManager.getInstance().startStarLapseShooting();
// Stop starlapse shooting
InstaCameraManager.getInstance().stopStarLapseShooting();

Video Recording

Determine if it is Video Mode

boolean isVideoMode = CaptureMode.PURE_RECORD.isVideoMode();

Start/Stop Recording

// Start normal recording
InstaCameraManager.getInstance().startNormalRecord();
// Stop normal recording
InstaCameraManager.getInstance().stopNormalRecord();

// Start HDR recording
InstaCameraManager.getInstance().startHDRRecord();
// Stop HDR recording
InstaCameraManager.getInstance().stopHDRRecord();

// Start Bullet Time
InstaCameraManager.getInstance().startBulletTime();
// Stop Bullet Time
InstaCameraManager.getInstance().stopBulletTime();

// Start timelapse recording
InstaCameraManager.getInstance().startTimeLapse();
// Stop timelapse recording
InstaCameraManager.getInstance().stopTimeLapse();

// Start time shift recording
InstaCameraManager.getInstance().startTimeShift();
// Stop time shift recording
InstaCameraManager.getInstance().stopTimeShift();

// Start loop recording
InstaCameraManager.getInstance().startLooperRecord();
// Stop loop recording
InstaCameraManager.getInstance().stopLooperRecord();

// Start super recording
InstaCameraManager.getInstance().startSuperRecord();
// Stop super recording
InstaCameraManager.getInstance().stopSuperRecord();

// Start slow motion recording
InstaCameraManager.getInstance().startSlowMotionRecord();
// Stop slow motion recording
InstaCameraManager.getInstance().stopSlowMotionRecord();

// Start selfie tracking mode
InstaCameraManager.getInstance().startSelfieRecord();
// Stop selfie tracking mode
InstaCameraManager.getInstance().stopSelfieRecord();

// Start night scene recording
InstaCameraManager.getInstance().startPureRecord();
// Stop night scene recording
InstaCameraManager.getInstance().stopPureRecord();

LIVE Module

Note: Required to use with the Media SDK.

Determine if it is Live Streaming Mode

boolean isLiveMode = CaptureMode.PURE_RECORD.isLiveMode();

Start Live Streaming

Note: After the preview stream is turned off, the camera will automatically switch the capturing mode to normal recording. Before starting LIVE, you need to check whether the current capturing mode is LIVE. Specific parameters are set using CaptureSetting.

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() {
        // 直播推流开始
    }
});

End LIVE

InstaCameraManager.getInstance().stopLive();

File Management Module

Get the Camera Socket Address

// Return value example:http://192.168.42.1:80
InstaCameraManager.getInstance().getCameraHttpPrefix();

Get Camera File URL

// Return value example:[/DCIM/Camera01/VID_20250326_184618_00_001.insv]
List<String> usls = InstaCameraManager.getInstance().getAllUrlList();

// Includes files in the video
List<String> usls = InstaCameraManager.getInstance().getAllUrlListIncludeRecording();

Delete Camera Files

// Delete a single camera file
InstaCameraManager.getInstance().deleteFile(String filePathnew ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // Delete successfully
    }

    @Override
    public void onFailed() {
       // Delete failed
    }

    @Override
    public void onCameraConnectError() {
      // Camera connection error
    }
});

// Batch delete camera files
InstaCameraManager.getInstance().deleteFileList(List<String> fileUrlListnew ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // Delete successfully
    }

    @Override
    public void onFailed() {
       // Delete failed
    }

    @Override
    public void onCameraConnectError() {
      // Camera connection error
    }
});

Logging Module

Set Log Root Path

The SDK's log system supports saving logs to local files. Call the following code to set the log save location.

// Set the log cache path. If not set, no cache will be performed.
LogManager.instance.setLogRootPath(StorageUtils.getInternalRootPath() + "/log");

Start/Stop Logging

Enable the global log real-time capture function, which will capture all logs, including SDK logs, system logs, host APP logs, etc., and save them in the directory specified above.

// Enable real-time log capture
LogManager.instance.startLogDumper();

// Stop real-time log capture
LogManager.instance.stopLogDumper();

GPS Data Module

Settings in Photo Mode

// android.location.Location class,developer obtains it via system API
Location location;

// Set GPS data when taking a photo
GpsData gpsData = new GpsData();
gpsData.setLatitude(location.getLatitude());
gpsData.setLongitude(location.getLongitude());
gpsData.setAltitude(location.getAltitude());
InstaCameraManager.getInstance().startNormalCapture(gpsData.simpleGpsDataToByteArray());

GPS Data Interface for Input in Different Photo Modes

// Start normal capturing and input GPS data.
InstaCameraManager.getInstance().startNormalCapture(byte[]);

// Start HDR capturing and input GPS data.
InstaCameraManager.getInstance().startHDRCapture(byte[]);

// Start burst capturing and input GPS data.
InstaCameraManager.getInstance().startBurstCapture(byte[]);

// Start interval shooting and input GPS data.
InstaCameraManager.getInstance().stopIntervalShooting(byte[]);

Settings in Record Mode

GPS data for recording settings can be divided into the following two situations:

When the Recording is Stopped

Stopping recording is the same as taking photos. The example code is as follows:

// android.location.Location class, developer obtains it via system API
Location location;

// Set GPS data when stopping the recording
GpsData gpsData = new GpsData();
gpsData.setLatitude(location.getLatitude());
gpsData.setLongitude(location.getLongitude());
gpsData.setAltitude(location.getAltitude());
InstaCameraManager.getInstance().stopNormalRecord(gpsData.simpleGpsDataToByteArray());

In Recording

GPS data can be set at any time in the video recording. GPS data is usually used to create the camera's motion trajectory. Therefore, it is recommended to set the GPS interval as much as possible each time. The example code is as follows:

// Collect GPS data every 100ms; once 20 GPS data points are accumulated, send them to the camera

private Handler mMainHandler = new Handler(Looper.getMainLooper());
// List of GPS data
private List<GpsData> mCollectGpsDataList = new ArrayList<GpsData>();

private Runnable mCollectGpsDataRunnable = new Runnable() {
    @Override
    public void run() {
        // android.location.Location class, developer obtains it via system API
        Location locationif (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);
    }
};

// Start collecting GPS data
mMainHandler.post(mCollectGpsDataRunnable);

GPS Data Interface for Input in Different Recording Modes

// Stop normal recording and input GPS data.
InstaCameraManager.getInstance().stopNormalRecord(byte[]);

// Stop HDR recording and input GPS data.
InstaCameraManager.getInstance().stopHDRRecord(byte[]);

// Stop Bullet Time and input GPS data.
InstaCameraManager.getInstance().stopBulletTime(byte[]);

// Stop Timelapse and input GPS data.
InstaCameraManager.getInstance().stopTimeLapse(byte[]);

// Stop Time Shift and input GPS data.
InstaCameraManager.getInstance().stopTimeShift(byte[]);

// Stop super Recording and input GPS data.
InstaCameraManager.getInstance().stopSuperRecord(byte[]);

// Stop loop Recording and input GPS data.
InstaCameraManager.getInstance().stopLooperRecord(byte[]);

// Stop night Scene recording and input GPS data.
InstaCameraManager.getInstance().stopPureRecord(byte[]);

// Stop selfie tracking recording and input GPS data.
InstaCameraManager.getInstance().stopSelfieRecord(byte[]);

Other Features Module

Camera Activation

Activating the camera requires the use of two pieces of data, appIdand secretKey. These two data need to be applied for by the official Insta360.

Note: Activation requires network permissions

Note: Nano S cameras do not support this feature.

Example code is as follows:

String appid = "xxxxxxxx";
String mSecretKey = "xxxxxxx";
InstaCameraManager.getInstance().activateCamera(new SecretInfo(appid , mSecretKey), new InstaCameraManager.IActivateCameraCallback() {
    @Override
    public void onStart() {
        // Began to activate
    }

    @Override
    public void onSuccess() {
        // Activation successful
    }

    @Override
    public void onFailed(String message) {
        // Activation failed
    }
});

Camera Prompt Sound

Note: The Nano S camera does not support the prompt sound switch, but supports the setting.

The switch for camera prompt sound. Example code is as follows:

// Turn on the camera prompt tone
InstaCameraManager.getInstance().setCameraBeepSwitch(true);

// Determine whether the camera has a prompt tone turned on
boolean isBeep = InstaCameraManager.getInstance().isCameraBeep();

Format the SD Card

InstaCameraManager.getInstance().formatStorage(new ICameraOperateCallback() {
    @Override
    public void onSuccessful() {
        // SD card formatted successfully
    }

    @Override
    public void onFailed() {
        // SD card formatting failed
    }

    @Override
    public void onCameraConnectError() {
        // Camera connection error
    }
});

Camera Lock Screen

Note: Nano S cameras do not support this feature.

After the camera is locked, the user cannot operate the camera screen. Example code is as follows:

// true: lock screen   false: unlock screen
InstaCameraManager.getInstance().setCameraLockScreen(true);

Turn off the Camera

Instructions to control camera shutdown, sample code is as follows:

Note: Only Insta360X5 and later cameras support this feature.

InstaCameraManager.getInstance().shutdownCamera();

Calibration of Gyroscope

Note: Nano S cameras do not support this feature.

When the camera is connected to Wi-Fi, this function should be used. Before calibration, make sure the camera is placed vertically on a stable and horizontal surface.

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

    @Override
    public void onFailed() {
    }

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

Firmware Upgrade

Use the FwUpgradeManager class to upgrade the firmware version. The example code is as follows:

Note: Nano S cameras do not support this feature.

Note: Please make sure to upload the correct files to the camera to prevent any potential damage. For example, do not upload the ONE X firmware upgrade package to the ONE X2 camera.

// Determine if an upgrade is in progress
FwUpgradeManager.getInstance().isUpgrading();

// Cancel the upgrade
FwUpgradeManager.getInstance().cancelUpgrade();

String fwFilePath = "/xxx/InstaOneXFW.bin";
// Upgrade firmware
FwUpgradeManager.getInstance().startUpgrade(fwFilePath, new FwUpgradeListener() {
    @Override
    public void onUpgradeSuccess() {
        // Callback after successful upgrade
    }

    @Override
    public void onUpgradeFail(int errorCode, String message) {
         // Upgrade failure callback
         // Firmware error code
    }

    @Override
    public void onUpgradeCancel() {
         // Upgrade cancel callback
    }

    @Override
    public void onUpgradeProgress(double progress) {
        // Upgrade progress callback: 0-1
    }
});

Sharpness Settings (Currently Unsupported)

Error Code

Camera Connection Error Code

Error Code Explanation
-122 Bluetooth device disconnected
501 Bluetooth disconnection occurred
2201 System error BleException.ERROR_CODE_SYSTEM_STATUS_133
2002 Open camera timed out
2206 System error BleException.ERROR_CODE_NOTIFY_FAILURE
2207 System error BleException.ERROR_CODE_SHAKE_HAND
3201 Socket connection failed
3205 Socket connection timed out
3206 Socket reconnect timed out
4001 System error BleException.ERROR_CODE_SYNC_PACK
4101 Camera type error
4103 Camera sync parameter timed out
4402 Camera operating system error
4403 Camera is occupied
4405 Parsing proto failed
4406 Camera sync parameter retry timeout
4407 Camera data exception
4414 Failed to wake up Bluetooth
4417 Camera disconnected during operation
4504 Camera disconnected when connected
4505 Bluetooth binding rejected
4507 Bluetooth write failed
4508 Device Bluetooth busy
4602 Device Wi-Fi busy
4605 USB error
4606 Socket Disconnected Due to Dirty Data
-14169 Failed to synchronize camera parameters due to Bluetooth failure

Firmware Upgrade Error Code

Error Code Explanation
-1000 Already upgrading
-1001 Camera not connected
-1002 When the camera battery is below 12%, the upgrade will fail, please make sure the camera battery is fully charged
-14004 Http server error
400 Http server error
500 Http server error
-14005 Socket IO exception
  1. Capturing Failed Error Code

Error Code Explanation
-14161 Low battery
-14162 Exceeded the maximum recording time limit
-14163 SD card is full
-14165 Exceeded the file limit
-14166 SD card speed is low
-14167 Coding anomaly
-14168 Frame loss
-14180 Excessive file fragmentation
-14181 Camera temperature is too high
-14182 Low power start
-14183 Storage Deflection Start
-14184 High temperature start
-14164 Other situations
  1. Camera Activation Error Code

Error Code Explanation
400 Parameter error, possibly due to the camera type or serial number not being obtained
401 Interface signature verification failed
402 Data encryption verification failed
403 The nonce credential has already been used
406 The timestamp has expired
429 Frequent interface requests
500 Internal system exception
3001 Device serial number does not match device type
3002 Camera has been activated
3003 Activation denied; IP address is not within a valid region
3004 Unable to generate a valid serial number
3005 The system does not support activating devices of this model
3006 The serial number has been locked by the backend and cannot be activated
429 The activation IP is subject to rate limiting. Rate limiting policy: 45 attempts per IP per day

Media SDK Function

Environmental Preparation

  • Add the maven address to the build file (build.gradle file in the project root directory)
allprojects {
    repositories {
        ...
        maven {
            url 'XXXXXX'
            credentials {
                // see sdk demo
                username = '***'
                password = '***'
            }
        }
    }
}
  • Import the dependency library in thebuild.gradle file of the app directory
dependencies {
    implementation 'com.arashivision.sdk:sdkmedia:x.x.x'
}

Preview Module

If you have integrated the Camera SDK, you can open and display the preview content.

Preview Control Initalization

You need to put *InstaCapturePlayerView*into your XML file and bind the lifecycle of the Activity:

<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());
}

Display Preview Screen

Show preview screen in IPreviewStatusListener.onOpen() callback of Camera SDK

@Overridepublic void onOpened() {
    InstaCameraManager.getInstance().setStreamEncode();
    mCapturePlayerView.setPlayerViewListener(new PlayerViewListener() {
        @Override
        public void onLoadingFinish() {
            // Fixed writing
            InstaCameraManager.getInstance().setPipeline(mCapturePlayerView.getPipeline());
        }
        
        @Override
        public void onLoadingStatusChanged(boolean isLoading) {
            // loading status change
        }

        @Override
        public void onFail(String desc) {
        }
        
        @Override
        public void onFirstFrameRender() {
            // First frame rendered successfully
        }
    });
    // Set parameters, which will be described in detail later
    mCapturePlayerView.prepare(createParams());
    // Play
    mCapturePlayerView.play();
    // Keep the screen always on
    mCapturePlayerView.setKeepScreenOn(false);
}

Release Resources

When closing the preview stream, you need to release the InstaCapturePlayerView

@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);
}

Set Preview Parameters

private CaptureParamsBuilderV2createParams() {
    CaptureParamsBuilderV2builder = new CaptureParamsBuilderV2()
            // (Optional) Set your resolution and frame rate. The default values are generated intelligently by the SDK.
            .setWidth(int width)
            .setHeight(int height)
            .setFps(int fps) //Max 30fps
            // (optional) achromatic Default value is true
            .setImageFusionEnabled(boolean enable)
            // (Optional) Set the gesture switch. The default value is generated intelligently by the SDK
            .setGestureEnabled(boolean enable)
            // (Optional) Set the number of frames cached for anti-shake. The more frames cached, the better the anti-shake effect, but the higher the image delay.
            .setStabCacheFrameNum(5)
            // (Optional) Set the stabilization type. The default value is generated intelligently by the SDK.
            .setStabType(@InstaStabType.StabType int mStabType)
            // (Optional) Set the rendering mode; the default value is “RenderModel.AUTO”.
            .setRenderModel(RenderModel.PLANE_STITCH)
            // (Optional) Set the screen ratio. For example, 9:16. The default value is generated by the SDK.
            // If the rendering mode type is “PLANE_STITCH”, it is recommended to set the aspect ratio to 2:1.
            .setScreenRatio(int,int)
            // (Optional) Set custom Surface information
            .setCameraRenderSurfaceInfo(CameraRenderSurfaceInfo);
    return builder;
}

Switch Rendering Mode

// Ordinary
mCapturePlayerView.switchNormalMode();
// Fish eye
mCapturePlayerView.switchFisheyeMode();
// Perspective
mCapturePlayerView.switchPerspectiveMode();

Field of View Distance

You can customize the viewing angle and distance according to your preferences.

Fov: Angle range 0~180

Distance: line of sight range 0~∞

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

Gesture Operation

You can set PlayerGestureListener to observe gesture actions:

mCapturePlayerView.setGestureListener(new PlayerGestureListener() {
    @Override
    public boolean onDown(MotionEvent e) {
        // Use finger press event
        return PlayerGestureListener.super.onDown(e);
    }

    @Override
    public boolean onTap(MotionEvent e) {
        // User finger click event, similar to View. OnClickListener. OnClick (v)
        return PlayerGestureListener.super.onTap(e);
    }

    @Override
    public void onUp() {
        // User finger lift event
        PlayerGestureListener.super.onUp();
    }

    @Override
    public void onLongPress(MotionEvent e) {
         // User long press event
        PlayerGestureListener.super.onLongPress(e);
    }

    @Override
    public void onZoom() {
        // User two-finger zoom event
        PlayerGestureListener.super.onZoom();
    }

    @Override
    public void onZoomAnimation() {
        // Rebound animation when scaling to maximum or minimum
        PlayerGestureListener.super.onZoomAnimation();
    }

    @Override
    public void onZoomAnimationEnd() {
        // Zoom rebound animation ends
        PlayerGestureListener.super.onZoomAnimationEnd();
    }

    @Override
    public void onScroll() {
        // User finger swipe event
        PlayerGestureListener.super.onScroll();
    }

    @Override
    public void onFlingAnimation() {
        // Fling animation
        PlayerGestureListener.super.onFlingAnimation();
    }

    @Override
    public void onFlingAnimationEnd() {
         // Quick swipe animation ends
        PlayerGestureListener.super.onFlingAnimationEnd();
    }
});

WorkWrapper

WorkWrapper is a collection of all data in a slice file. For example: Continuous capturing generates multiple files, which are then encapsulated into a single WorkWrapper for unified processing. Subsequent operations such as playback, export, and information retrieval are all performed by manipulating the WorkWrapper object.

How to Get WorkWrapper

You can scan media files from your camera or local directory to obtainList<WorkWrapper>

Note: This is a time-consuming operation that needs to be handled in a child thread.

// Get from the camera
List<WorkWrapper> list = WorkUtils.getAllCameraWorks();

// Get from local file
List<WorkWrapper> list = WorkUtils.getAllLocalWorks(String dirPath);

// If you have the URL of the media file, you can also create WorkWrapper yourself
String[] urls = {img1.insv, img2.insv, img3.insv};
WorkWrapper workWrapper = new WorkWrapper(urls);

Load File Trailer Data

Call the WorkWrapper.loadExtraData() function to load the file trailer data. The play and export functions can be used only after the file trailer data is loaded.

Call the WorkWrapper.isExtraDataLoaded() function to determine whether the file trailer data has been loaded.

Note: This method is a time-consuming operation and needs to be executed in the IO thread.

Read the Content of WorkWrapper

The information you can obtain from WorkWrapper is as follows:

Method Parameter Return Value Type Explanantion
getIdenticalKey() - String For Glide or other DiskCacheKeys
getUrls() - String[] Get media file URL
getUrls() boolean String[] Get the URL of the media file. Set true/false to determine whether to include the dng file path
getAllUrls() - String[] Get all file paths for operations such as downloading and deletion.
getWidth() - int Get width
getHeight() - int Get height
getBitrate() - int Get the video bitrate. If it is a photo, return 0
getFps() - double Get the video frame rate. If it is a photo, return 0
isPhoto() - boolean Whether it is a photo
isHDRPhoto() - boolean Is it an HDR photo
supportPureShot() - boolean Whether to support PureShot algorithm
isVideo() - boolean Whether it is a video
isHDRVideo() - boolean Is it HDR video
isCameraFile() - boolean Is the media file sourced from the camera device
isLocalFile() - boolean Is the media file sourced from a mobile device
getCreationTime() - long Obtain media file shooting timestamp, unit: ms
getFirstFrameTimeOffset() - long Obtain the offset of timestamp relative to camera startup when shooting media files, used to match gyroscope, exposure, and other data, unit: ms
getGyroInfo() - GyroInfo[] Obtain gyroscope data for media files
getExposureData() - ExposureData[] Obtain exposure data for media files
loadThumbnail() - Bitmap Loading thumbnails (time-consuming operation)
loadExtraData() - - Load file trailer data (time-consuming operation)
isExtraDataLoaded() - boolean Whether the file trailer data has been loaded

Image Player

If you want to play images or videos, you must first create a WorkWrapper

Player Initialization

Put the InstaImagePlayerView into an XML file and bind the lifecycle of the Activity.

<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());
}

Set Playback Parameters

ImageParamsBuilder builder = new ImageParamsBuilder()
      //  (Optional) Whether to enable dynamic stitching, default is true
      .setDynamicStitch(boolean dynamicStitch)
      // (Optional) Set the stabilization type, default is InstaStabType STAB_TYPE_OFF
      .setStabType(@InstaStabType.StabType int mStabType)
      // (Optional) Set the playback proxy file, such as HDR.jpg generated by splicing, which is empty by default
      .setUrlForPlay(String url)
      // (Optional) Sets the render model type, default is Render_MODE_AUTO
      .setRenderModel(RenderModel.PLANE_STITCH)
      // (Optional) Set the aspect ratio of the screen, default is full screen display
      //If the render mode type is "RENDER_mode_PLANE_STITCH", the recommended setting ratio is 2:1
      .setScreenRatio(int ratioX, int ratioY)
      // (Optional) Eliminate color difference in image stitching, default is false
      .setImageFusion(boolean imageFusion)
      // (Optional) Set the lens guards type, default is OffsetType. ORIGINAL
      .setOffsetType(OffsetType offsetType)
      // (Optional) Set the color enhancement switch; default is false.
      .setColorPlusEnable(boolean enabled);
      // (Optional) Set the color enhancement intensity, default value is 1, valid range 0-1
      .setColorPlusFilterIntensity(float colorPlusFilterIntensity);
      // (Optional) Whether to allow gesture operations, default is true
      .setGestureEnabled(boolean enabled);
      // (Optional) thumbnail cache folder, default is getCacheDir () + "/ work_thumbnail "
      .setCacheWorkThumbnailRootPath(String path)
      // (Optional) Stabilizer data cache folder, default is get CacheD ir () + "/ stabilizer "
      .setStabilizerCacheRootPath(String path)
      // (Optional) Cache folder, default is getExternalCacheDir () + "/ template_blender "
      .setCacheTemplateBlenderRootPath(String path)
      // (Optional) Star mode image cache folder, default is getCacheDir () + "/ cut_scene "
      .setCacheCutSceneRootPath(String path);

Start Playing

WorkWrapper and playback parameters need to be set before playback.

// Set WorkWrapper and playback parameters
mImagePlayerView.prepare(workWrapper, new ImageParamsBuilder());
// Start playing
mImagePlayerView.play();

Release Resources

When the Activity is destroyed, release InstaImagePlayerView

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

Switch Rendering Mode

Note: If you want to switch between tiling mode and other modes, you must first restart the player.

If the rendering mode you are using is RENDER_MODE_AUTO, you can switch between the following modes.

// Switch to normal mode
mImagePlayerView.switchNormalMode();

// Switch to fisheye mode
mImagePlayerView.switchFisheyeMode();

// Switch to perspective mode
mImagePlayerView.switchPerspectiveMode();

// To switch to tiling mode, you need to restart the player
ImageParamsBuilder builder = new ImageParamsBuilder();
builder.setRenderModelType(ImageParamsBuilder.RENDER_MODE_PLANE_STITCH);
builder.setScreenRatio(2, 1);
mImagePlayerView.prepare(mWorkWrapper, builder);
mImagePlayerView.play();

Field of View Distance

You can customize the viewing angle and distance according to your preferences.

Fov: Angle range 0~180

Distance: line of sight range 0~∞

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

Set Listener

You can set the PlayerViewListener to observe changes in the player state.

mImagePlayerView.setPlayerViewListener(new PlayerViewListener() {
    @Override
    public void onLoadingStatusChanged(boolean isLoading) {
        // Player loading status changed
        //isLoading:whether loading
    }

    @Override
    public void onLoadingFinish() {
        // Player loading complete
    }

    @Override
    public void onFail(int errorCode, String errorMsg) {
        // if GPU not support, errorCode is -10003 or -10005 or -13020
        // Player error
    }
    
    @Override
    public void onFirstFrameRender() {
        // First frame rendering successfully
    }
});

Gesture Operation

You can set PlayerGestureListener to observe gesture actions:

mImagePlayerView.setGestureListener(new PlayerGestureListener() {
    @Override
    public boolean onDown(MotionEvent e) {
        // User finger press event
        return PlayerGestureListener.super.onDown(e);
    }

    @Override
    public boolean onTap(MotionEvent e) {
        // User finger click event, similar to View.OnClickListener.OnClick(v)
        return PlayerGestureListener.super.onTap(e);
    }

    @Override
    public void onUp() {
        // User finger lift event
        PlayerGestureListener.super.onUp();
    }

    @Override
    public void onLongPress(MotionEvent e) {
         // User long press event
        PlayerGestureListener.super.onLongPress(e);
    }

    @Override
    public void onZoom() {
        // User two-finger zoom event
        PlayerGestureListener.super.onZoom();
    }

    @Override
    public void onZoomAnimation() {
        // Rebound animation when scaling to maximum or minimum
        PlayerGestureListener.super.onZoomAnimation();
    }

    @Override
    public void onZoomAnimationEnd() {
        // Zoom rebound animation ends
        PlayerGestureListener.super.onZoomAnimationEnd();
    }

    @Override
    public void onScroll() {
        // User finger swipe event
        PlayerGestureListener.super.onScroll();
    }

    @Override
    public void onFlingAnimation() {
        // Quick slide animation
        PlayerGestureListener.super.onFlingAnimation();
    }

    @Override
    public void onFlingAnimationEnd() {
         // Quick swipe animation ends
        PlayerGestureListener.super.onFlingAnimationEnd();
    }
});

Video Player

Player Initialization

Put the *InstaVideoPlayerView *into an XML file and bind the lifecycle of the Activity.

<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());
}
  1. Set Playback Parameters

VideoParamsBuilder builder = new VideoParamsBuilder()
      // (Optional) Load icon, default is empty
      .setLoadingImageResId(int resId)
      // (Optional) Background color during loading, default is black
      .setLoadingBackgroundColor(int color)
      // (Optional) Whether to play automatically
      .setAutoPlayAfterPrepared(boolean autoPlayAfterPrepared)
      // (Optional) Set the stabilization type, default is InstaStabType STAB_TYPE_OFF
      .setStabType(@InstaStabType.StabType int stabType)
      // (Optional) Whether to play in loop; default is true
      .setIsLooping(boolean isLooping)
      // (Optional) Set whether to play the LRV
      .setLrvEnable(boolean isLrvEnable)
      // (Optional) Whether to enable dynamic stitching, default is true
      .setDynamicStitch(boolean dynamicStitch)
      // (Optional) Eliminate color difference in image stitching, default is false
      .setImageFusion(boolean imageFusion)
      // (Optional) Set the lens guards type, default is OffsetType. ORIGINAL
      .setOffsetType(OffsetType offsetType)
      // (Optional) Remove purple fringing. Default value is false. Requires adding an algorithm file.
      .setDePurpleFilterOn(boolean isDePurpleFilterOn)
      // (Optional) Set the color enhancement switch, default is false
      .setColorPlusEnable(boolean enabled);
      // (Optional) Set the color enhancement intensity, default value is 1, valid range 0-1
      .setColorPlusFilterIntensity(float colorPlusFilterIntensity);
      // (Optional) Sets the render model type, default is Render_MODE_AUTO
      .setRenderModel(RenderModel.PLANE_STITCH)
      // (Optional) Set the aspect ratio of the screen, default is full screen display.
      // If the render mode type is "RENDER_MODE_PLANE_STITCH", it is recommended to set the ratio to 2:1
      .setScreenRatio(int ratioX, int ratioY)
      // (Optional) Whether to allow gesture operations, default is true
      .setGestureEnabled(boolean enabled)
      // (Optional) thumbnail cache folder, default is getCacheDir () + "/ work_thumbnail "
      .setCacheWorkThumbnailRootPath(String path)
      // (Optional) Star mode image cache folder, default is getCacheDir () + "/ cut_scene "
      .setCacheCutSceneRootPath(String path);

Start Playing

WorkWrapper and playback parameters need to be set before playback.

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

Release Resources

When the Activity is destroyed, release InstaVideoPlayerView

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

Playback Control

You can control the playback progress, pause/resume, playback volume, etc. Of the video by calling the code in VideoPlayerView.

方法 参数 返回值 说明
isPlaying - boolean Is the video playing
isLooping - boolean Whether play it on a loop
setLooping boolean void Set whether play it on a loop
setVolume float (Range 0-1) void Set playback volume
pause - void Pause playback
resume - void Resume playback
seekTo long void Fast forward to the specified progress playback
isSeeking - boolean Is it fast forwarding?
getVideoCurrentPosition - long Get the current playback progress of the video
getVideoTotalDuration - long Get the total length of the video.

Switch Rendering Mode

Note: If you want to switch between tiling mode and other modes, you must first restart the player.

If the rendering mode you are using is RENDER_MODE_AUTO, you can switch between the following modes.

// Switch to normal mode
mVideoPlayerView.switchNormalMode();

// Switch to fisheye mode
mVideoPlayerView.switchFisheyeMode();

// Switch to perspective mode
mVideoPlayerView.switchPerspectiveMode();

// To switch to tiling mode, you need to restart the player
VideoParamsBuilder builder = new VideoParamsBuilder();
builder.setRenderModelType(ImageParamsBuilder.RENDER_MODE_PLANE_STITCH);
builder.setScreenRatio(2, 1);
mImagePlayerView.prepare(mWorkWrapper, builder);
mImagePlayerView.play();

Field of View Distance

You can customize the viewing angle and distance according to your preferences.

Fov:Angle range 0~180

Distance:line of sight range 0~∞

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

Set Listener

You can set the PlayerViewListener to observe changes in the player state.

mVideoPlayerView.setPlayerViewListener(new PlayerViewListener() {
    @Override
    public void onLoadingStatusChanged(boolean isLoading) {
        // Player loading status change
        //isLoading:whether loading
    }

    @Overrid
    epublic void onLoadingFinish() {
        // Player loading complete
    }

    @Override
    public void onFail(int errorCode, String errorMsg) {
        // if GPU not support, errorCode is -10003 or -10005 or -13020
        // Player error
    }
    
    @Override
    public void onFirstFrameRender() {
        // First frame rendering successfully
    }
});

You can set VideoStatusListener to observe changes in video status.

mVideoPlayerView.setVideoStatusListener(new VideoStatusListener() {
    @Override
    public void onProgressChanged(long position, long length) {
        // Play progress callback
        // position:played length
        // length:Total length of the video
    }

    @Override
    public void onPlayStateChanged(boolean isPlaying) {
        // Video playback status callback
        // isPlaying:whether it is playing
    }

    @Override
    public void onSeekComplete() {
        // Fast forward completed
    }

    @Override
    public void onCompletion() {
        // Video playback finished
    }
});

Gesture Operation

You can set PlayerGestureListener to observe gesture actions.

mVideoPlayerView.setGestureListener(new PlayerGestureListener() {
    @Override
    public boolean onDown(MotionEvent e) {
        // User finger press event
        return PlayerGestureListener.super.onDown(e);
    }

    @Override
    public boolean onTap(MotionEvent e) {
        // User finger click event, similar to View.OnClickListener.OnClick(v)
        return PlayerGestureListener.super.onTap(e);
    }

    @Override
    public void onUp() {
        // User finger lift event
        PlayerGestureListener.super.onUp();
    }

    @Override
    public void onLongPress(MotionEvent e) {
         // User long press event
        PlayerGestureListener.super.onLongPress(e);
    }

    @Override
    public void onZoom() {
        // User two-finger zoom event
        PlayerGestureListener.super.onZoom();
    }

    @Override
    public void onZoomAnimation() {
        // Rebound animation when scaling to maximum or minimum
        PlayerGestureListener.super.onZoomAnimation();
    }

    @Override
    public void onZoomAnimationEnd() {
        // Zoom rebound animation ends
        PlayerGestureListener.super.onZoomAnimationEnd();
    }

    @Override
    public void onScroll() {
        // User finger swipe event
        PlayerGestureListener.super.onScroll();
    }

    @Override
    public void onFlingAnimation() {
        // Quick slide animation
        PlayerGestureListener.super.onFlingAnimation();
    }

    @Override
    public void onFlingAnimationEnd() {
         // Quick swipe animation ends
        PlayerGestureListener.super.onFlingAnimationEnd();
    }
});

Export

Export Parameters

If you want to export images, you need to first understand the ExportImageParamsBuilder image export parameters.

ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
    // (Must) Export file path
    .setTargetPath(String path)
    // (Optional) Set the width of the exported image, the default value is obtained from WorkWapper.
    .setWidth(int width)
    // (Optional) Set the height of the exported image, the default value is obtained from WorkWapper.
    .setHeight(int height)
    // (Optional) Set export mode, default is'PANORAMA'
    // ExportMode.PANORAMA: Export panoramic images
    // ExportMode.SPHERE: Export flat thumbnail
    .setExportMode(ExportUtils.ExportMode mode)
    // (Optional) Whether to enable dynamic stitching, default is true.
    .setDynamicStitch(boolean dynamicStitch)
    // (Optional) Set the stabilization type, default is InstaStabType.STAB_TYPE_OFF.
    .setStabType(@InstaStabType.StabType int stabType)
    // (Optional) Eliminate color difference in image stitching, default is false
    .setImageFusion(boolean imageFusion)
    // (Optional) Remove purple fringing. Default value is false. Requires adding an algorithm file.
    .setDePurpleFilterOn(boolean isDePurpleFilterOn)
    // (Optional) Set the lens guards type, default is OffsetType. ORIGINAL.
    .setOffsetType(OffsetType offsetType)
    // (Optional) Set as HDR.jpg generated by splicing, default is null
    .setUrlForExport(String url)
    // (Optional) Set to use software decoder, default is false
    .setUseSoftwareDecoder(boolean useSoftwareDecoder)
    // (Optional) Set the camera angle. It is recommended to use it when exporting thumbnails.
    // The currently displayed angle parameter can be obtained from'PlayerView.getXXX () '.
    .setFov(float fov)
    .setDistance(float distance)
    .setYaw(float yaw)
    .setPitch(float pitch)
    // (Optional) Cache folder, default is getCacheDir () + "/ work_thumbnail "
    .setCacheWorkThumbnailRootPath(String path)
    // (Optional) Cache folder, default is get CacheD ir () + "/ stabilizer "
    .setStabilizerCacheRootPath(String path)
    // (Optional) Cache folder, default is getCacheDir () + "/ cut_scene "
    .setCacheCutSceneRootPath(String path);

Export Panoramic Images

Use images to export parameters:

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() {       
                // Export successful        
            }

            @Override
            public void onFail() {
                // Export failed
            }

            @Override
            public void onCancel() {
                // Cancel export
            }

            @Override
            public void onProgress(float progress) {
                // Export progress
            }
        });

Export Image thumbnail

Use images to export parameters:

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() {       
                // Export successful     
            }

            @Override
            public void onFail() {
                // Export faild
            }

            @Override
            public void onCancel() {
                // Cancel export
            }

            @Override
            public void onProgress(float progress) {
                // Export progress
            }
        });

Export Video

Export Video Parameters

To export a video, you first need to understand the video export parameters ExportVideoParamsBuilder

ExportVideoParamsBuilder builder = new ExportVideoParamsBuilder()
    // (Must) Export file path
    .setTargetPath(String path)
    // (Optional)Set the width of the exported video. It must be a power of 2, and the default value is obtained from WorkWapper.
    .setWidth(int width)
    // (Optional)Set the height of the exported video. It must be a power of 2, and the default value is obtained from WorkWapper.
    .setHeight(int height)
    // (Optional)Set the bitrate for exporting videos, with the default value being obtained from WorkWapper.
    .setBitrate(int bitrate)
    // (Optional)Set the fps for exporting videos, with the default value being obtained from WorkWapper.
    .setFps(int fps)
    // (Optional) Set export mode, default is'PANORAMA'
    // ExportMode.PANORAMA: Export panoramic images
    // ExportMode.SPHERE: Export flat thumbnail
    .setExportMode(ExportUtils.ExportMode mode)
    // (Optional) Remove purple fringing. Default value is false. Requires adding an algorithm file.
    .setDePurpleFilterOn(boolean isDePurpleFilterOn)
    // (Optional) Enable noise reduction (Noise reduction is enabled by default for exported images; the noise reduction toggle is only supported for exported videos)
    // The ExportUtils.supportDenoise(WorkWrapper) method must be called in advance to determine whether denoising is supported.
    // If noise reduction is supported, the setting is effective; otherwise, the setting is ineffective.
    .setDenoise(true)
    // (Optional) Eliminate color difference in image stitching, default is false
    .setImageFusion(boolean imageFusion)
    // (Optional) Set the lens guards type, default is OffsetType. ORIGINAL.
    .setOffsetType(OffsetType offsetType)
    // (Optional) Whether to enable dynamic stitching, default is true.
    .setDynamicStitch(boolean dynamicStitch)
    // (Optional) Set the stabilization type, default is InstaStabType.STAB_TYPE_OFF.
    .setStabType(@InstaStabType.StabType int stabType)
    // (Optional) Set to use software decoder, default is false
    .setUseSoftwareDecoder(boolean useSoftwareDecoder)
    // (Optional) Cache folder, default is getCacheDir () + "/ work_thumbnail"
    .setCacheWorkThumbnailRootPath(String path)
    // (Optional) Cache folder, default is getCacheDir () + "/ cut_scene"
    .setCacheCutSceneRootPath(String path)
    // (Optional) Set the field of view
    .setFov(float fov)
    // (Optional) Set the view distance
    .setDistance(float distance)
    // (Optional) Set the Euler angle - pitch angle
    .setPitch(float pitch)
    // (Optional) Set the Euler angle-yaw angle
    .setYaw(float yaw)
    // (Optional) Set the Euler angle-roll angle
    .setRoll(float roll);

Export Panoramic Video

Use video export parameters.

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() {       
                // Export successful        
            }

            @Override
            public void onFail() {
                // Export failed
            }

            @Override
            public void onCancel() {
                // Cancel export
            }

            @Override
            public void onProgress(float progress) {
                // Export progress
            }
        });

Export Video Thumbnail

Since the exported result is an image, use the image export parameters.

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() {       
                // Export successful        
            }

            @Override
            public void onFail() {
                // Export failed
            }

            @Override
            public void onCancel() {
                // Cancel export
            }

            @Override
            public void onProgress(float progress) {
                // export progress
            }
        });

Stop Exporting

ExportUtils.stopExport(exportId);

Others

Generate HDR Images

If you have a WorkWrapper with HDR images, you can generate them into an image file using HDR stitching.

Note: This is a time-consuming operation that needs to be handled in a child thread.

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

After the successful call of generateHDR, outputPath can be played as a proxy or set as an export URL.

// Set as playback agent
ImageParamsBuilder builder = new ImageParamsBuilder()
        // If HDR splicing is successful, set it as a playback proxy
        .setUrlForPlay(isSuccessful ? hdrOutputPath : null);
mImagePlayerView.prepare(workWrapper, builder);
mImagePlayerView.play();

// Set as export url
ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
        .setExportMode(ExportUtils.ExportMode.PANORAMA)
        .setTargetPath(exportPath)
        // If HDR splicing is successful, set it as export url
        .setUrlForExport(hdrOutputPath);

Generate PureShot images

If you have a WorkWrapper of a PureShot image, you can generate it into an image file by stitching it together with PureShot.

Note: This is a time-consuming operation that needs to be handled in a child thread.

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

Note: Generating PureShot images requires algorithm model files. Please request the algorithm model files corresponding to your SDK version from our technical support team.

algoFolderPath is the directory for algorithm model files, which can be either LocalStoragePath or AssetsRelativePath. The SDK will load these files as needed.

After the successful call to generatePureShot, outputPath can be played as a proxy or set as an export URL.

// Set as playback agent
ImageParamsBuilder builder = new ImageParamsBuilder()
        // If PureShot splicing is successful, set it as a playback proxy
        .setUrlForPlay(isSuccessful ? pureshotOutputPath : null);
mImagePlayerView.prepare(workWrapper, builder);
mImagePlayerView.play();

// Set as export url
ExportImageParamsBuilder builder = new ExportImageParamsBuilder()
        .setExportMode(ExportUtils.ExportMode.PANORAMA)
        .setTargetPath(exportPath)
        // If PureShot splicing is successful, set it as the export url
        .setUrlForExport(pureshotOutputPath);

Algorithm File

Certain functions require algorithm files. These files can be found in the assets folder within the demo directory. Ensure the file paths match those in the demo.

Below is a table mapping function of their corresponding required algorithms:

Function Model File Path Description
Defringe defringe_lr_dynamic_e28c1212.ins defringe_hr_dynamic_7b56e80f.ins DFixed path: file:///android_assets/insta360/model/
Color Plus lut_7a79b17a_32.ins Fixed path: file:///android_assets/insta360/model/
PureShot Generation Pmdenoise_raw_plus.insraw_denoising_abeda57d.ins283fish.ilp283wide.ilp577.ilp586.ilpX3.ilp Developer custom path:Passed in by the StitchUtils.generatePureShot function

Error Code

Picture/Video Export Error Code

Error code Explanation
-31000 Exporting in progress
-31010 Stop exporting
-31011 Failed to load stabilization data
-31012 EXPORT_TERMINATED_BY_WORK_REFERENCE_RELEASABLE
-31016 EXPORT_POST_EXECUTE_FAILED
-31017 Original thumbnail LRV not found
-31018 Original thumbnail LRV loading failed
-31019 EXPORT_VIDEO_TO_IMAGE_SEQUENCE_CANCEL
-13016 Export timeout
-13017 Cancel export
-13018 SHADOW_EXPORT_INIT_SHADOW_CLONE_FAIL
-13019 SHADOW_EXPORT_PREPARE_EXPORT_INFO_FAIL
-13021 Failed to enable hardware encoding
-13022 SHADOW_EXPORT_FAIL_TARGET_TIME_NULL
-13023 SHADOW_EXPORT_PREPRARE_FRAME_EXPORTER_FAIL
-13024 SHADOW_EXPORT_INPUT_TARGET_FAIL
-13025 STOP_MOTION_SELECT_POSE_CLIP_NULL
-13026 STOP_MOTION_SELECT_CLIP_NOT_MATCH
-13027 STOP_MOTION_SELECT_LOAD_STABILIZER_FAIL
-13028 STOP_MOTION_SELECT_KEY_NULL
-13029 SHADOW_EXPORT_TRACK_TARGET_EMPTY
-13031 Frame exporter preparation failed
-13033 Reverse video parsing failed
-13034 Dual stream frame format is different
-13035 Thumbnail Stabilization Error
-13036 Video frame rate equals 0
-13038 Video width equals zero
-13039 Video height equals zero
-13040 The denoise model equals null.
-13041 Video source frame rate equals 0
-13042 Video source duration equals 0
-13043 Image Denoise File Transfer Error
-13034 Dual stream frame format is different
-13044 Failed to load AAA parameters
-13045 Failed to create denoise data
-13046 Image width equals 0
-13047 Image height equals 0

FAQ

Q1: What should I do if I cannot access the Internet when connecting to the camera?

This typically refers to establishing a connection with the camera via Wi-Fi. The app communicates with the camera through two methods: socket and HTTP. Below are the corresponding functions for each communication method:

  • Socket:Preview stream, read camera parameters, set camera parameters, read capture parameters, set capture parameters, etc. // TODO Supported features to be completed
  • Http Initialize the supported list, download camera files. // TODO Supported features to be completed

The root cause of this issue stems from calling ConnectivityManager#bindProcessToNetwork(network) when establishing a socket connection with the camera, which binds the current process to the camera's Wi-Fi network.

Therefore, after establishing a Wi-Fi connection, calling ConnectivityManager#bindProcessToNetwork(4GNetwork) to bind to an available network (such as 4G) resolves the inability to access the internet. Since the socket connection is already established, unbinding still allows continued use of socket-enabled features.

However, this approach introduces a problem. Because the current process is no longer bound to the camera's Wi-Fi, using features dependent on HTTP communication will result in the following error:

image

There are two solutions to this problem:

  1. When using features related to HTTP communication, call the bindProcessToNetwork(camera) method to bind to the camera's Wi-Fi. Upon completing the relevant functionality, call bindProcessToNetwork(4g) to switch back to the available 4G network.
    1. Pros: Simple implementation
    2. Cons: Will temporarily disconnect from the Internet.
  2. Launch a new process named download. Call the bindProcessToNetwork(camera) method to bind the download process to the camera's Wi-Fi network. All HTTP communication-related functions are executed within the download process.
    1. Pros: Perfectly solves the problem of being unable to access the Internet.
    2. Cons: Complex implementation

Q2: What is the data format in the VideoData object?

H.264 format, containing both PPS and SPS frame data.

Q3:How to resolve C++_shared conflicts?

Upgrade to version 1.8.1_build_05 or later

Q4:How to handle the issue regarding OK Go?

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:Connection error -2110203 issue?

Socket read failure typically occurs when Wi-Fi is disabled by the system. Manually reconnecting to Wi-Fi via the system settings page can reduce the likelihood of automatic disconnection by the system.

Q6:Regarding the issue of some Huawei phones displaying a black screen during playback?

The photo width is 16386 pixels, exceeding the 8192-pixel rendering limit on some Huawei phones.

About

Android SDK enables integration of Insta360 360 cameras into Android apps for control and media management.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 7