Live Video Streaming

Last Updated on : 2023-05-22 06:38:31download

Tuya IPC SDK for iOS provides basic IP camera (IPC) capabilities, such as live video streaming, playing back footage on an SD card, video screenshots, video recording, and real-time talk with IPCs. YUV data is available after video frames are decoded. You can further process video data based on the YUV data.

After the TuyaSmartCameraType instance object is created, live video streaming can be started. Video data transmission and command interaction are implemented through peer-to-peer (P2P) connections.

P2P connections

Before live video streaming, a P2P connection must be created. The P2P connection status is subject to your maintenance. The IPC SDK can only send commands to and receive responses from IPCs.

API description

To create a P2P connection, you can prioritize connections over a local area network (LAN) or the internet. When LAN connections are prioritized, if TCP connections are not created between the app and an IPC over the same LAN, or the IPC does not support prioritized LAN connections, the SDK automatically selects connections over the internet.

- (void)connectWithMode:(TuyaSmartCameraConnectMode)mode;

Parameters

Parameter Description
mode The prioritized connection mode.

TuyaSmartCameraConnectMode

Enum value Description
TuyaSmartCameraConnectAuto Automatic selection
TuyaSmartCameraConnectFromInternet Internet connections prioritized
TuyaSmartCameraConnectFromLocal LAN connections prioritized

API description

Closes a P2P connection.

- (void)disConnect;

Delegate callback

Indicates that a P2P connection is created.

- (void)cameraDidConnected:(id<TuyaSmartCameraType>)camera;

Indicates that a P2P connection is closed. This method is called only in the case of a passive disconnection. For example, the connection is closed in poor network conditions or the IPC stops the connection.

- (void)cameraDisconnected:(id<TuyaSmartCameraType>)camera;

The CONNECT method might cause thread blocking. We recommend that you call it in child threads.

Live video streaming

After a P2P connection is created, live video streaming can be started.

API description

Starts live video streaming.

- (void)startPreview;

Starts live video streaming with specified definition. This API method is not supported by P2P 1.0 devices.

- (void)startPreviewWithDefinition:(TuyaSmartCameraDefinition)definition;

Stops live video streaming.

- (void)stopPreview;

Returns a video rendering view.

- (UIView<TuyaSmartVideoViewType> *)videoView;

Delegate callback

Indicates that live video streaming is started.

- (void)cameraDidBeginPreview:(id<TuyaSmartCameraType>)camera;

Indicates that live video streaming is stopped.

- (void)cameraDidStopPreview:(id<TuyaSmartCameraType>)camera;

Video rendering

After live video streaming is started, the IPC SDK automatically renders the received video streams. You can call the method - (UIView<TuyaSmartVideoViewType> *)videoView of the camera object to get the rendering view. Then, you can add the view to the video screen and set the layout properties.

Protocol description

Protocol name Description
TuyaSmartVideoViewType The video renderer protocol. The video rendering implementation varies depending on different IPC implementation solutions.

API description

The image zoom properties. Default value: NO. In this case, if the aspect ratio of the view is different from that of the video image, black bars will appear on the top and bottom or left and right of the image. If the value is set to YES, the image will stretch to fill the entire view and might cause image distortion.

@property (nonatomic, assign) BOOL scaleToFill;

Sets the image zoom ratio.

- (void)tuya_setScaled:(float)scaled;

Sets the image offset.

- (void)tuya_setOffset:(CGPoint)offset;

Clears the current image and cached video frames.

- (void)tuya_clear;

Captures a screenshot of the current rendered image.

- (UIImage *)screenshot;

The TuyaSmartCameraType object provides the autoRender property. Default value: YES. The value allows the IPC SDK to automatically render video images. To disable automatic rendering, you can set the value to NO, call the delegate method to get the YUV data of each video frame, and then develop your preferred video rendering solution. For more information about the required method, see Raw stream data.

Full-screen playing

The IPC SDK does not support full-screen playing. To enable full-screen playing, you can modify the layout of the video rendering view. To allow the video image to fill the entire view, set the scaleToFill property to YES. However, this setting might cause image distortion. In full-screen mode, switching between the portrait and landscape screens and the layout changes are subject to your maintenance.

Flowchart

Live Video Streaming

Failure callback

The IPC delegate provides the callback to return the error messages that have occurred during IPC operations.

API description

Provides the callback of IPC error messages.

- (void)camera:(id<TuyaSmartCameraType>)camera didOccurredErrorAtStep:(TYCameraErrorCode)errStepCode specificErrorCode:(NSInteger)errorCode;

Parameters

Parameter Description
camera The IPC object that causes an error.
errStepCode The operation in which the error has occurred.
errorCode The error code that indicates the cause of the error.

Enum values of TYCameraErrorCode

Enum value Description
TY_ERROR_NONE None.
TY_ERROR_CONNECT_FAILED Failed to create a P2P connection.
TY_ERROR_START_PREVIEW_FAILED Failed to stream live videos.
TY_ERROR_START_PLAYBACK_FAILED Failed to play back footage on an SD card.
TY_ERROR_PAUSE_PLAYBACK_FAILED Failed to pause playback of footage on an SD card.
TY_ERROR_RESUME_PLAYBACK_FAILED Failed to resume playback of footage on an SD card.
TY_ERROR_ENABLE_MUTE_FAILED Failed to enable or disable the audio channel.
TY_ERROR_START_TALK_FAILED Failed to enable the video talk feature.
TY_ERROR_RECORD_FAILED Failed to record videos.
TY_ERROR_ENABLE_HD_FAILED Failed to set video definition.
TY_ERROR_GET_HD_FAILED Failed to get video definition.
TY_ERROR_QUERY_RECORD_DAY_FAILED Failed to query the date of footage on an SD card.
TY_ERROR_QUERY_TIMESLICE_FAILED Failed to query footage on an SD card.

For more information about errorCode, see Error Code.

Example

ObjC

#define kTuyaSmartIPCConfigAPI @"tuya.m.ipc.config.get"
#define kTuyaSmartIPCConfigAPIVersion @"2.0"

- (void)startStream {
	if (self.connected) {
		[self.camera startPreview];
		return;
	}
	id p2pType = [self.deviceModel.skills objectForKey:@"p2pType"];
	[[TuyaSmartRequest new] requestWithApiName:kTuyaSmartIPCConfigAPI postData:@{@"devId": self.devId} version:kTuyaSmartIPCConfigAPIVersion success:^(id result) {
		dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
			TuyaSmartCameraConfig *config = [TuyaSmartCameraFactory ipcConfigWithUid:[TuyaSmartUser sharedInstance].uid localKey:self.deviceModel.localKey configData:result];
			self.camera = [TuyaSmartCameraFactory cameraWithP2PType:p2pType config:config delegate:self];
			[self.camera connect];
		});
	} failure:^(NSError *error) {
				// Failed to get the configurations.
	}];
}

#pragma mark - TuyaSmartCameraDelegate

- (void)cameraDidConnected:(id<TuyaSmartCameraType>)camera {
	self.connected = YES;
	// Starts previewing only after a P2P connection is created.
		[camera startPreview];
}

- (void)cameraDisconnected:(id<TuyaSmartCameraType>)camera {
	// A P2P connection is closed due to unstable network conditions.
	self.connected = NO;
	self.previewing = NO;
}

- (void)cameraDidBeginPreview:(id<TuyaSmartCameraType>)camera {
		// Starts live video streaming.
	self.previewing = YES;
	// Adds a rendered video view to a video screen.
		[self.view addSubview:camera.videoView];
}

- (void)cameraDidStopPreview:(id<TuyaSmartCameraType>)camera {
		// Stops live video streaming.
	self.previewing = NO;
}

// The failure callback.
- (void)camera:(id<TuyaSmartCameraType>)camera didOccurredErrorAtStep:(TYCameraErrorCode)errStepCode specificErrorCode:(NSInteger)errorCode {
		if (errStepCode == TY_ERROR_CONNECT_FAILED) {
		// Failed to create a P2P connection.
		self.connected = NO;
	}
	else if (errStepCode == TY_ERROR_START_PREVIEW_FAILED) {
		// Failed to stream live videos.
		self.previewing = NO;
	}
}

Swift

func startStream() {
	if self.isConnected {
		self.camera.startPreview()
		return
	}
	let p2pType = self.deviceModel.skills["p2pType"]!
	TuyaSmartRequest().request(withApiName: kTuyaSmartIPCConfigAPI, postData: ["devId": self.devId], version: kTuyaSmartIPCConfigAPIVersion, success: { result in
		guard let responder = result as? [AnyHashable:Any] else {
			return;
		}
		DispatchQueue.global().async {
			let config = TuyaSmartCameraFactory.ipcConfig(withUid: TuyaSmartUser.sharedInstance().uid, localKey: self.deviceModel.localKey, configData: responder)
			self.camera = TuyaSmartCameraFactory.camera(withP2PType: p2pType, config: config, delegate: self)
			self.camera.connect()
		}
	}) { _ in
		// Failed to get the configurations.
	}
}

func cameraDidConnected(_ camera: TuyaSmartCameraType!) {
	self.isConnected = true
	// Starts previewing only after a P2P connection is created.
	camera.startPreview()
}

func cameraDisconnected(_ camera: TuyaSmartCameraType!) {
	// A P2P connection is closed due to unstable network conditions.
	self.isConnected = false
	self.isPreviewing = false
}

func cameraDidBeginPreview(_ camera: TuyaSmartCameraType!) {
	// Starts live video streaming.
	self.isPreviewing = true;
	// Adds a rendered video view to a video screen.
	self.view.addSubview(camera.videoView())
}

func cameraDidStopPreview(_ camera: TuyaSmartCameraType!) {
	// Stops live video streaming.
	self.isPreviewing = false
}

func camera(_ camera: TuyaSmartCameraType!, didOccurredErrorAtStep errStepCode: TYCameraErrorCode, specificErrorCode errorCode: Int) {
	if errStepCode == TY_ERROR_CONNECT_FAILED  {
		// Failed to create a P2P connection.
		self.isConnected = false
	}else if errStepCode == TY_ERROR_START_PREVIEW_FAILED {
		// Failed to stream live videos.
		self.isPreviewing = false
	}
}

After the app runs in the background, video streaming must be stopped. Then, video data is processed with hardware decoding and Open Graphics Library (OpenGL) rendering. Otherwise, video streaming with the app running in the background might cause the app to crash. In most cases, each Tuya-powered IPC supports up to five concurrent P2P connections with five mobile phones. We recommend that the app closes the P2P connections after running in the background for a certain period to release resources.