更新记录

1.0.3(2026-06-06)

  • Android防截屏优化
  • 新增iOS、Android截屏、录屏功能

1.0.2(2026-05-25)

  • 优化

1.0.1(2026-05-22)

  • 新增iOS端
查看更多

平台兼容性

uni-app(4.66)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × × × 5.0 12 12
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × - × ×

uni-app x(4.66)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × 5.0 12 12 ×

yt-screenshot

开发文档

UTS 语法 UTS API插件 UTS uni-app兼容模式组件 UTS 标准模式组件 Hello UTS

特别提醒

  • 购买本插件前,请先试用、请先试用、请先试用,并充分自测确认满足需求之后再行购买。购买之后无法退款;
  • 如有使用上的疑问、bug,可以进交流群联系作者;
  • 结合文档和示例代码集成使用;
  • 遇到使用问题进交流群询问;
  • ios/Android试用必须先打基座、试用必须先打基座、试用必须先打基座重要事情说三遍;
  • uniapp纯血鸿蒙需要源码授权才能试用、uniapp-x项目可以免费试用(官方规定与插件无关)。
  • 如果截屏和录制的视频加载不出来可在截屏/录屏返回的路径前面加上“file://”

插件功能介绍 (支持uni-app/uni-app-x)

  • 应用级防截屏 / 防录屏(任意页面调用一次,跳转其他页面后仍生效)
    • iOS(iOS 13+)
    • Android
    • HarmonyOS
    • 仅针对系统级截屏/录屏(如电源键+音量键截屏、系统录屏、第三方普通录屏 App 对该窗口的抓取,通常表现为黑屏)
    • 无法阻止本插件captureScreen / startScreenRecord(应用内主动采集不受 FLAG_SECURE / iOS 防护限制)
  • iOS / Android 应用内截屏录屏(开始 / 结束 / 取消录屏;Android 可选麦克风)
  • iOS / Android 删除本地截图、录屏文件 deleteResource
  • HarmonyOS 端截屏、录屏、删除资源暂未实现captureScreenstartScreenRecordstopScreenRecordcancelScreenRecorddeleteResource 当前为空实现,请勿在鸿蒙端依赖上述能力)

各端能力对照

能力 iOS Android HarmonyOS
防截屏 / 防录屏(应用级) ✅(iOS 13+)
截屏 captureScreen ❌ 暂未实现
录屏 startScreenRecord ✅(应用内录屏,保存需 iOS 14+) ❌ 暂未实现
删除资源 deleteResource ❌ 暂未实现

更多好用插件

API 一览

方法 说明 iOS Android HarmonyOS
initScreen() 初始化(Android 录屏必调;同时注册应用级防截屏生命周期) 空实现 空实现
onAntiScreenshot() 开启应用级防截屏/防录屏
offAntiScreenshot() 关闭应用级防截屏/防录屏
captureScreen(para) 截取当前屏幕
startScreenRecord(para) 开始录屏
stopScreenRecord() 结束录屏并保存
cancelScreenRecord() 取消录屏并删除本次文件
deleteResource(para) 删除本地截图/录屏文件

回调类型 ResultInfo

{
  success: boolean
  savedPath?: string   // 成功时的文件绝对路径
  error?: string       // 失败或取消时的说明(如「已取消录屏」)
}

集成文档

导入

import * as screenshot from '@/uni_modules/yt-screenshot'

初始化

// 建议在 App.onLaunch 或首页 onLoad 中调用一次即可,无需每个页面重复调用
// Android:录屏能力依赖此初始化;同时会注册应用级防截屏的 Activity 生命周期监听
screenshot.initScreen()

说明

  • 防截屏:任意页面调用 onAntiScreenshot() 后全局生效,跳转新页面无需再次开启。
  • 录屏:若在非首页使用录屏, 也需在onLoad中调用 initScreen

防截屏 / 防录屏(三端可用,应用级)

// 开启(应用级,跳转页面后仍生效)
screenshot.onAntiScreenshot()

// 关闭
screenshot.offAntiScreenshot()

能力边界(请务必了解)

场景 是否可防
系统快捷键截屏(如电源键 + 音量键)
系统自带录屏 / 普通第三方录屏 App 对该应用窗口的抓取 ✅(通常黑屏)
本插件 captureScreen 应用内截屏 无法防住
本插件 startScreenRecord 应用内录屏 无法防住
root、投屏、特殊辅助手段等系统级绕过 ❌(任何防截屏方案均无法完全杜绝)

防截屏的设计目标是阻止外部对应用窗口内容的被动抓取。本插件的截屏/录屏是应用主动采集屏幕内容,与系统截屏机制不同,因此开启防截屏后,插件自身的 captureScreenstartScreenRecord 仍可正常使用。

截屏(仅 iOS / Android)

screenshot.captureScreen({
  onComplete: (info) => {
    // info.success  info.savedPath  info.error
  }
})
  • Android 保存路径:应用外部私有目录 screenshots/shot_{timestamp}.png
  • iOS 保存路径:Documents/screenshots/shot_{timestamp}.png

录屏(仅 iOS / Android)

screenshot.startScreenRecord({
  isMic: false, // 是否录制麦克风,默认 false
  onStart: (info) => {
    // info.success  info.error
  },
  onComplete: (info) => {
    // info.success  info.savedPath  info.error(取消时为「已取消录屏」)
  }
})

screenshot.stopScreenRecord()   // 结束并保存
screenshot.cancelScreenRecord() // 取消并删除本次文件
  • Android 保存路径:应用外部私有目录 screen_records/record_{timestamp}.mp4
  • iOS 保存路径:Documents/screen_records/record_{timestamp}.mp4
  • iOS 自定义路径保存需 iOS 14.0+(插件 deploymentTarget 为 14)

删除资源(仅 iOS / Android)

删除插件生成的截图、录屏等本地文件:

screenshot.deleteResource({
  filePath: '/path/to/shot_xxx.png', // 或 onComplete 回调中的 savedPath,支持 file:// 前缀
  onComplete: (info) => {
    // info.success  info.error(路径无效 / 文件不存在 / 删除失败)
  }
})

保存到系统相册(manifest 配置)

示例代码中在截屏/录屏成功后,会调用 uni.saveImageToPhotosAlbumuni.saveVideoToPhotosAlbum 将文件保存到系统相册。这两个 API 属于 uni 框架能力,需在项目 manifest 中完成相应配置,否则可能出现「未获取权限」「打包时未添加 Gallery 模块」等错误。

uni-app 项目

1. 勾选 App 模块(必做)

manifest.jsonApp 模块配置 中勾选 Camera&Gallery(相机和相册);或在源码视图的 app-plusmodules 中添加:

{
  "app-plus": {
    "modules": {
      "Camera": {}
    }
  }
}

HBuilderX 3.6.11+ 起,相机与相册合并为 Camera 模块。若项目较旧且保存时报「未添加 Gallery 模块」,可额外添加 "Gallery": {}

2. iOS 隐私描述(必做)

manifest.jsonApp 模块配置iOS 隐私信息访问的许可描述 中填写:

键名 说明
NSPhotoLibraryAddUsageDescription 保存图片/视频到相册(必配)
NSPhotoLibraryUsageDescription 读取相册(部分场景下保存也可能触发,建议一并配置)

源码视图示例(app-plusdistributeiosprivacyDescription):

{
  "app-plus": {
    "distribute": {
      "ios": {
        "privacyDescription": {
          "NSPhotoLibraryAddUsageDescription": "用于将截图、录屏保存到系统相册",
          "NSPhotoLibraryUsageDescription": "用于访问系统相册"
        }
      }
    }
  }
}

3. Android 权限(一般自动处理)

勾选 Camera 模块后,云端/本地打包通常会写入相册相关权限。若 targetSdkVersion ≥ 33 且保存失败,可在 app-plusdistributeandroidpermissions 中补充:

{
  "app-plus": {
    "distribute": {
      "android": {
        "permissions": [
          "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" android:maxSdkVersion=\"32\"/>",
          "<uses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\"/>",
          "<uses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\"/>"
        ]
      }
    }
  }
}

4. 修改后重新打基座/打包

manifest 模块与权限变更不会随普通热更新生效,需重新制作自定义调试基座或重新云打包。

uni-app-x 项目

1. Android 相册权限(通常自动注入)

工程内若调用了 uni.saveImageToPhotosAlbum / uni.saveVideoToPhotosAlbum,打包时一般会自动合并 Android 相册相关权限(如 READ_MEDIA_IMAGESREAD_MEDIA_VIDEO 等),多数情况无需手动配置。

若保存时报错 1101005(未获取权限)或权限缺失,可在 app-androiddistributepermissions 中手动补充(参考 Android 端权限适配):

{
  "app-android": {
    "distribute": {
      "permissions": [
        "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" android:maxSdkVersion=\"32\"/>",
        "<uses-permission android:name=\"android.permission.READ_MEDIA_IMAGES\"/>",
        "<uses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\"/>",
        "<uses-permission android:name=\"android.permission.READ_MEDIA_VISUAL_USER_SELECTED\"/>"
      ]
    }
  }
}

2. iOS 隐私描述(必做)

uni-app-x 的 manifest.json 不提供 iOS 隐私描述可视化配置,需在项目 nativeResources/ios/Info.plist 中添加:

<key>NSPhotoLibraryAddUsageDescription</key>
<string>用于将截图、录屏保存到系统相册</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>用于访问系统相册</string>

详见 iOS 原生应用配置文件和资源

3. 使用 <video> 预览录屏(可选)

若页面使用 <video> 组件预览录屏文件,需在 app-android / app-iosdistribute.modules 中启用 uni-video

{
  "app-android": {
    "distribute": {
      "modules": {
        "uni-video": {}
      }
    }
  },
  "app-ios": {
    "distribute": {
      "modules": {
        "uni-video": {}
      }
    }
  }
}

4. 运行时权限

Android 上保存到相册属于敏感权限,除 manifest 声明外,还需在运行时获得用户授权;失败时可引导用户到系统设置中开启相册权限。官方 API 文档:saveImageToPhotosAlbumsaveVideoToPhotosAlbum

uniapp完整示例

<template>
    <scroll-view class="content" scroll-y="true">
        <view class="btn" @click="onAntiScreenshot"><text>开启防截屏</text></view>
        <view class="btn" @click="offAntiScreenshot"><text>关闭防截屏</text></view>
        <view class="btn" @click="captureScreen"><text>截取当前屏幕内容</text></view>

        <view class="mic-row">
            <text class="mic-label">录制麦克风</text>
            <switch class="mic-switch" :checked="recordWithMic" :disabled="isRecording" @change="onMicSwitchChange" />
        </view>

        <view class="btn" @click="startScreenRecord"><text>开始录制</text></view>
        <view class="btn" @click="stopScreenRecord"><text>结束录屏</text></view>
        <view class="btn btn-cancel" @click="cancelScreenRecord"><text>取消录屏</text></view>
        <view class="btn" style="background-color: #00000000;flex-direction: row;justify-content: space-between;">
            <view
                style="background-color: antiquewhite;display: flex;flex: 1;height: 80rpx;align-items: center; justify-content: center;margin-right: 30rpx;"
                @click="deleteResource"><text>删除截屏资源</text></view>
            <view
                style="background-color: antiquewhite;display: flex;flex: 1;height: 80rpx;align-items: center; justify-content: center;"
                @click="deleteResourceVideo"><text>删除录屏资源</text></view>
        </view>

        <view v-if="imageSrc != ''" class="preview-wrap">
            <text class="preview-title">截图预览</text>
            <image class="preview-image" :src="imageSrc" mode="aspectFit"></image>
        </view>

        <view class="preview-wrap">
            <text class="preview-title">录屏预览</text>
            <video id="recordVideo" class="preview-video" :class="{ 'preview-video--hidden': videoSrc == '' }"
                :src="videoSrc" controls :show-center-play-btn="true" object-fit="contain"
                @error="onVideoError"></video>
            <text v-if="videoSrc != ''" class="path-text">{{ videoPath }}</text>
        </view>

        <navigator url="/pages/index/twopage" class="link">页面跳转</navigator>
    </scroll-view>
</template>

<script>
    import * as Screenshot from '@/uni_modules/yt-screenshot'

    export default {
        data() {
            return {
                imageSrc: '',
                videoSrc: '',
                videoPath: '',
                isRecording: false,
                recordWithMic: false
            }
        },
        onLoad() {
            Screenshot.initScreen();
        },
        onReady() {
            // 引用 video API,确保自定义基座打包时包含 uni-video 模块
            // this.videoContext = uni.createVideoContext('recordVideo', this);
        },
        methods: {
            toFileUrl(path) {
                if (path == null || path == '') {
                    return '';
                }
                if (path.startsWith('file://')) {
                    return path;
                }
                return 'file://' + path;
            },
            onAntiScreenshot() {
                Screenshot.onAntiScreenshot()
            },
            offAntiScreenshot() {
                Screenshot.offAntiScreenshot()
            },
            captureScreen() {
                Screenshot.captureScreen({
                    onComplete: (info) => {
                        console.log(
                            `截图完成:success:${info.success}---path:${info.savedPath}----error:${info.error}`)
                        if (info.success && info.savedPath != null) {
                            this.imageSrc = this.toFileUrl(info.savedPath);
                            uni.showToast({
                                title: '截图成功',
                                icon: 'success'
                            });
                            uni.saveImageToPhotosAlbum({
                                filePath: this.imageSrc,
                                success: (_) => {
                                    console.log("保存相册成功");
                                },
                                fail: (e) => {
                                    console.log(`保存失败:${e}`)
                                }
                            })
                        } else {
                            uni.showToast({
                                title: info.error != null ? info.error : '截图失败',
                                icon: 'none'
                            });
                        }
                    }
                });
            },
            onMicSwitchChange(e) {
                this.recordWithMic = e.detail.value;
            },
            startScreenRecord() {
                if (this.isRecording) {
                    return;
                }
                Screenshot.startScreenRecord({
                    isMic: this.recordWithMic,
                    onStart: (info) => {
                        console.log(`录制开始:success:${info.success}----error:${info.error}`)
                        if (info.success) {
                            this.isRecording = true;
                            uni.showToast({
                                title: '开始录制',
                                icon: 'none'
                            });
                        } else {
                            uni.showToast({
                                title: info.error != null ? info.error : '录屏启动失败',
                                icon: 'none'
                            });
                        }
                    },
                    onComplete: (info) => {
                        console.log(
                            `录制完成:success:${info.success}---path:${info.savedPath}----error:${info.error}`)
                        this.isRecording = false;
                        if (info.success && info.savedPath != null) {
                            this.videoPath = info.savedPath;
                            this.videoSrc = this.toFileUrl(info.savedPath);
                            uni.showToast({
                                title: '录屏已保存',
                                icon: 'success'
                            });
                            uni.saveVideoToPhotosAlbum({
                                filePath: this.videoPath,
                                success: (_) => {

                                },
                                fail: (error) => {

                                }
                            })
                        } else if (info.error == '已取消录屏') {
                            this.videoPath = '';
                            this.videoSrc = '';
                            uni.showToast({
                                title: '已取消录屏',
                                icon: 'none'
                            });
                        } else if (info.error != null && info.error != '当前未在录屏') {
                            uni.showToast({
                                title: info.error,
                                icon: 'none'
                            });
                        }
                    }
                });
            },
            stopScreenRecord() {
                if (!this.isRecording) {
                    uni.showToast({
                        title: '当前未在录屏',
                        icon: 'none'
                    });
                    return;
                }
                Screenshot.stopScreenRecord()
            },
            cancelScreenRecord() {
                if (!this.isRecording) {
                    uni.showToast({
                        title: '当前未在录屏',
                        icon: 'none'
                    });
                    return;
                }
                Screenshot.cancelScreenRecord()
            },
            deleteResource() {
                Screenshot.deleteResource({
                    filePath: this.imageSrc,
                    onComplete: (info) => {
                        uni.showToast({
                            title: info.success ? "删除成功" : "删除失败",
                            icon: 'none'
                        })
                    }
                })
            },
            deleteResourceVideo() {
                Screenshot.deleteResource({
                    filePath: this.videoPath,
                    onComplete: (info) => {
                        uni.showToast({
                            title: info.success ? "删除成功" : "删除失败",
                            icon: 'none'
                        })
                    }
                })
            },
            onVideoError(e) {
                console.log('视频播放错误:', e);
                uni.showToast({
                    title: '视频加载失败',
                    icon: 'none'
                });
            }
        }
    }
</script>

<style>
    .content {
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        padding-bottom: 40rpx;
    }

    .btn {
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: antiquewhite;
        border-radius: 8rpx;
        width: 690rpx;
        height: 80rpx;
        margin-top: 30rpx;
    }

    .preview-wrap {
        width: 690rpx;
        margin-top: 40rpx;
    }

    .preview-title {
        font-size: 28rpx;
        color: #333333;
        margin-bottom: 16rpx;
    }

    .preview-image {
        width: 690rpx;
        height: 400rpx;
        background-color: #eeeeee;
        border-radius: 8rpx;
    }

    .preview-video {
        width: 690rpx;
        height: 400rpx;
        background-color: #000000;
        border-radius: 8rpx;
    }

    .preview-video--hidden {
        height: 0;
    }

    .path-text {
        font-size: 22rpx;
        color: #999999;
        margin-top: 12rpx;
    }

    .btn-cancel {
        background-color: #f5d0d0;
    }

    .mic-row {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        width: 690rpx;
        height: 80rpx;
        margin-top: 40rpx;
        padding: 0 24rpx;
        background-color: #f8f8f8;
        border-radius: 8rpx;
    }

    .mic-label {
        font-size: 28rpx;
        color: #333333;
    }

    .mic-switch {
        transform: scale(0.9);
    }

    .link {
        margin-top: 50rpx;
        color: #4a90e2;
        font-size: 28rpx;
    }
</style>

完整示例(uni-app-x)

以下为常用能力示例,完整演示(含图片/视频预览、删除资源、页面跳转验证应用级防截屏)。

<template>
    <scroll-view class="content" scroll-y="true">
        <view class="btn" @click="onAntiScreenshot"><text>开启防截屏</text></view>
        <view class="btn" @click="offAntiScreenshot"><text>关闭防截屏</text></view>
        <view class="btn" @click="captureScreen"><text>截取当前屏幕内容</text></view>

        <view class="mic-row">
            <text class="mic-label">录制麦克风</text>
            <switch class="mic-switch" :checked="recordWithMic" :disabled="isRecording" @change="onMicSwitchChange" />
        </view>

        <view class="btn" @click="startScreenRecord"><text>开始录制</text></view>
        <view class="btn" @click="stopScreenRecord"><text>结束录屏</text></view>
        <view class="btn btn-cancel" @click="cancelScreenRecord"><text>取消录屏</text></view>
        <view class="btn" style="background-color: #00000000;flex-direction: row;justify-content: space-between;">
            <view
                style="background-color: antiquewhite;display: flex;flex: 1;height: 80rpx;align-items: center; justify-content: center;margin-right: 30rpx;"
                @click="deleteResource"><text>删除截屏资源</text></view>
            <view
                style="background-color: antiquewhite;display: flex;flex: 1;height: 80rpx;align-items: center; justify-content: center;"
                @click="deleteResourceVideo"><text>删除录屏资源</text></view>
        </view>

        <view v-if="imageSrc != ''" class="preview-wrap">
            <text class="preview-title">截图预览</text>
            <image class="preview-image" :src="imageSrc" mode="aspectFit"></image>
        </view>

        <view class="preview-wrap">
            <text class="preview-title">录屏预览</text>
            <video id="recordVideo" class="preview-video" :class="{ 'preview-video--hidden': videoSrc == '' }"
                :src="videoSrc" controls :show-center-play-btn="true" object-fit="contain"
                @error="onVideoError"></video>
            <text v-if="videoSrc != ''" class="path-text">{{ videoPath }}</text>
        </view>

        <navigator url="/pages/index/twopage" class="link">页面跳转</navigator>
    </scroll-view>
</template>

<script>
    import * as Screenshot from '@/uni_modules/yt-screenshot'

    export default {
        data() {
            return {
                imageSrc: '' as string,
                videoSrc: '' as string,
                videoPath: '' as string,
                isRecording: false as boolean,
                recordWithMic: false as boolean
            }
        },
        onLoad() {
            Screenshot.initScreen();
        },
        onReady() {
            // 引用 video API,确保自定义基座打包时包含 uni-video 模块
            // this.videoContext = uni.createVideoContext('recordVideo', this);
        },
        methods: {
            toFileUrl(path : string | null) : string {
                if (path == null || path == '') {
                    return '';
                }
                if (path.startsWith('file://')) {
                    return path;
                }
                return 'file://' + path;
            },
            onAntiScreenshot() {
                Screenshot.onAntiScreenshot()
            },
            offAntiScreenshot() {
                Screenshot.offAntiScreenshot()
            },
            captureScreen() {
                Screenshot.captureScreen({
                    onComplete: (info) => {
                        console.log(`截图完成:success:${info.success}---path:${info.savedPath}----error:${info.error}`)
                        if (info.success && info.savedPath != null) {
                            this.imageSrc = this.toFileUrl(info.savedPath);
                            uni.showToast({ title: '截图成功', icon: 'success' });
                            uni.saveImageToPhotosAlbum({
                                filePath: this.imageSrc,
                                success: (_) => {
                                    console.log("保存相册成功");
                                },
                                fail: (e) => {
                                    console.log(`保存失败:${e}`)
                                }
                            })
                        } else {
                            uni.showToast({
                                title: info.error != null ? info.error : '截图失败',
                                icon: 'none'
                            });
                        }
                    }
                });
            },
            onMicSwitchChange(e : UniSwitchChangeEvent) {
                this.recordWithMic = e.detail.value;
            },
            startScreenRecord() {
                if (this.isRecording) {
                    return;
                }
                Screenshot.startScreenRecord({
                    isMic: this.recordWithMic,
                    onStart: (info) => {
                        console.log(`录制开始:success:${info.success}----error:${info.error}`)
                        if (info.success) {
                            this.isRecording = true;
                            uni.showToast({ title: '开始录制', icon: 'none' });
                        } else {
                            uni.showToast({
                                title: info.error != null ? info.error : '录屏启动失败',
                                icon: 'none'
                            });
                        }
                    },
                    onComplete: (info) => {
                        console.log(`录制完成:success:${info.success}---path:${info.savedPath}----error:${info.error}`)
                        this.isRecording = false;
                        if (info.success && info.savedPath != null) {
                            this.videoPath = info.savedPath;
                            this.videoSrc = this.toFileUrl(info.savedPath);
                            uni.showToast({ title: '录屏已保存', icon: 'success' });
                            uni.saveVideoToPhotosAlbum({
                                filePath: this.videoPath,
                                success: (_) => {

                                },
                                fail: (error) => {

                                }
                            })
                        } else if (info.error == '已取消录屏') {
                            this.videoPath = '';
                            this.videoSrc = '';
                            uni.showToast({ title: '已取消录屏', icon: 'none' });
                        } else if (info.error != null && info.error != '当前未在录屏') {
                            uni.showToast({
                                title: info.error,
                                icon: 'none'
                            });
                        }
                    }
                });
            },
            stopScreenRecord() {
                if (!this.isRecording) {
                    uni.showToast({ title: '当前未在录屏', icon: 'none' });
                    return;
                }
                Screenshot.stopScreenRecord()
            },
            cancelScreenRecord() {
                if (!this.isRecording) {
                    uni.showToast({ title: '当前未在录屏', icon: 'none' });
                    return;
                }
                Screenshot.cancelScreenRecord()
            },
            deleteResource() {
                Screenshot.deleteResource({
                    filePath: this.imageSrc,
                    onComplete: (info) => {
                        uni.showToast({
                            title: info.success ? "删除成功" : "删除失败",
                            icon: 'none'
                        })
                    }
                })
            },
            deleteResourceVideo() {
                Screenshot.deleteResource({
                    filePath: this.videoPath,
                    onComplete: (info) => {
                        uni.showToast({
                            title: info.success ? "删除成功" : "删除失败",
                            icon: 'none'
                        })
                    }
                })
            },
            onVideoError(e : UniVideoErrorEvent) {
                console.log('视频播放错误:', e);
                uni.showToast({ title: '视频加载失败', icon: 'none' });
            }
        }
    }
</script>

<style>
    .content {
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        padding-bottom: 40rpx;
    }

    .btn {
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: antiquewhite;
        border-radius: 8rpx;
        width: 690rpx;
        height: 80rpx;
        margin-top: 30rpx;
    }

    .preview-wrap {
        width: 690rpx;
        margin-top: 40rpx;
    }

    .preview-title {
        font-size: 28rpx;
        color: #333333;
        margin-bottom: 16rpx;
    }

    .preview-image {
        width: 690rpx;
        height: 400rpx;
        background-color: #eeeeee;
        border-radius: 8rpx;
    }

    .preview-video {
        width: 690rpx;
        height: 400rpx;
        background-color: #000000;
        border-radius: 8rpx;
    }

    .preview-video--hidden {
        height: 0;
    }

    .path-text {
        font-size: 22rpx;
        color: #999999;
        margin-top: 12rpx;
    }

    .btn-cancel {
        background-color: #f5d0d0;
    }

    .mic-row {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        width: 690rpx;
        height: 80rpx;
        margin-top: 40rpx;
        padding: 0 24rpx;
        background-color: #f8f8f8;
        border-radius: 8rpx;
    }

    .mic-label {
        font-size: 28rpx;
        color: #333333;
    }

    .mic-switch {
        transform: scale(0.9);
    }

    .link {
        margin-top: 50rpx;
        color: #4a90e2;
        font-size: 28rpx;
    }
</style>

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: