feat: 视频水印固定位置显示;允许截屏禁止录屏
This commit is contained in:
29
uni_modules/yb-screen-capture/index.d.ts
vendored
Normal file
29
uni_modules/yb-screen-capture/index.d.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
export type CaptureScreenSuccess = {
|
||||
/**
|
||||
* 截图结果,格式为 data URL:data:image/jpeg;base64,xxxx
|
||||
*/
|
||||
base64 : string
|
||||
}
|
||||
|
||||
export type CaptureScreenSuccessCallback = (res : CaptureScreenSuccess) => void
|
||||
|
||||
export type CaptureScreenFail = {
|
||||
errCode : number,
|
||||
errMsg : string
|
||||
}
|
||||
|
||||
export type CaptureScreenFailCallback = (res : CaptureScreenFail) => void
|
||||
|
||||
export type CaptureScreenCompleteCallback = (res : any) => void
|
||||
|
||||
export type CaptureScreenOptions = {
|
||||
success ?: CaptureScreenSuccessCallback,
|
||||
fail ?: CaptureScreenFailCallback,
|
||||
complete ?: CaptureScreenCompleteCallback
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取当前应用窗口画面(含视频等硬件加速渲染内容),通过 base64 返回。
|
||||
* 仅 App-Android 生效,基于 Android PixelCopy 实现。
|
||||
*/
|
||||
export declare const captureScreen : (options : CaptureScreenOptions) => void
|
||||
85
uni_modules/yb-screen-capture/package.json
Normal file
85
uni_modules/yb-screen-capture/package.json
Normal file
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"id": "yb-screen-capture",
|
||||
"displayName": "yb-screen-capture",
|
||||
"version": "1.0.0",
|
||||
"description": "截取当前应用窗口(含硬件加速渲染的视频画面),返回 base64",
|
||||
"keywords": [
|
||||
"截图",
|
||||
"截屏",
|
||||
"PixelCopy"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.7.7"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "uts",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "插件不采集任何数据",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y",
|
||||
"alipay": "n"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-android": "y",
|
||||
"app-ios": "n",
|
||||
"app-harmony": "n"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "n",
|
||||
"Android Browser": "n",
|
||||
"微信浏览器(Android)": "n",
|
||||
"QQ浏览器(Android)": "n"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "n",
|
||||
"IE": "n",
|
||||
"Edge": "n",
|
||||
"Firefox": "n",
|
||||
"Safari": "n"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "n",
|
||||
"阿里": "n",
|
||||
"百度": "n",
|
||||
"字节跳动": "n",
|
||||
"QQ": "n",
|
||||
"钉钉": "n",
|
||||
"快手": "n",
|
||||
"飞书": "n",
|
||||
"京东": "n"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "n",
|
||||
"联盟": "n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
uni_modules/yb-screen-capture/readme.md
Normal file
22
uni_modules/yb-screen-capture/readme.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# yb-screen-capture
|
||||
|
||||
截取当前应用窗口画面(含视频等硬件加速渲染内容),通过 base64 返回。
|
||||
|
||||
- 仅 **App-Android** 生效,基于 Android `PixelCopy` 实现(Android 8.0 及以上能正确截取视频画面;低于 8.0 降级为 View 截图,视频区域可能为黑屏)。
|
||||
- 截图范围为「当前屏幕可见区域」,不是长页面截图。
|
||||
|
||||
## 使用
|
||||
|
||||
```js
|
||||
uni.captureScreen({
|
||||
success: (res) => {
|
||||
// res.base64 形如:data:image/jpeg;base64,xxxx
|
||||
console.log(res.base64)
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(err.errCode, err.errMsg)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
> 注意:UTS 插件需要打自定义基座(标准基座无法运行)才能调试/运行。
|
||||
127
uni_modules/yb-screen-capture/utssdk/app-android/index.uts
Normal file
127
uni_modules/yb-screen-capture/utssdk/app-android/index.uts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { UTSAndroid } from "io.dcloud.uts";
|
||||
import PixelCopy from "android.view.PixelCopy";
|
||||
import OnPixelCopyFinishedListener from "android.view.PixelCopy.OnPixelCopyFinishedListener";
|
||||
import Bitmap from "android.graphics.Bitmap";
|
||||
import Canvas from "android.graphics.Canvas";
|
||||
import Handler from "android.os.Handler";
|
||||
import Looper from "android.os.Looper";
|
||||
import Build from "android.os.Build";
|
||||
import ByteArrayOutputStream from "java.io.ByteArrayOutputStream";
|
||||
import Base64 from "android.util.Base64";
|
||||
import {
|
||||
CaptureScreen,
|
||||
CaptureScreenOptions,
|
||||
CaptureScreenSuccess,
|
||||
CaptureScreenFail
|
||||
} from "../interface.uts";
|
||||
|
||||
/**
|
||||
* 将 Bitmap 压缩为 JPEG 并编码为 data URL 形式的 base64
|
||||
*/
|
||||
function encodeBitmapToBase64(bitmap : Bitmap) : string {
|
||||
const baos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
|
||||
const bytes = baos.toByteArray();
|
||||
const base64 = Base64.encodeToString(bytes, Base64.NO_WRAP);
|
||||
bitmap.recycle();
|
||||
return "data:image/jpeg;base64," + base64;
|
||||
}
|
||||
|
||||
/**
|
||||
* PixelCopy 完成监听器
|
||||
*/
|
||||
class PixelCopyListener extends OnPixelCopyFinishedListener {
|
||||
|
||||
private bitmap : Bitmap;
|
||||
private options : CaptureScreenOptions;
|
||||
|
||||
constructor(bitmap : Bitmap, options : CaptureScreenOptions) {
|
||||
super();
|
||||
this.bitmap = bitmap;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
override onPixelCopyFinished(copyResult : Int) : void {
|
||||
if (copyResult == PixelCopy.SUCCESS) {
|
||||
const base64 = encodeBitmapToBase64(this.bitmap);
|
||||
const res : CaptureScreenSuccess = { base64: base64 };
|
||||
this.options.success?.(res);
|
||||
this.options.complete?.(res);
|
||||
} else {
|
||||
this.bitmap.recycle();
|
||||
const res : CaptureScreenFail = {
|
||||
errCode: 12010,
|
||||
errMsg: "captureScreen:fail PixelCopy copyResult=" + copyResult
|
||||
};
|
||||
this.options.fail?.(res);
|
||||
this.options.complete?.(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 UI 线程执行实际截图
|
||||
*/
|
||||
class CaptureRunnable extends Runnable {
|
||||
|
||||
private options : CaptureScreenOptions;
|
||||
|
||||
constructor(options : CaptureScreenOptions) {
|
||||
super();
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
override run() : void {
|
||||
try {
|
||||
const activity = UTSAndroid.getUniActivity();
|
||||
if (activity == null) {
|
||||
const res : CaptureScreenFail = { errCode: 12010, errMsg: "captureScreen:fail activity is null" };
|
||||
this.options.fail?.(res);
|
||||
this.options.complete?.(res);
|
||||
return;
|
||||
}
|
||||
// 注意:UTS 中 getWindow() 返回可空类型,必须用 ! 断言,否则编译失败
|
||||
const window = activity!.getWindow()!;
|
||||
const decorView = window.getDecorView()!;
|
||||
const width = decorView.getWidth();
|
||||
const height = decorView.getHeight();
|
||||
if (width <= 0 || height <= 0) {
|
||||
const res : CaptureScreenFail = { errCode: 12010, errMsg: "captureScreen:fail invalid window size" };
|
||||
this.options.fail?.(res);
|
||||
this.options.complete?.(res);
|
||||
return;
|
||||
}
|
||||
|
||||
const bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Android 8.0+:使用 PixelCopy 可以正确截取 SurfaceView/视频等硬件加速画面
|
||||
const handler = new Handler(Looper.getMainLooper());
|
||||
PixelCopy.request(window, bitmap, new PixelCopyListener(bitmap, this.options), handler);
|
||||
} else {
|
||||
// 低版本降级:仅能截取 View 层级内容,视频区域可能为黑屏
|
||||
const canvas = new Canvas(bitmap);
|
||||
decorView.draw(canvas);
|
||||
const base64 = encodeBitmapToBase64(bitmap);
|
||||
const res : CaptureScreenSuccess = { base64: base64 };
|
||||
this.options.success?.(res);
|
||||
this.options.complete?.(res);
|
||||
}
|
||||
} catch (e) {
|
||||
const res : CaptureScreenFail = { errCode: 12010, errMsg: "captureScreen:fail " + e.toString() };
|
||||
this.options.fail?.(res);
|
||||
this.options.complete?.(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const captureScreen : CaptureScreen = function (options : CaptureScreenOptions) {
|
||||
const activity = UTSAndroid.getUniActivity();
|
||||
if (activity == null) {
|
||||
const res : CaptureScreenFail = { errCode: 12010, errMsg: "captureScreen:fail activity is null" };
|
||||
options.fail?.(res);
|
||||
options.complete?.(res);
|
||||
return;
|
||||
}
|
||||
activity!.runOnUiThread(new CaptureRunnable(options));
|
||||
}
|
||||
73
uni_modules/yb-screen-capture/utssdk/interface.uts
Normal file
73
uni_modules/yb-screen-capture/utssdk/interface.uts
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* uni.captureScreen 成功回调参数
|
||||
*/
|
||||
export type CaptureScreenSuccess = {
|
||||
/**
|
||||
* 截图结果,格式为 data URL:data:image/jpeg;base64,xxxx
|
||||
*/
|
||||
base64 : string
|
||||
}
|
||||
|
||||
/**
|
||||
* uni.captureScreen 成功回调函数定义
|
||||
*/
|
||||
export type CaptureScreenSuccessCallback = (res : CaptureScreenSuccess) => void
|
||||
|
||||
/**
|
||||
* uni.captureScreen 失败回调参数
|
||||
*/
|
||||
export type CaptureScreenFail = {
|
||||
errCode : number,
|
||||
errMsg : string
|
||||
}
|
||||
|
||||
/**
|
||||
* uni.captureScreen 失败回调函数定义
|
||||
*/
|
||||
export type CaptureScreenFailCallback = (res : CaptureScreenFail) => void
|
||||
|
||||
/**
|
||||
* uni.captureScreen 完成回调函数定义(成功、失败都会执行)
|
||||
*/
|
||||
export type CaptureScreenCompleteCallback = (res : any) => void
|
||||
|
||||
/**
|
||||
* uni.captureScreen 参数
|
||||
*/
|
||||
export type CaptureScreenOptions = {
|
||||
/**
|
||||
* 接口调用成功的回调函数
|
||||
*/
|
||||
success ?: CaptureScreenSuccessCallback,
|
||||
/**
|
||||
* 接口调用失败的回调函数
|
||||
*/
|
||||
fail ?: CaptureScreenFailCallback,
|
||||
/**
|
||||
* 接口调用结束的回调函数(调用成功、失败都会执行)
|
||||
*/
|
||||
complete ?: CaptureScreenCompleteCallback
|
||||
}
|
||||
|
||||
export type CaptureScreen = (options : CaptureScreenOptions) => void
|
||||
|
||||
export interface Uni {
|
||||
/**
|
||||
* 截取当前应用窗口画面(含视频等硬件加速渲染内容),通过 base64 返回。
|
||||
* 仅 App-Android 生效,基于 Android PixelCopy 实现。
|
||||
*
|
||||
* @param {CaptureScreenOptions} options
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "osVer": "8.0",
|
||||
* "uniVer": "3.7.7",
|
||||
* "unixVer": "3.9.0"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @uniVersion 3.7.7
|
||||
* @uniVueVersion 2,3
|
||||
*/
|
||||
captureScreen(options : CaptureScreenOptions) : void
|
||||
}
|
||||
Reference in New Issue
Block a user