Hi, I recently bought a new Insta360 X3 camera and signed up for the SDK. We were able to utilize the Android SDK without any issues but in iOS SDK when we want to see the camera preview, the app freezes after a few seconds. This is the code that we are currently using.
import UIKit
import INSCameraSDK
class Insta360Controller: UIViewController, INSCameraPreviewPlayerDelegate {
private var mediaSession:INSCameraMediaSession?
private var previewPlayer:INSCameraPreviewPlayer?
private var videoEncode:INSVideoEncode?
override func viewDidLoad() {
super.viewDidLoad()
videoEncode = INSVideoEncode.H264
mediaSession = INSCameraMediaSession()
//Set Navigation bar title
title = "Camera preview"
//Setup INSCamera socket
INSCameraManager.socket().setup()
//Start sending heartbeats to camera to maintain connection
INSCameraManager.socket().commandManager.sendHeartbeats(with: nil)
//Setup INSCamera socket for camera state monitoring
INSCameraManager.socket().addObserver(self, forKeyPath: "cameraState", options: .new, context: nil)
//Setup preview player view
setupCameraPreviewView()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if(INSCameraManager.shared().currentCamera != nil) {
weak var weakSelf = self
weakSelf?.updateConfiguration()
weakSelf?.runMediaSession()
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
INSCameraManager.socket().shutdown()
}
//Setup camera preview player view
private func setupCameraPreviewView(){
let frame = CGRect(x:0,y:0,width: view.bounds.width,height: view.bounds.height)
previewPlayer = INSCameraPreviewPlayer(frame: frame, renderType: INSRenderType.sphericalPanoRender)
previewPlayer?.play(withGyroTimestampAdjust: 30.0)
previewPlayer?.delegate = self
view.addSubview(previewPlayer!.renderView)
mediaSession?.plug(previewPlayer!)
//Adjust field of view params
let offset = INSCameraManager.shared().currentCamera?.settings?.mediaOffset
if (offset != nil) {
let rawValue = INSLensOffset(offset: offset!).lensType
if rawValue == INSLensType.oneX2.rawValue ||
rawValue == INSLensType.oneR577Wide.rawValue ||
rawValue == INSLensType.oneR283Wide.rawValue {
previewPlayer?.renderView.enablePanGesture = false
previewPlayer?.renderView.enablePinchGesture = false
previewPlayer?.renderView.render.camera?.xFov = 37
previewPlayer?.renderView.render.camera?.distance = 700
}
}
}
//Run media session for camera preview and plug streaming video into preview player
private func runMediaSession() {
guard INSCameraManager.shared().cameraState == INSCameraState.connected else { return }
guard let mediaSession else { return }
weak var weakSelf = self
if mediaSession.running {
view.isUserInteractionEnabled = false
mediaSession.commitChanges() { error in
if let error {
print("###commitChanges media session with error: \(error)")
}
weakSelf?.view.isUserInteractionEnabled = true
if let error {
print("###commitChanges media failed", error.localizedDescription)
}
}
} else {
view.isUserInteractionEnabled = false
mediaSession.startRunning() { error in
if let error {
print("###start running media session with error: \(error)")
}
weakSelf?.view.isUserInteractionEnabled = true
if error != nil {
weakSelf!.previewPlayer!.play(withSmoothBuffer: false)
}
}
}
}
//Update media session configuration
func updateConfiguration() {
// main stream resolution
mediaSession?.expectedVideoResolution = INSVideoResolution1920x960x30
// secondary stream resolution
mediaSession?.expectedVideoResolutionSecondary = INSVideoResolution960x480x30
// use main stream or secondary stream to preview
mediaSession?.previewStreamType = INSPreviewStreamType.main
// audio sample rate
mediaSession?.expectedAudioSampleRate = INSAudioSampleRate.rate48000Hz
// preview stream encode
mediaSession?.videoStreamEncode = INSVideoEncode.H264
// gyroscope correction mode
// If you are in panoramic preview, use `INSGyroPlayModeDefault`.
// If you are in wide angle preview, use `INSGyroPlayModeFootageMotionSmooth`.
mediaSession?.gyroPlayMode = INSGyroPlayMode.normal
mediaSession?.expectedVideoResolution = .init(width: Int(view.frame.width), height: Int(view.frame.height), fps: 30)
}
//Start media session as soon as camera is connected
private func startSendingHeartbeats() {
runMediaSession()
}
//Stop media session as soon as camera is disconnected
private func stopSendingHeartbeats() {
mediaSession?.stopRunning(completion: nil)
}
//Camera state observer
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if !(object is INSCameraManager) {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
if keyPath == "cameraState" {
let state = INSCameraState(rawValue: (change?[NSKeyValueChangeKey.newKey] as? NSNumber)?.uintValue ?? 0)
switch state {
case .found:
print("Found")
case .connected:
print("Camera connected successfully")
startSendingHeartbeats()
case .connectFailed:
print("Failed to connect to camera")
stopSendingHeartbeats()
default:
stopSendingHeartbeats()
}
}
}
//Convert (photo or video) resource uri to http url via http tunnel and Wi-Fi socket
func INSHTTPURLForResourceURI(_ uri: String) -> URL? {
URL(string: uri)
}
//Convert local http url to (photo or video) resource uri
func INSResourceURIFromHTTPURL(_ url: URL) -> String? {
nil
}
deinit {
mediaSession?.stopRunning() { error in
if let error {
print("stop media session with err: \(error)")
}
}
INSCameraManager.socket().removeObserver(self, forKeyPath: "cameraState")
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
This message gets printed in the console after a few seconds
INSStitchTypeNone!
Hi, I recently bought a new Insta360 X3 camera and signed up for the SDK. We were able to utilize the Android SDK without any issues but in iOS SDK when we want to see the camera preview, the app freezes after a few seconds. This is the code that we are currently using.
}
This message gets printed in the console after a few seconds INSStitchTypeNone!
Please help.