更新记录

1.1.8(2023-09-26)

iOS的SDK升级到了 4.1.8 android SDK升级到了 0.1.9.8 增加了转发模式,增加了转发的POI地址,贴纸等内容 具体可以看看3.14例子

1.1.7(2023-08-21)

增加2字段 micro_app_task_id 小程序任务id agent_client_key 撮合中介, 由于js没有long行 所以传入的时候 需要变为这样的字符串 "(long)xxxx数值" 修改了授权权限的输入key

1.1.6(2023-07-31)

新版本请修改原来的授权模式 douyinopensdk,douyinsharesdk,snssdk1128,douyinv1opensdk,douyinliteopensdk 修正了scope的内容白名单权限

查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:5.0 - 14.0 armeabi-v7a:支持,arm64-v8a:支持,x86:未测试 适用版本区间:11 - 16

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


VniDyPlugin 插件使用说明

为了更好在Uniapp上即成抖音SDK,特开发此插件

DEMO URL地址: https://gitee.com/vnidev/uniapp-douyin-share-plugin-demo


0x0 更新记录

1.1.8 iOS的SDK升级到了 4.1.8 android SDK升级到了 0.1.9.8 增加了转发模式,增加了转发的POI地址,贴纸等内容 Android&iOS 转发内容到抖音 可以看看3.14案例

1.1.7 增加2字段 micro_app_task_id 小程序任务id agent_client_key 撮合中介,由于js没有long行 所以传入的时候 需要变为这样的字符串 "(long)xxxx数值" 修改了授权权限的输入key

1.1.6 bug fixes

1.1.3 修复一个内存泄露的问题

1.1.3 更新SDK版本

1.1.2 增加删除文件内容 修复片头片尾合成问题

1.1.1 修正同一部手机安装两份插件的问题

1.1.0 新增根据路径获取md5值,防止上传文件出现重复,新增根据路径获取封面,新增获取图片的详细信息,包含图片/视频大小,长和宽,视频的长度,系统文件名,文件路径,对应的ID信息等。具体看新的API内容 【具体看3.12, 3.13, 3.14 】

1.0.9 解决部门应用trial.whitelist问题,增加scope参数自定义

1.0.8 解决iOS的多个hastag无法显示

1.0.7 增加从相册选取内容,并返回系统ID,可以用于片头和片尾的自定义操作

一、准备工作

1.1 获得抖音SDK的ClientKey

  • 打开抖音开发平台 > 点击打开注册app
  • 请到开发者应用登记页面进行申请
  • 填写您的应用包名,申请后将获得 ClientKey
可能需要填写Andorod 应用签名, 获取签名:通过keytool产生apk签名用的的keystore证书,用证书打包一个apk文件包名需要和你抖音上设置的相同, 用 GenSignatureAndroid.apk APP获取签名,或通过 keytool JDK1.8集以下支持,获取命令:keytool -printcert -jarfile your.apk  

1.1.1 应用未上线,白名单问题:

登录的时候增加 scope: trial.whitelist 新的应用需要开启白名单权限 【特殊权限 > 测试应用白名单权限 > 请提额 】

1.1.1 scope 权限不足

检查具体的权限是否有没有申请权限

1.2 安装插件

  • 打开您的Xbuilder工程文件
  • 点击 manifest.json -> App原生插件配置
  • 选择您已经购买的云端插件

1.3 配置项目

  • 打开 【iOS设置】【App常用其他设置】
    • 应用白名单 加入下面的值 douyinopensdk,douyinsharesdk,snssdk1128,douyinv1opensdk,douyinliteopensdk
    • UrlSchemes 加入 上面申请的 ClientKey

1.4 配置截图



二、如何使用插件


2.1 插件使用规则

// 加载插件
var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

//输入基本参数,具体参数请看具体的方法, 这里只是作为演示
let input = {
  appid : '[系统换成您申请的key]',
  ... [其他配置参数]
}

// 调用方法 具体的方法从第三节开始开始
plugin.[您需要调用的方法](input,(resp)=>{
   resp 为反馈响应
})

2.2 方法的响应内容,具体内容需参考具体方法【第三节】


{
   "finished": true / false,
   "source" : input,
   "errCode" : "错误码",
   "errString" : "错误提示",
   other // 其他响应参数
}

2.3 问题咨询

微信:vnidev QQ:154314278



三、具体API详情内容


3.1 检查用户是否安装了抖音APP

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

var input = { "appid": "替换为您的appId" }
plugin.hasDouyin(input, resp => {

});

结果:

{
    "finished": true, //执行结果
    "installed": true //是否安装了抖音App
}


3.2 检查是否是否拥有相册权限

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.hasPhotoPerm({ }, resp => {

});

结果:

{
    "read_photo": true, //读取相册的权限
    "finished": true, //执行结果
    "write_photo": true //写入相册的权限
}


3.3 打开App的设置界面

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.openAppSetting();

结果:

该操作无回调数据


3.4 使用抖音授权登录

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

var input = {
    "appid": "替换为您的appId",
    "checked_scope": "mobile,data.external.user,data.external.item", //默认选中权限,根据自己拥有的权限来
    "unchecked_scope": "fans.data,video.data,video.list" //默认不选中权限,根据自己拥有的权限来,后台查看权限集合
    //"scope" : "trial.whitelist" //只有whitelist才需要这个字段
    //state : "" 透传字段,需要的时候才传
    //extraInfoData: { key: value } //扩展字段,需要才传

}
// 部分用户显示trial.whitelist问题,scope中加入trial.whitelist,上面的例子中取消scope前的注释
// https://open.douyin.com/platform/resource/docs/openapi/data-open-service/user-data/get-user-video-status 【Scope: data.external.user参考权限】

plugin.ssoLogin(input, (resp) => {

})

结果:

{
    //提交给服务器来置换用户的真实信息
    "code": "8e659bf93d8b065egI6qgg9cM5JwyndJ28v2",
    //用户所申请的权限
    "permissions": [
        "user_info",
        "mobile"
    ],
    // 调用结果
    "finished": true, 
    //传入的参数
    "source": {
        "appid": ""替换为您的appId"",
        "mobile": "checked"
    }
}

3.5 启动抖音的拍摄功能

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

var input = {
    "appid": "替换为您的appId",
    "state": "state", //可以不需要
    "hashtag" : "hashtag", //可以不需要
    //附加的小程序,可以不需要 
    "mpInfo" : {
       "title" : "小程序标题",
       "description" : "小程序描述",
       "appid" : "小程序appid",
       "appUrl" : "小程序启动页面"
    },
    // extraInfoData: { key: value } 根据情况填写
}

plugin.startCreate(input, (res) => {

})

结果:

{
    // 成功后抖音给出的状态
    "code": 20000, 
    // 执行结果  
    "finished": true, 
    // 输入值
    "source": {
        "appid": "替换为您的appId"
    }
}

结果2 用户取消之后的结果

{
    "finished": false,
    "source": {
        "appid": "替换为您的appId"
    },
    "errCode": -2,
    "errString": "Sharing canceled"
}

3.6 获取抖音SDK版本号

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.sdkVersion({}, res => {

})

结果

{
    //当前SDK的版本号
    "version": "4.0.2",
    //执行结果
    "finished": true
}


3.7 分享指定内容给好友

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

分享图片
var image = {
  "appid": "替换为您的appId",
    "type": "image",
    "maxshare": 1,  //目前sdk支持 1
    "minshare": 1,  //最少选择多少张 默认1
    "hashtag": "话题1,话题2",

    //如果想直接分享图片/视频网络地址可以用用这2个参数。如果从相册选择的话,下面2个参数可不要
    "mediaUrl" : "如果下载地址无法判断下载文件格式的请指定medianame为下载的名字带",
    "mediaName" : "xxx.mp4",

    "state": "state"
}

var video = {
  "appid": "替换为您的appId",
    "type": "video",
    "maxshare": 1,  //目前sdk支持 1
    "hashtag": "话题1,话题2",
    "state": "state"
}

var link = {
    "appid": "替换为您的appId",
    "type": "link",
    "hashtag": "hashtag",
    "state": "state",
    "link": {
      "url": "链接地址",
      "title": "标题",
      "desc": "网站描述",
      "cover": "图片地址"
    }
}

plugin.shareToUser(image / video / link , resp => {

})

结果

成功

{
    "code": 20000,
    "state": "state",
    "finished": true,
    "source": xxx
}

失败

{
    "finished": false,
    "source": xxx,
    "errCode": -4,
    "errString": "Share Link Permissions denied"
}

3.7 把内容提交到抖音页面

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

分享图片
var config = {
    "appid": "替换为您的appId",
    "type": 'image', // 类型可选 image / video
    "maxshare": 5,  //发送过去的最大选择个数
    "minshare": 1,  //最少选择多少张 默认1
    "hashtag": "hashtag,hastag2",
    "state": "state",
    //附加的小程序,可以不需要
    "mpInfo" : {
       "title" : "小程序标题",
       "description" : "小程序描述",
       "appid" : "小程序appid",
       "appUrl" : "小程序启动页面"
    },
    "startpage": "edit" 
    //eidt 编辑页面  clip 剪辑页面 publish 发布页面(单个视频)
}

plugin.shareMedia(config, (resp) => {

})

结果

成功的时候
{
    "code": 20000,
    "state": "state",
    "finished": true,
    "source": xxx
}
失败的时候
{
    "finished": false,
    "source": xxx,
    "errCode": -2,
    "errString": "Sharing canceled"
}


3.8 把视频地址的URL进行直接发布,无需先下载后选择发布

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.shareVideoUrl({
    appid: "替换为您的appId",
    url: "视频地址",
    filename: "指定文件名,可以不填写,为了防止有些动态获取无法获取文件类型",
    hashtag: "你好,李欢饮",
    startpage : "clip", //clip,edit,publish 剪辑,编辑,发布页面
    state: "state",
    //附加的小程序,可以不需要
    "mpInfo" : {
       "title" : "小程序标题",
       "description" : "小程序描述",
       "appid" : "小程序appid",
       "appUrl" : "小程序启动页面"
    },
  }, res => {

  });

由于下载文件全部在插件中完成,所以暂时不支持加入header等授权资源内容操作

下载的过程中请用 uni.showLoading({ title: "正在处理.." }),结束之后用 hideLoading, 并设置一个超时时间,超过就自动关闭。

3.9 下载视频到相册中,并刷新相册

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.downloadMedia({
    urls: [
        "http://192.168.10.110:9090/videoplayback.mp4",
        "http://192.168.10.110:9090/a.mp4",
        "http://192.168.10.110:9090/b.mp4",
        "http://192.168.10.110:9090/c.mp4"
    ],
  }, res => {
        this.authdata = res
        uni.hideLoading()
});

成功之后会会返回系统的相册的ID,您可以根据系统ID做分享操作

3.10 从相册选取文件内容,并返回系统ID

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.pickMedia({

    type : 'video', // video 视频 image 图片
    max : 5, // 最多选几张 默认5
    min : 1, //最少选几张 默认1

  }, res => {

        uni.hideLoading()
});

响应内容

{
  finished : true,
  selected : ['xx'] //选取的结果
}

3.11 直接通过相册的路径分享

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.shareMediaViaPaths({
    appid: "替换为您的appId",
    startpage : 'clip', //clip 剪辑 | edit 编辑 | publish 发布 publish的时候只能一个文件
    mediaIds : [], //需要分享的路径
    sharetype: 'video', //video 视频 | image 图片
    mpInfo : null , //附带的小程序信息,具体看上面小程序信息
    hashtag: '', //话题标签
    state : '', 附加的state
  }, res => {
        this.authdata = res
        uni.hideLoading()
});



3.12 根据路径获取文件的MD5,

注意:如果视频比较大比较耗时

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.getMd5({
    path : ''
  }, res => {
        this.authdata = re
});



3.13 根据路径获取文件的封面,

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.getCover({
    path : '绝对路径',
    width: -1,  // 缩略图宽度,默认-1,原始尺寸
    type : 'png',   //默认png 可选 jpg
    quality: 1  // 当type=jpg时,可以选择压缩比,0~1之间, png时本参数无效

  }, res => {
        this.authdata = re
});



3.14 从相册中选择视频/图片,并返回详细信息,

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.getMediaInfoAndPath({
    type : 'video', // 选择类型,图片(image)/视频(video)
    max: 5,  // 最多选择多少个,默认5个
    min: 1 ,  //至少选择多少个,默认1个
    withmd5: false, // 选择之后是否同时返回Md5值,默认false
    withcover : false, //选择完之后是否返回封面缩略图,默认false
    withcoverwidth: 600  // 缩略图宽度,默认600px宽,原始尺寸,    
  }, res => {
        this.authdata = re
});

返回内容:
name -> 系统中的文件名
width -> 图片/视频的宽度
height -> 图片/视频的高度
path -> 在系统中的路径
size -> 文件大小
duration -> 视频的长度。图片没有值
identifier -> 视频/图片的id,可用于分享或者发起视频内容
mediaType -> 文件格式 image:图片 video: 视频 audio:音频 Unknown: 未知



3.12 通过uni的临时下载地址分享

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.shareMediaViaUniDownloadPaths({
    appid: "替换为您的appId",
    startpage : 'clip', //clip 剪辑 | edit 编辑 | publish 发布 publish的时候只能一个文件
    mediaPaths : ['路径1','路径2'], //需要分享的路径
    sharetype: 'video', //video 视频 | image 图片
    mpInfo : null , //附带的小程序信息,具体看上面小程序信息
    hashtag: '', //话题标签
    state : '', 附加的state
  }, res => {
        this.authdata = res
        uni.hideLoading()
});



3.13 根据ID删除系统图片和视频

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.deleteMediaByFileIds({
    fileids: []
    // filedis iOS上是对应的分享ID
    // filedis android 上是对应的是相册路径
    // 具体参考demo
  }, res => {
     console.info('删除',res)
});



3.14 比较复杂的按钮,转发内容

var plugin = uni.requireNativePlugin('Vnidev-DyPlugin-Core');

plugin.shareVideoUrl({
                    "appid": 'APP_ID',
                    "debug": true,
                    "filename": "1648454685371qyjvideo.mp4",
                    "startpage": "publish",
                    "url": this.vidoeurl,
                    //背景颜色模式,三个参数均可选,效果自己调试的时候查看
                    "backgroundModel": {
                        "topColor": "#ff0000",
                        "bottomColor": "#ffFF00",
                        "webImageURL": "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"
                    },
                    "enablePublishStory": true, // 开发转发模式 否则就是分享模式

                    "poiID": "6776458642267949056", // 单独的Poi模式,如果下面有poi的sticker 下面的优先级高一些
                    // "videoid": "videoid", //传入的视频ID,作用未知

                    "enable_sticker": true, // 打开 sticker 总开关 下面的 
                    // 打开后下面的
                    "stickers": [{
                        //url or iamge
                        "image": "https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/newfanyi-da0cea8f7e.png",
                        "locationX": 0.3, //默认0.5
                        "locationY": 0.5, //默认0.5
                        "maxEdge": 300,
                        "minimumScale": 0.5,
                        "deleteable": true,
                        "editable": true,
                        //Android的
                        "startTime": 0,
                        "endTime": 10 * 1000, //毫秒
                        "normalizedSizeX": 0.5,
                        "normalizedSizeY": 0.5,
                        "scale": 1.0,
                        "rotate": 0
                    }],
                    // 自定义标题 复杂标题,可以设置 hastag 等
                    "title": {
                        "mentions": ["openid1", "openid2"],
                        "hashtags": ["hastag1", "hastag2"],
                        "title": "请注意看了"
                    },
                    //@某个用户
                    "mentionStickers": [{
                        "openID": "openid",
                        "locationX": 0.3,
                        "locationY": 0.4
                    }],
                    //hashtag 贴纸
                    "hashtagStickers": [{
                            "text": "贴纸文字1",
                            "locationX": 0.3,
                            "locationY": 0.4
                        },
                        {
                            "text": "贴纸文字2",
                            "locationX": 0.5,
                            "locationY": 0.4
                        }
                    ],
                    "poiSticker": {
                        "poiID": "6776458642267949056",
                        "locationX": 0.5,
                        "locationY": 0.5
                    },
                    "mpInfo": {
                        "title": "京东好物·生鲜水果",
                        "description": "弄懂",
                        "appUrl": "pages/product/product?wareId=19579574388",
                        "appid": "tta9e7df5a36cd128c"
                    }
                }, res => {
                    this.authdata = res
                    uni.hideLoading()
                });

三、运行效果图


iOS效果图

Android运行图

APK演示代码地址

https://gitee.com/vnidev/uniapp-douyin-share-plugin-demo

隐私、权限声明

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

相册的读取权限 相册的写入权限

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

插件不采集任何数据 插件使用的抖音开发平台 SDK采集数据请参考其官方说明:https://open.douyin.com/platform/doc?doc=docs/accession-guide/platform-introduction

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

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问