本文介绍如何借助无影云手机的SDK来操控缩略图。
池化使用缩略图
说明
建议使用池化的方式来管理和复用缩略图。关于具体的实现方法,请参见各SDK的Demo。
Android SDK
final WeakReference<ViewHolder> weakHolder = new WeakReference<>(holder);
CloudPhonePool.getInstance().requestThumbnail(mContext, phone, new ThumbnailCallback() {
@Override
public void onFinished(CloudPhone phone, Bitmap bitmap, int errorCode) {
if (errorCode != 0) {
return;
}
ViewHolder currentHolder = weakHolder.get();
if (currentHolder != null) {
currentHolder.ivThumbnail.setImageBitmap(bitmap);
}
}
});
Web SDK
function requestThumbnail(params, callback) {
if (!params.appInstanceId) {
console.log(`Thumbnail params appInstanceId is null`);
if (callback) callback(params, null, -1);
return;
}
if (thumbnailSDKMap.has(params.appInstanceId)) {
console.log(`Thumbnail ${params.appInstanceId} reuse`);
var item = thumbnailSDKMap.get(params.appInstanceId);
if (item.canReuse()) {
item.callback = callback;
return;
} else {
item.stopThumbnail();
thumbnailSDKMap.delete(params.appInstanceId);
}
}
console.log(`Thumbnail ${params.appInstanceId} new`);
var item = new WYThumbnailImg(params, callback);
thumbnailSDKMap.set(params.appInstanceId, item);
}
iOS SDK
__weak typeof(cell) weakCell = cell;
[[ASPCloudPhonePool sharedInstance] requestThumbnail:engineItem completion:^(ASPCloudPhoneEngineItem *engineItem, UIImage *image, NSInteger errorCode) {
weakCell.imageView.image = image;
}];
创建缩略图对象
Android SDK
public CloudPhoneEngine getCloudPhoneEngine(CloudPhone phone, Context context) {
IASPEngineListener mListener = new IASPEngineListener() {
@Override
public void onConnectionSuccess(int connectionId) {
Log.i(TAG, "onConnectionSuccess " + phone.getName());
}
@Override
public void onConnectionFailure(int errorCode, String errorMsg) {
Log.i(TAG, "onConnectionFailure errorCode:" + errorCode + " errorMsg:" + errorMsg + "," + phone.getName());
String s = String.format("%s 错误码:%d", errorMsg, errorCode);
showError(s);
}
@Override
public void onEngineError(int errorCode, String errorMsg) {
Log.i(TAG, "onEngineError errorCode:" + errorCode + " errorMsg:" + errorMsg + "," + phone.getName());
String s = String.format("%s 错误码:%d", errorMsg, errorCode);
showError(s);
}
@Override
public void onDisconnected(int reason) {
Log.i(TAG, "onDisconnected reason=" + reason + "," + phone.getName());
}
@Override
public void onReconnect(int errorCode) {
Log.i(TAG, "onReconnect: " + errorCode + "," + phone.getName());
}
@Override
public void onFirstFrameRendered(long timeCostMS) {
Log.i(TAG, "onFirstFrameRendered " + phone.getName());
}
@Override
public void onPolicyUpdate(String policy) {
Log.i(TAG, "policy=" + policy);
}
@Override
public void onSessionSuccess() {
Log.i(TAG, "onSessionSuccess " + phone.getName());
}
@Override
public void onDisposed() {
Log.i(TAG, "onDisposed");
}
};
Bundle bundle = new Bundle();
// 物理会议ID,以ai-开头。
bundle.putString(CloudPhoneEngine.CONFIG_INSTANCEID, phone.getId());
bundle.putString(CloudPhoneEngine.CONFIG_TICKET, phone.getTicket());
bundle.putBoolean(CloudPhoneEngine.CONFIG_ENABLE_THUMBNAIL, true);
bundle.putInt(CloudPhoneEngine.CONFIG_ENABLE_THUMBNAIL_WIDTH, 200);
bundle.putInt(CloudPhoneEngine.CONFIG_ENABLE_THUMBNAIL_HEIGHT, 360);
CloudPhoneEngine engine = new CloudPhoneEngine();
engine.prepare(bundle, context);
engine.getASPEngine().registerASPEngineListener(mListener);
return engine;
}
Web SDK
说明
推荐通过获取缩略图的src
来显示缩略图。创建缩略图时,需指定onThumbnailData
回调。
const containerId = `thumbnail_${index}`;//每个缩略图必须保持唯一
const div = document.createElement("div");
div.id = containerId;
div.style.width = "200px"; // 固定宽度
div.style.height = "360px"; // 固定高度
div.style.border = "1px solid #ccc"; // (可选)边框
try {
var thumbnail = new window.Wuying.ThumbnailSDK({
appInstanceId: data.appInstanceId,//物理会话ID 以ai-开头
ticket: data.ticket,
containerId: containerId,
defaultConfig: { width: 200, height: 360, fps: 1 }
}, {
onConnected: (data) => {
console.log(`Thumbnail ${index} connected`, data);
},
onDisConnected: (data) => {
console.log(`Thumbnail ${index} disconnected`, data);
},
onThumbnailData: (url) => {
console.log(`Thumbnail ${index} url:`, url);
img.src = url
}
});
} catch (error) {
console.error(`Failed to initialize SDK for ${containerId}:`, error);
}
iOS SDK
ASPCloudPhoneEngine *engine = [[ASPCloudPhoneEngine alloc] init];
engine.engineDelegate = self;
engine.thumbnailDelegate = self;
启动缩略图
Android SDK
CloudPhoneEngine engine = getCloudPhoneEngine(phone, mContext);
engine.start();
iOS SDK
ASPCloudPhoneEngineItem *engineItem = [[ASPCloudPhoneEngineItem alloc] init];
engineItem.ticket = tciket;
engineItem.instanceId = instanceId; //以ai-开头
engineItem.isThumbnail = YES;
engineItem.thumbnailSize = CGSizeMake(200, 360);
[engine start:engineItem];
监听缩略图数据回调
Android SDK
engine.unregisterThumbnailListener();
// 使用弱引用包裹 ViewHolder,避免内存泄漏。
final WeakReference<ViewHolder> weakHolder = new WeakReference<>(holder);
engine.registerThumbnailListener(new IThumbnailListener() {
@Override
public void onThumbnailUpdate(byte[] rgba, int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(ByteBuffer.wrap(rgba));
// 通过弱引用安全获取 ViewHolder。
ViewHolder currentHolder = weakHolder.get();
if (currentHolder != null) {
// 直接在主线程更新 UI(假设 onThumbnailUpdate 在非主线程调用)。
((Activity) currentHolder.itemView.getContext()).runOnUiThread(() -> {
currentHolder.ivThumbnail.setImageBitmap(bitmap);
});
}
}
});
iOS SDK
#pragma mark - ASPThumbnailDelegate
- (void)onThumbnailUpdate:(void*)buffer width:(uint32_t)width height:(uint32_t)height {
if (buffer && width > 0 && height > 0) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(buffer, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
self.bitmap = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof (weakSelf) strongSelf = weakSelf;
if (strongSelf.completion) strongSelf.completion(strongSelf.engineItem, strongSelf.bitmap, 0);
});
} else {
NSLog(@"onThumbnailUpdate error");
}
}
停止和释放缩略图
Android SDK
engine.dispose();
Web SDK
thumbnail.session.stop();
iOS SDK
- (void)stopThumbnail {
if (self.engine) {
self.engine.thumbnailDelegate = nil;
[self.engine dispose];
self.engine.engineDelegate = nil;
self.engine = nil;
}
}
相关文档
该文章对您有帮助吗?