前言
经过查询资料得出:微信小程序对于屏幕相关的API不同的操作系统支持程度是不一样的。因此 Android 和 iOS 需采用不同的方案来实现禁止录屏的方案
Android
/**
* 安卓系统禁止录屏处理函数
* @param toggle 是否禁止录屏
*/
function disableAndroidSys(toggle: boolean) {
if (Taro.setVisualEffectOnCapture) {
const visualEffect = toggle ? 'hidden' : 'none';
Taro.setVisualEffectOnCapture({ visualEffect });
}
}
iOS
/**
* 苹果系统禁止录屏处理函数
* @param toggle 是否禁止录屏
*/
function disableIOSSys(toggle: boolean) {
if (toggle) {
// 从其他页面开始录屏切换到播放页
handleIOSDSRFromOtherPage();
// 在播放页面开始录屏
handleIOSDSRFromCurrentPage();
} else {
// 取消相关的监听事件
Taro.offScreenRecordingStateChanged(changeHandler);
}
}
/**
* 当前页面防止ios录频
*/
function handleIOSDSRFromCurrentPage() {
if (Taro.onScreenRecordingStateChanged) {
Taro.onScreenRecordingStateChanged(changeHandler);
}
}
/**
* 跨屏幕防止ios录频
*/
function handleIOSDSRFromOtherPage() {
if (Taro.getScreenRecordingState) {
Taro.getScreenRecordingState({
success: res => {
// res.state: on(正在录屏) | off(没有开始录屏)
// 此处只需处理正在录屏的情况
// @ts-ignore
if (res.state === 'on') {
setIosWatermarkingState(true);
}
}
});
}
}
/**
* 屏幕录制状态变化监听函数
*/
function changeHandler(res: any) {
// res.state: start(开始录屏) | stop(结束录屏)
// @ts-ignore
if (res.state === 'start') {
// 展示水印弹窗
setIosWatermarkingState(true);
} else {
// 隐藏水印弹窗
setIosWatermarkingState(false);
}
}
完整代码
将禁止屏幕录制功能封装成了一个hook,这样可以实现比较高效地逻辑复用。
// useDisableScreenRecording.tsx
import Taro from '@tarojs/taro';
import { useState } from 'react';
import { Watermarking } from '@/modules/watermarking';
export const useDisableScreenRecording = () => {
const [iosWatermarkingState, setIosWatermarkingState] = useState(false);
/**
* 禁止录屏处理函数
* @param toggle 是否禁止录屏
*/
function disableScreenRecording(toggle: boolean) {
if (isIOSSystem()) {
disableIOSSys(toggle);
} else {
disableAndroidSys(toggle);
}
}
/**
* 判断系统是否为Ios
*/
function isIOSSystem(): boolean {
return /ios/i.test(Taro.getSystemInfoSync().system);
}
/**
* 安卓系统禁止录屏处理函数
* @param toggle 是否禁止录屏
*/
function disableAndroidSys(toggle: boolean) {
if (Taro.setVisualEffectOnCapture) {
const visualEffect = toggle ? 'hidden' : 'none';
Taro.setVisualEffectOnCapture({ visualEffect });
}
}
/**
* 苹果系统禁止录屏处理函数
* @param toggle 是否禁止录屏
*/
function disableIOSSys(toggle: boolean) {
if (toggle) {
// 从其他页面开始录屏切换到播放页
handleIOSDSRFromOtherPage();
// 在播放页面开始录屏
handleIOSDSRFromCurrentPage();
} else {
// 取消相关的监听事件
Taro.offScreenRecordingStateChanged(changeHandler);
}
}
/**
* 当前页面防止ios录频
*/
function handleIOSDSRFromCurrentPage() {
if (Taro.onScreenRecordingStateChanged) {
Taro.onScreenRecordingStateChanged(changeHandler);
}
}
/**
* 跨屏幕防止ios录频
*/
function handleIOSDSRFromOtherPage() {
if (Taro.getScreenRecordingState) {
Taro.getScreenRecordingState({
success: res => {
// res.state: on(正在录屏) | off(没有开始录屏)
// 此处只需处理正在录屏的情况
// @ts-ignore
if (res.state === 'on') {
setIosWatermarkingState(true);
}
}
});
}
}
/**
* 屏幕录制状态变化监听函数
*/
function changeHandler(res: any) {
// res.state: start(开始录屏) | stop(结束录屏)
// @ts-ignore
if (res.state === 'start') {
// 展示水印弹窗
setIosWatermarkingState(true);
} else {
// 隐藏水印弹窗
setIosWatermarkingState(false);
}
}
function IosWatermarking() {
return iosWatermarkingState ? <Watermarking /> : null;
}
return { IosWatermarking, disableScreenRecording };
};
下面是使用示例
// page/xxxx/index.tsx
import { View } from '@tarojs/components';
import { useDidHide, useDidShow } from '@tarojs/taro';
import { useDisableScreenRecording } from '@/hooks/useDisableScreenRecording';
import './index.scss';
export default function Play() {
const { IOSWatermarking, disableScreenRecording } = useDisableScreenRecording();
useDidShow(() => {
disableScreenRecording(true);
});
useDidHide(() => {
disableScreenRecording(false);
});
return (
<View className="play">
{/* 省略的代码 */}
<IOSWatermarking />
</View>
);
}