1. Camera Features
Camera SDK provides live video of smart cameras, device memory card video playback, screenshots, recorded videos, and real-time calls with cameras. It also provides YUV data after video frame decoding. Developers can Perform secondary processing on the video data.
1.1. Live video
After creating the TuyaSmartCameraType
instance object, you can start playing live video. Video data transmission and command interaction are based on p2p channels.
1.1.1. P2P connection
Before start playing the video, you need to connect the p2p channel. The connection status of p2p needs to be maintained by the developer. The SDK is only responsible for publish commands and receiving camera response results.
Declaration
Start connecting p2p channels.
- (void)connect;
Declaration
Disconnect p2p channel.
- (void)disConnect;
Delegate Declaration
p2p channel successfully connected.
- (void)cameraDidConnected: (id <TuyaSmartCameraType>) camera;
Delegate Declaration
The p2p channel is disconnected and will only be called when it is passively disconnected, such as a poor network environment or the device actively disconnects.
- (void)cameraDisconnected: (id <TuyaSmartCameraType>) camera;
The connect method may block the thread. It is recommended to call it from a child thread.
1.1.2. Live video
After the p2p channel is successfully connected, you can start playing live video.
Declaration
Start playing live video.
- (void)startPreview;
Declaration
Stop playing live video.
- (void)stopPreview;
Declaration
Get video render view.
- (UIView<TuyaSmartVideoViewType> *)videoView;
Delegate Declaration
The live video has started successfully.
- (void)cameraDidBeginPreview: (id <TuyaSmartCameraType>) camera;
Delegate Declaration
The live video has successfully stopped playing.
- (void)cameraDidStopPreview: (id <TuyaSmartCameraType>) camera;
1.1.3. Video rendering
After the video is successfully played, the SDK receives the video stream and it will be automatically rendered. Developers can use the camera object's - (UIView<TuyaSmartVideoViewType> *)videoView
method to get the rendered view, add it to the screen, and set the layout properties.
Protocol
Protocol | Description |
---|---|
TuyaSmartVideoViewType | Video renderer protocol, depending on the camera implementation, the specific implementation of video rendering is also different |
Declaration
Image scaling properties. The default is NO
. If the aspect ratio of the view is different from the aspect ratio of the video image, there will be black borders on the top, bottom, or left and right sides of the image. Set to YES
, the image will stretch to cover the entire view, which may cause image distortion.
@property (nonatomic, assign) BOOL scaleToFill;
Declaration
Set image scaling.
- (void)tuya_setScaled:(float)scaled;
Declaration
Set image offset.
- (void)tuya_setOffset:(CGPoint)offset;
Declaration
Clear current image and cached video frames.
- (void)tuya_clear;
Declaration
Screenshot of the currently rendered image.
- (UIImage *)screenshot;
The
TuyaSmartCameraType
object also provides anautoRender
property, which defaults toYES
, and the SDK will automatically render the video image. If the developer does not want the SDK to automatically render the video, this property can be set toNO
, and then the YUV data of each frame of video can be obtained from the delegate method, and the video rendering is developed independently. Refer to Original video data .
Full screen
The SDK does not provide full-screen playback capabilities. Full-screen playback only needs to modify the layout of the video rendering view. If you need the video image to fill the view, you can set the scaleToFill
property to YES, but the image may be stretched and deformed . In full-screen mode, the rotation of the horizontal and vertical screens and the layout changes need to be maintained by the developer.
1.1.4. Flow chart
1.1.5. Error callback
All error feedback of camera operation will be called back by delegate method.
Declaration
Camera operation failed callback.
- (void)camera:(id<TuyaSmartCameraType>)camera didOccurredErrorAtStep:(TYCameraErrorCode)errStepCode specificErrorCode:(NSInteger)errorCode;
Parameters
Parameter | Description |
---|---|
camera | The camera object where the error occurred |
errStepCode | Error operation |
errorCode | Error code, indicating the reason for the failure |
enum TYCameraErrorCode
Value | Description |
---|---|
TY_ERROR_NONE | None |
TY_ERROR_CONNECT_FAILED | P2p connection failed |
TY_ERROR_START_PREVIEW_FAILED | Live video play failed |
TY_ERROR_START_PLAYBACK_FAILED | Memory card video playback failed |
TY_ERROR_PAUSE_PLAYBACK_FAILED | Failed to pause video playback |
TY_ERROR_RESUME_PLAYBACK_FAILED | Failed to resume video playback |
TY_ERROR_ENABLE_MUTE_FAILED | Video sound switch failed |
TY_ERROR_START_TALK_FAILED | Talk failed |
TY_ERROR_RECORD_FAILED | Video recording failed |
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 | Memory card video playback date query failed |
TY_ERROR_QUERY_TIMESLICE_FAILED | Memory card video clip query failed |
The meaning of errorCode
can refer to the 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 configuration information
}];
}
#pragma mark - TuyaSmartCameraDelegate
- (void)cameraDidConnected:(id<TuyaSmartCameraType>)camera {
self.connected = YES;
[camera startPreview];
}
- (void)cameraDisconnected:(id<TuyaSmartCameraType>)camera {
self.connected = NO;
self.previewing = NO;
}
- (void)cameraDidBeginPreview:(id<TuyaSmartCameraType>)camera {
self.previewing = YES;
[self.view addSubview:camera.videoView];
}
- (void)cameraDidStopPreview:(id<TuyaSmartCameraType>)camera {
self.previewing = NO;
}
- (void)camera:(id<TuyaSmartCameraType>)camera didOccurredErrorAtStep:(TYCameraErrorCode)errStepCode specificErrorCode:(NSInteger)errorCode {
if (errStepCode == TY_ERROR_CONNECT_FAILED) {
// p2p connect failed
self.connected = NO;
}
else if (errStepCode == TY_ERROR_START_PREVIEW_FAILED) {
// live video play failed
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 configuration information
}
}
func cameraDidConnected(_ camera: TuyaSmartCameraType!) {
self.isConnected = true
camera.startPreview()
}
func cameraDisconnected(_ camera: TuyaSmartCameraType!) {
self.isConnected = false
self.isPreviewing = false
}
func cameraDidBeginPreview(_ camera: TuyaSmartCameraType!) {
self.isPreviewing = true;
self.view.addSubview(camera.videoView())
}
func cameraDidStopPreview(_ camera: TuyaSmartCameraType!) {
self.isPreviewing = false
}
func camera(_ camera: TuyaSmartCameraType!, didOccurredErrorAtStep errStepCode: TYCameraErrorCode, specificErrorCode errorCode: Int) {
if errStepCode == TY_ERROR_CONNECT_FAILED {
// p2p connect failed
self.isConnected = false
}else if errStepCode == TY_ERROR_START_PREVIEW_FAILED {
// live video play failed
self.isPreviewing = false
}
}
When the app enters the background, it is necessary to stop the video playback. The video data uses hardware decoding and OpenGL rendering. When the app is in the background and continues to play, the app may crash. In addition, Tuya smart cameras generally support a maximum of 5 p2p channels (that is, 5 mobile phones can be connected at the same time). It is recommended that the app actively disconnect the p2p connection after a period of time in the background to release resources.