智能小程序小部件(Widget)媒体组件属性说明和示例代码汇总

camera

基础库 2.2.0 开始支持, 低版本需做兼容处理。

系统相机。相关 API:ty.createCameraContext。这是基于异层渲染的原生组件, 请注意原生组件使用限制

属性说明

属性名 类型 默认值 必填 说明
mode string normal 应用模式,只在初始化时有效,不能动态变更
resolution string medium 分辨率,不支持动态修改;可选值有 low: 低,medium: 中,high: 高
device-position string back 摄像头朝向, 可选值有front: 前置, back: 后置
flash string auto 闪光灯, 可选值有auto: 自动, on: 打开, off: 关闭, torch: 常亮
border-width number 0 边框的宽度, 单位 px
border-style string solid 边框的样式, 可选值: solid 和 dashed
border-color string #ffffff 边框的颜色, 必须为十六进制格式
border-radius number 0 边框的圆角, 单位 px
border-radius-top-left number 边框的左上角圆角大小, 单位 px
border-radius-top-right number 边框的右上角圆角大小, 单位 px
border-radius-bottom-left number 边框的左下角圆角大小, 单位 px
border-radius-bottom-right number 边框的右下角圆角大小, 单位 px
background-color string #ffffff 背景颜色, 必须为十六进制格式
bind:bindstop eventhandle 摄像头在非正常终止时触发,如退出后台等情况
bind:error eventhandle 用户不允许使用摄像头时触发
bind:initdone eventhandle 相机初始化完成时触发,e.detail = {maxZoom}

Bug & Tip

  1. tip:同一页面只能插入一个 camera 组件。
  2. tip:Tuya MiniApp Tools 上不支持。
  3. tip:相关原理请参考 基于异层渲染的原生组件
  4. tip:请注意 原生组件使用限制

示例代码

TYML
<view class="page-body">
  <camera
    style="width: 100%; height:300px;"
    resolution="high"
    device-position="{{devicePosition}}"
    flash="{{flash}}"
    frame-size="large"
    bindstop="stop"
    binderror="error"
    bindinitdone="initdone"
  ></camera>
  <view class="btn-area">
    <button class="page-body-button" type="primary" bindtap="takePhoto">takePhoto API</button>
    <button class="page-body-button" type="primary" bindtap="setZoom">setZoom API</button>
    <button class="page-body-button" type="primary" bindtap="devicePositionCHnage">device-position 属性</button>
    <button class="page-body-button" type="primary" bindtap="flashChange">flash 属性</button>
    <view>预览照片:</view>
    <image ty:if="{{src}}" mode="widthFix" src="{{src}}"></image>
  </view>
</view>
JS
Page({
  data: {
    devicePosition: 'back',
    flash: 'off',
    src: '',
  },
  onReady() {
    this.ctx = ty.createCameraContext();
  },
  devicePositionCHnage() {
    this.setData({
      devicePosition: this.data.devicePosition === 'back' ? 'front' : 'back',
    });
  },
  flashChange() {
    this.setData({
      flash: this.data.flash === 'off' ? 'on' : 'off',
    });
  },
  stop(e) {
    console.log('demo stop', e);
  },
  error(e) {
    console.log('demo error', e);
  },
  initdone(e) {
    console.log('demo initdone', e);
  },
  takePhoto() {
    this.ctx.takePhoto({
      quality: 'high',
      success: (res) => {
        this.setData({
          src: res.tempImagePath,
        });
      },
      fail: (res) => {
        console.log('demo takePhoto fail', res);
      },
    });
  },
  setZoom() {
    this.ctx.setZoom({
      zoom: 5,
      success: (res) => {
        console.log('demo setZoom success', res);
      },
      fail: (res) => {
        console.log('demo setZoom fail', res);
      },
    });
  },
});
JSON
{
  "navigationBarTitleText": "camera"
}
TYSS
.page-body {
  display: flex;
  align-items: center;
  flex-direction: column;
  padding: 10px 20px 20px;
}
 
.btn-area {
  width: 100%;
  margin-top: 20px;
}
 
.page-body-button {
  width: 100%;
  margin-bottom: 20px;
}

image

图片。支持 JPG、PNG、SVG、WEBP、GIF 等格式。

属性说明

属性名 类型 默认值 必填 说明 备注
src string false 图片资源地址
mode string scaleToFill false 图片剪裁方式,详情见后面的表格
lazy-load boolean false false 图片懒加载
bind:error eventhandler false 当错误发生时
bind:load eventhandler false 当图片加载完时

mode 的合法值

说明
scaleToFill 缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
aspectFit 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
aspectFill 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
widthFix 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变
heightFix 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变
top 裁剪模式,不缩放图片,只显示图片的顶部区域
bottom 裁剪模式,不缩放图片,只显示图片的底部区域
center 裁剪模式,不缩放图片,只显示图片的中间区域
left 裁剪模式,不缩放图片,只显示图片的左边区域
right 裁剪模式,不缩放图片,只显示图片的右边区域
top left 裁剪模式,不缩放图片,只显示图片的左上边区域
top right 裁剪模式,不缩放图片,只显示图片的右上边区域
bottom left 裁剪模式,不缩放图片,只显示图片的左下边区域
bottom right 裁剪模式,不缩放图片,只显示图片的右下边区域

示例代码

TYML
<view class="page-head">
	<view class="page-head-title">image</view>
	<view class="page-head-line"></view>
</view>
 
<view class="section l-r-padding" ty:for="{{array}}" ty:key="{{item.mode}}">
  <view class="page-section-title">{{item.text}}</view>
  <view class="section__ctn">
    <image class="image" src="{{src}}" mode="{{item.mode}}" bind:load="load" bind:error="error"></image>
  </view>
</view>
JS
Page({
  data: {
    array: [
      {
        mode: 'widthFix',
        text: 'widthFix:缩放模式,宽度不变,高度自动变化,保持原图宽高比不变',
      },
      {
        mode: 'heightFix',
        text: 'heightFix:缩放模式,高度不变,宽度自动变化,保持原图宽高比不变',
      },
      {
        mode: 'scaleToFill',
        text: 'scaleToFill:不保持纵横比缩放图片,使图片完全适应',
      },
      {
        mode: 'aspectFit',
        text: 'aspectFit:保持纵横比缩放图片,使图片的长边能完全显示出来',
      },
      {
        mode: 'aspectFill',
        text: 'aspectFill:保持纵横比缩放图片,只保证图片的短边能完全显示出来',
      },
      {
        mode: 'top',
        text: 'top:不缩放图片,只显示图片的顶部区域',
      },
      {
        mode: 'bottom',
        text: 'bottom:不缩放图片,只显示图片的底部区域',
      },
      {
        mode: 'center',
        text: 'center:不缩放图片,只显示图片的中间区域',
      },
      {
        mode: 'left',
        text: 'left:不缩放图片,只显示图片的左边区域',
      },
      {
        mode: 'right',
        text: 'right:不缩放图片,只显示图片的右边边区域',
      },
      {
        mode: 'top left',
        text: 'top left:不缩放图片,只显示图片的左上边区域',
      },
      {
        mode: 'top right',
        text: 'top right:不缩放图片,只显示图片的右上边区域',
      },
      {
        mode: 'bottom left',
        text: 'bottom left:不缩放图片,只显示图片的左下边区域',
      },
      {
        mode: 'bottom right',
        text: 'bottom right:不缩放图片,只显示图片的右下边区域',
      },
    ],
    src: '/images/godzilla.png',
  },
  load: function (event) {
    console.log('demo image load', event.detail, event);
  },
  error: function (event) {
    console.log('demo image error', event.detail, event);
  },
});
TYSS
.section {
  margin-top: 20px;
}
.section__title {
  margin-bottom: 10px;
}
.image {
  height: 200px;
  width: 200px;
  background-color: #ffffff;
}
.section__ctn {
  margin-top: 15px;
  margin-bottom: 20px;
}

常见问题(FAQ)

image 支持懒加载吗?

支持,可通过配置lazy-load实现图片懒加载

真机调用 image 组件,显示的图片被压缩?

建议把 mode 值设为 widthFix。

ipc-player

基础库 2.2.0 开始支持, 低版本需做兼容处理。

实时视频播放。

相关 API:ty.createIpcPlayerContext。这是基于异层渲染的原生组件, 请注意 原生组件使用限制

属性说明

属性名 类型 默认值 必填 说明
device-id string device-id 组件的唯一标识符,必须设置该属性
autoplay boolean false 自动播放
muted boolean false 是否静音;
clarity string normal 清晰度, 可选值有normal: 标清, hd: 高清
sound-mode string speaker 声音输出方式, 可选值有speaker: 扬声器, ear: 听筒
orientation string vertical 画面方向, 可选值有 vertical: 竖直, horizontal: 水平
object-fit string contain 填充模式, 可选值有 contain: 图像长边填满屏幕,短边区域会被填充⿊⾊, fillCrop: 图像铺满屏幕,超出显示区域的部分将被截掉; 注: 如果设置了 scalable = true 和 scale-multiple >= 1,则 object-fit 不生效
auto-pause-if-navigate boolean true 当跳转到本小程序的其他页面时,是否自动暂停本页面的实时音视频播放
auto-pause-if-open-native boolean true 当跳转到 App 其它原生页面时,是否自动暂停本页面的实时音视频播放
rotate-z number 0 摄像头旋转角度,有效值 0~360 的整数
scalable boolean true 当前是否可缩放
scale-multiple number 0 缩放比例,默认值 0 为不生效, 仅当 scalable 为 true 且 scale-multiple >= 1 时生效,最大不超过 maxScaleMultiple (maxScaleMultiple 可以通过 bind:initdone 事件返回的参数进行获取); 注: 该属性生效时 object-fit 不生效
ptz-controllable boolean true 设置是否开启视频区域云平台控制
border-width number 0 边框的宽度, 单位 px
border-style string solid 边框的样式, 可选值: solid 和 dashed
border-color string #ffffff 边框的颜色, 必须为十六进制格式
border-radius number 0 边框的圆角, 单位 px
border-radius-top-left number 边框的左上角圆角大小, 单位 px
border-radius-top-right number 边框的右上角圆角大小, 单位 px
border-radius-bottom-left number 边框的左下角圆角大小, 单位 px
border-radius-bottom-right number 边框的右下角圆角大小, 单位 px
background-color string #ffffff 背景颜色, 必须为十六进制格式
bind:connectchange eventhandle 当连接状态发生变化时触发,detail = { state }, state: 0 表示连接成功
bind:previewchange eventhandle 当预览状态发生变化时触发,detail = { state }, state: 1 表示开始预览成功, state: 0 表示结束预览成功
bind:onlinechange eventhandle 当 ipc 设备在线状态变化时触发,detail = { online }, online: true 表示在线, online: false 表示离线或断电
bind:initdone eventhandle 初始化完成时触发
bind:zoomchange eventhandle 视频缩放比例及当前倍数变化,detail = { zoomLevel }, zoomLevel 为缩放比例
bind:videotap eventhandle 点击视频时触发
bind:error eventhandle 当状态异层时触发 error 事件,detail = { "errCode": 错误码 , "errMsg": 错误描述 }, 错误码见下表

错误码

说明
-1000 其他未知异常
-1001 connect 失败
-1002 开启预览失败
-1003 结束预览失败
-1004 设置静音失败
-1005 设置清晰度失败
-1006 截图失败
-1007 属性不合法
-1008 设置参数不合法
-1009 disconnect 失败
-1010 网络状态不可用
-1011 设备离线
-1012 设备被移除
-1013 startTalk fail
-1014 StopTalk fail
-1015 StartRecord fail
-1016 StopRecord fail
-1017 IsTalkBacking fail
-1018 SetAvailableRockerDirections fail
-1019 IsPTZControllable fail
-1020 SetTrackingStatus fail
-1021 GetVideoInfo fail

Bug & Tip

  1. tip:ipc-player 默认宽度 300px、高度 225px,可通过 tyss 设置宽高。
  2. tip:Tuya MiniApp Tools 上暂不支持。
  3. tip:相关原理请参考 基于异层渲染的原生组件
  4. tip:请注意 原生组件使用限制

示例代码

TYML
<view class="page-body">
  <ipc-player
    ty:if="{{isShow}}"
    class="ipc"
    device-id="{{deviceId}}"
    autoplay="{{true}}"
    auto-pause-if-navigate="{{true}}"
    auto-pause-if-open-native="{{true}}"
    object-fit="{{objectFit}}"
    orientation="{{orientation}}"
    bindconnectChange="onConnectChange"
    binderror="onError"/>
 
  <view class="btn-box">
    <button bindtap="setMuted1" class="page-body-button" type="primary">开启静音</button>
    <button bindtap="setMuted2" class="page-body-button" type="primary">关闭静音</button>
    <button bindtap="setSoundMode1" class="page-body-button" type="primary">扬声器播放</button>
    <button bindtap="setSoundMode2" class="page-body-button" type="primary">听筒播放</button>
    <button bindtap="setClarity1" class="page-body-button" type="primary">标清播放</button>
    <button bindtap="setClarity2" class="page-body-button" type="primary">高清播放</button>
    <button bindtap="orientationChange" class="page-body-button" type="primary">orientation 切换 </button>
    <button bindtap="objectFitChange" class="page-body-button" type="primary">objectFit 切换 </button>
    <button bindtap="snapshot" class="page-body-button" type="primary">截取视频影像</button>
    <view>截取视频影像如下:<view>
    <image src="{{tempImagePath}}"></image>
  </view>
</view>
JS
Page({
  data: {
    deviceId: 'vdevo164759164131606',
    tempImagePath: '',
    isShow: true,
    orientation: 'vertical',
    objectFit: 'contain',
  },
  onReady() {
    this.ctx = ty.createIpcPlayerContext(this.data.deviceId);
  },
  onUnload() {
    this.ctx.disconnect({
      success: (res) => {
        console.log('demo disconnect success');
      },
    });
  },
  initIpc() {
    this.ctx = ty.createIpcPlayerContext(this.data.deviceId);
    this.ctx.connect({
      success: (res) => {
        this.ctx.startPreview({
          success: (res) => {
            console.log('demo 开启预览成功');
          },
          fail: (res) => {
            console.log('demo 开启预览失败');
          },
        });
      },
      fail: (res) => {
        console.log('demo 建立通道连接失败');
      },
    });
  },
  onConnectChange(e) {
    console.log('demo onConnectChange 事件触发', e);
  },
  onError(e) {
    console.log('demo onError 事件触发', e);
  },
  snapshot() {
    this.ctx.snapshot({
      success: (res) => {
        console.log('demo snapshot API 调用成功', res);
        this.setData({
          tempImagePath: res.tempImagePath,
        });
      },
      fail: (res) => {
        console.log('demo snapshot API 调用失败', res);
      },
    });
  },
  setMuted1() {
    this.ctx.setMuted({
      mute: true,
      success: (res) => {
        console.log('demo setMuted API 开启成功', res);
      },
      fail: (res) => {
        console.log('demo setMuted API 开启失败', res);
      },
    });
  },
  setMuted2() {
    this.ctx.setMuted({
      mute: false,
      success: (res) => {
        console.log('demo setMuted API 关闭成功', res);
      },
      fail: (res) => {
        console.log('demo setMuted API 关闭失败', res);
      },
    });
  },
  setSoundMode1() {
    this.ctx.setSoundMode({
      mode: 'speaker',
      success: (res) => {
        console.log('demo setSoundMode API 扬声器播放成功', res);
      },
      fail: (res) => {
        console.log('demo setSoundMode API 扬声器播放失败', res);
      },
    });
  },
  setSoundMode2() {
    this.ctx.setSoundMode({
      mode: 'ear',
      success: (res) => {
        console.log('demo setSoundMode API 听筒播放成功', res);
      },
      fail: (res) => {
        console.log('demo setSoundMode API 听筒播放失败', res);
      },
    });
  },
  setClarity1() {
    this.ctx.setClarity({
      clarity: 'normal',
      success: (res) => {
        console.log('demo setClarity API 标清成功', res);
      },
      fail: (res) => {
        console.log('demo setClarity API 标清失败', res);
      },
    });
  },
  setClarity2() {
    this.ctx.setClarity({
      clarity: 'hd',
      success: (res) => {
        console.log('demo setClarity API 高清成功', res);
      },
      fail: (res) => {
        console.log('demo setClarity API 高清失败', res);
      },
    });
  },
  orientationChange() {
    this.setData({
      orientation:
        this.data.orientation == 'vertical' ? 'horizontal' : 'vertical',
    });
  },
  objectFitChange() {
    this.setData({
      objectFit: this.data.objectFit == 'contain' ? 'fillCrop' : 'contain',
    });
  },
});
JSON
{
  "navigationBarTitleText": "ipc-player"
}
TYSS
.page-body {
  display: flex;
  align-items: center;
  flex-direction: column;
  padding: 10px 20px 20px;
}
 
.ipc {
  width: 100%;
}
 
.btn-box {
  width: 100%;
  margin-top: 20px;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
 
.page-body-button {
  width: 160px;
  margin-bottom: 20px;
  display: inline-block;
  padding: 10px 20px;
}

video

视频。相关 API: ty.createVideoContext

属性 类型 默认值 必填 说明
src string 要播放视频的资源地址,支持网络路径; 注意分区部署情况下,视频是否支持访问
duration number 指定视频时长,单位秒 s
controls boolean true 是否显示默认播放控件(播放/暂停按钮、播放进度、时间)
danmu-list Array<{text, color,time}> 弹幕列表
danmu-btn boolean false 是否显示弹幕按钮,只在初始化时有效,不能动态变更
enable-danmu boolean false 是否展示弹幕,只在初始化时有效,不能动态变更
autoplay boolean false 是否自动播放
loop boolean false 是否循环播放
muted boolean false 是否静音播放
initial-time number 0 指定视频初始播放位置
show-fullscreen-btn boolean true 是否显示全屏按钮
show-play-btn boolean true 是否显示视频底部控制栏的播放按钮
show-center-play-btn boolean true 是否显示视频中间的播放按钮
object-fit string contain 当视频大小与 video 容器大小不一致时,视频的表现形式
poster string 视频封面的图片网络资源地址
show-mute-btn boolean false 是否显示静音按钮
autoPause boolean true 非可视区域是否自动暂停
border-radius number 0 指定视频 border-radius
bind:play eventhandle 当开始/继续播放时触发 play 事件
bind:pause eventhandle 当暂停播放时触发 pause 事件
bind:ended eventhandle 当播放到末尾时触发 ended 事件
bind:timeupdate eventhandle 播放进度变化时触发,event.detail = {currentTime, duration} 。
bind:waiting eventhandle 视频出现缓冲时触发
bind:error eventhandle 视频播放出错时触发
bind:progress eventhandle 加载进度变化时触发,只支持一段加载。event.detail = {buffered},百分比
bind:loadedmetadata eventhandle 视频元数据加载完成时触发。event.detail = {width, height, duration}
bind:seekcomplete eventhandler seek 完成时触发 (position iOS 单位 s, Android 单位 ms)

object-fit 的合法值

说明
contain 包含
fill 填充
cover 覆盖

Bug & Tip

tip:video 默认宽度 300px、高度 225px,可通过 tyss 设置宽高。

tip:video 支持三种视频格式:MP4、WebM、Ogg。

  • MP4 = MPEG 4 文件使用 H264 视频编解码器和 AAC 音频编解码器
  • WebM = WebM 文件使用 VP8 视频编解码器和 Vorbis 音频编解码器
  • Ogg = Ogg 文件使用 Theora 视频编解码器和 Vorbis 音频编解码器

常见问题(FAQ)

如何获取视频播放进度?

可通过bind:timeupdate 获取视频播放时长。

native-video

基础库 2.5.0 开始支持, 低版本需做兼容处理。
Tuya MiniApp Tools 上是通过 WebView 模拟的与真机存在差异,请以真机效果为主。

视频。相关 API: ty.createNativeVideoContext。这是基于异层渲染的原生组件, 请注意 原生组件使用限制

属性 类型 默认值 必填 说明
src string 要播放视频的资源地址,支持网络路径; 注意分区部署情况下,视频是否支持访问
duration number 指定视频时长,单位秒 s
controls boolean true 是否显示默认播放控件(播放/暂停按钮、播放进度、时间)
autoplay boolean false 是否自动播放
loop boolean false 是否循环播放
muted boolean false 是否静音播放
initial-time number 0 指定视频初始播放位置
show-fullscreen-btn boolean true 是否显示全屏按钮
show-play-btn boolean true 是否显示视频底部控制栏的播放按钮
show-center-play-btn boolean true 是否显示视频中间的播放按钮
object-fit string contain 当视频大小与 video 容器大小不一致时,视频的表现形式
poster string 视频封面的图片网络资源地址
show-mute-btn boolean false 是否显示静音按钮
border-width number 0 边框的宽度, 单位 px
border-style string solid 边框的样式, 可选值: solid 和 dashed
border-color string #ffffff 边框的颜色, 必须为十六进制格式
border-radius number 0 边框的圆角, 单位 px
border-radius-top-left number 边框的左上角圆角大小, 单位 px
border-radius-top-right number 边框的右上角圆角大小, 单位 px
border-radius-bottom-left number 边框的左下角圆角大小, 单位 px
border-radius-bottom-right number 边框的右下角圆角大小, 单位 px
background-color string #ffffff 背景颜色, 必须为十六进制格式
bind:play eventhandle 当开始/继续播放时触发 play 事件
bind:pause eventhandle 当暂停播放时触发 pause 事件
bind:ended eventhandle 当播放到末尾时触发 ended 事件
bind:timeupdate eventhandle 播放进度变化时触发,event.detail = {currentTime, duration} 。
bind:fullscreenchange eventhandle 视频进入和退出全屏时触发,event.detail = {fullScreen, direction},direction 有效值为 vertical 或 horizontal
bind:waiting eventhandle 视频出现缓冲时触发
bind:error eventhandle 视频播放出错时触发
bind:progress eventhandle 加载进度变化时触发,只支持一段加载。event.detail = {buffered},百分比
bind:loadedmetadata eventhandle 视频元数据加载完成时触发。event.detail = {width, height, duration}
bind:controlstoggle eventhandle 切换 controls 显示隐藏时触发。event.detail = {show}
bind:seekcomplete eventhandler seek 完成时触发 (position iOS 单位 s, Android 单位 ms)

object-fit 的合法值

说明
contain 包含
fill 填充
cover 覆盖

Bug & Tip

  1. tip:native-video 默认宽度 300px、高度 225px,可通过 tyss 设置宽高。
  2. tip:相关原理请参考 基于异层渲染的原生组件
  3. tip:请注意 原生组件使用限制
  4. tip:native-video 支持三种视频格式:MP4。
  • MP4 = MPEG 4 文件使用 H264 视频编解码器和 AAC 音频编解码器

<>立即开发

相关推荐
光路科技2 小时前
八大网络安全策略:如何防范物联网(IoT)设备带来的安全风险
物联网·安全·web安全
s甜甜的学习之旅4 小时前
Apache POI练习代码
apache
是小崔啊4 小时前
开源轮子 - Apache Common
java·开源·apache
委员6 小时前
基于NodeMCU的物联网空调控制系统设计
单片机·mcu·物联网·智能家居
逝灮8 小时前
【蓝桥杯——物联网设计与开发】拓展模块3 - 温度传感器模块
驱动开发·stm32·单片机·嵌入式硬件·物联网·蓝桥杯·温度传感器
邓校长的编程课堂9 小时前
基于树莓派Pico和声音传感器实现声控风扇的技术分享
物联网·嵌入式开发·树莓派pico·编程入门·c++编程·声音传感器·c++趣味编程
计算机徐师兄9 小时前
基于TP5框架的家具购物小程序的设计与实现【附源码、文档】
小程序·php·家具购物小程序·家具购物微信小程序·家具购物
曲辒净10 小时前
微信小程序实现二维码海报保存分享功能
微信小程序·小程序
程序猿阿伟10 小时前
《探索 Apache Spark MLlib 与 Java 结合的卓越之道》
java·spark-ml·apache
朽木成才11 小时前
小程序快速实现大模型聊天机器人
小程序·机器人