---
name: "NativeVideo"
mode: "component"
versionRequirements:
  - { name: "@ray-js/ray", version: "0.6.9" }
title: "NativeVideo - 视频"
---

## NativeVideo

> [VERSION] @ray-js/ray >= 0.6.9

### 描述

原生视频播放组件。

### 属性

| 属性 | 类型 | 必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `src` | `string` | 是 | - | 要播放视频的资源地址，支持网络路径；注意分区部署情况下视频是否支持访问 |
| `duration` | `number` | 否 | - | 指定视频时长，单位秒 |
| `controls` | `boolean` | 否 | `true` | 是否显示默认播放控件（播放/暂停按钮、播放进度、时间） |
| `autoplay` | `boolean` | 否 | `false` | 是否自动播放 |
| `loop` | `boolean` | 否 | `false` | 是否循环播放 |
| `muted` | `boolean` | 否 | `false` | 是否静音播放 |
| `initialTime` | `number` | 否 | `0` | 指定视频初始播放位置 |
| `showFullscreenBtn` | `boolean` | 否 | `true` | 是否显示全屏按钮 |
| `showPlayBtn` | `boolean` | 否 | `true` | 是否显示视频底部控制栏的播放按钮 |
| `showCenterPlayBtn` | `boolean` | 否 | `true` | 是否显示视频中间的播放按钮 |
| `objectFit` | `"contain" \| "fill" \| "cover" \| "none"` | 否 | `"contain"` | 当视频大小与 video 容器大小不一致时，视频的表现形式 |
| `poster` | `string` | 否 | - | 视频封面图资源地址 |
| `showMuteBtn` | `boolean` | 否 | `false` | 是否显示静音按钮 |
| `borderWidth` | `number` | 否 | `0` | 边框的宽度，单位 px |
| `borderStyle` | `"solid" \| "dashed"` | 否 | `"solid"` | 边框的样式，可选值 solid 和 dashed |
| `borderColor` | `string` | 否 | `"#ffffff"` | 边框的颜色，必须为十六进制格式 |
| `borderRadius` | `number` | 否 | `0` | 边框的圆角，单位 px |
| `borderRadiusTopLeft` | `number` | 否 | - | 边框的左上角圆角大小，单位 px |
| `borderRadiusTopRight` | `number` | 否 | - | 边框的右上角圆角大小，单位 px |
| `borderRadiusBottomLeft` | `number` | 否 | - | 边框的左下角圆角大小，单位 px |
| `borderRadiusBottomRight` | `number` | 否 | - | 边框的右下角圆角大小，单位 px |
| `backgroundColor` | `string` | 否 | `"#ffffff"` | 背景颜色，必须为十六进制格式 |
| `onPlay` | `() => void` | 否 | - | 当开始/继续播放时触发 |
| `onPause` | `() => void` | 否 | - | 当暂停播放时触发 |
| `onEnded` | `() => void` | 否 | - | 当播放到末尾时触发 |
| `onTimeupdate` | `(event: NativeVideoTimeUpdateEvent) => void` | 否 | - | 播放进度变化时触发 |
| `onFullscreenchange` | `(event: NativeVideoFullscreenChangeEvent) => void` | 否 | - | 视频进入和退出全屏时触发 |
| `onWaiting` | `() => void` | 否 | - | 视频出现缓冲时触发 |
| `onError` | `(event: NativeVideoErrorEvent) => void` | 否 | - | 视频播放出错时触发 |
| `onProgress` | `(event: NativeVideoProgressEvent) => void` | 否 | - | 加载进度变化时触发，只支持一段加载 |
| `onLoadedmetadata` | `(event: NativeVideoLoadedMetadataEvent) => void` | 否 | - | 视频元数据加载完成时触发 |
| `onControlstoggle` | `(event: NativeVideoControlsToggleEvent) => void` | 否 | - | 切换 controls 显示隐藏时触发 |
| `onSeekcomplete` | `(event: NativeVideoSeekCompleteEvent) => void` | 否 | - | seek 完成时触发 |
| `updateLayout` | `unknown` | 否 | - | 用来异层组件通知容器层样式更新 |

### 引用对象

##### `interface` NativeVideoTimeUpdateEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `NativeVideoTimeUpdateDetail` | 事件数据 |

##### `interface` NativeVideoFullscreenChangeEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `NativeVideoFullscreenChangeDetail` | 事件数据 |

##### `interface` NativeVideoErrorEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `NativeVideoErrorDetail` | 事件数据 |

##### `interface` NativeVideoProgressEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `NativeVideoProgressDetail` | 事件数据 |

##### `interface` NativeVideoLoadedMetadataEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `NativeVideoLoadedMetadataDetail` | 事件数据 |

##### `interface` NativeVideoControlsToggleEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `NativeVideoControlsToggleDetail` | 事件数据 |

##### `interface` NativeVideoSeekCompleteEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `detail` | `NativeVideoSeekCompleteDetail` | 事件数据 |

##### `interface` NativeVideoTimeUpdateDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `currentTime` | `number` | 当前播放进度，单位秒 |
| `duration` | `number` | 视频总时长，单位秒 |

##### `interface` BaseEvent

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `type` | `string` | 事件类型 |
| `timeStamp` | `number` | 页面打开到触发事件所经过的毫秒数 |
| `target` | `Target` | 触发事件的源组件 |
| `currentTarget` | `Target` | 当前组件的一些属性值集合 |
| `mark` | `any` | 事件标记数据 |

##### `interface` NativeVideoFullscreenChangeDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `fullScreen` | `boolean` | 是否全屏 |
| `direction` | `"vertical" \| "horizontal"` | 方向，有效值为 vertical 或 horizontal |

##### `interface` NativeVideoErrorDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `errMsg` | `string` | 错误信息 |

##### `interface` NativeVideoProgressDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `buffered` | `number` | 缓冲进度百分比 |

##### `interface` NativeVideoLoadedMetadataDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `width` | `number` | 视频宽度 |
| `height` | `number` | 视频高度 |
| `duration` | `number` | 视频时长 |

##### `interface` NativeVideoControlsToggleDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `show` | `boolean` | 是否显示控件 |

##### `interface` NativeVideoSeekCompleteDetail

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `position` | `number` | 跳转后的播放位置 |

##### `interface` Target

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `id` | `string` | 事件源组件的id |
| `dataset` | `Record<string, unknown>` | 事件源组件上的 `dataset` 自定义属性组成的集合 |


### 示例代码

#### 基础用法

```tsx
import React from 'react';
import { NativeVideo, View } from '@ray-js/ray';

export default function () {
  return (
    <View style={{ padding: '20px' }}>
      <NativeVideo
        src="https://images.tuyacn.com/rms-static/602542e0-48f8-11f1-95db-cfd3b8132c07-1778036702734.mp4"
        controls
        style={{ width: '100%', height: '200px' }}
        onPlay={() => console.log('开始播放')}
        onPause={() => console.log('暂停播放')}
        onEnded={() => console.log('播放结束')}
      />
    </View>
  );
}
```

#### 播放配置与封面

```tsx
import React from 'react';
import { NativeVideo, View } from '@ray-js/ray';

export default function () {
  return (
    <View style={{ padding: '20px' }}>
      <NativeVideo
        src="https://images.tuyacn.com/rms-static/602542e0-48f8-11f1-95db-cfd3b8132c07-1778036702734.mp4"
        poster="https://vjs.zencdn.net/v/oceans.png"
        controls
        autoplay={false}
        loop
        muted
        initialTime={3}
        objectFit="cover"
        showFullscreenBtn
        showPlayBtn
        showCenterPlayBtn={false}
        showMuteBtn
        style={{ width: '100%', height: '200px' }}
        onError={(e) => console.log('播放错误:', e.detail.errMsg)}
        onWaiting={() => console.log('缓冲中')}
        onTimeupdate={(e) => console.log('进度:', e.detail.currentTime, '/', e.detail.duration)}
      />
    </View>
  );
}
```

#### 自定义边框与事件

```tsx
import React from 'react';
import { NativeVideo, View } from '@ray-js/ray';

export default function () {
  return (
    <View style={{ padding: '20px' }}>
      <NativeVideo
        src="https://images.tuyacn.com/rms-static/602542e0-48f8-11f1-95db-cfd3b8132c07-1778036702734.mp4"
        controls
        borderWidth={2}
        borderStyle="dashed"
        borderColor="#1890ff"
        borderRadius={16}
        backgroundColor="#000000"
        style={{ width: '100%', height: '200px' }}
        onPlay={() => console.log('播放')}
        onPause={() => console.log('暂停')}
        onEnded={() => console.log('结束')}
        onFullscreenchange={(e) => console.log('全屏:', e.detail.fullScreen, '方向:', e.detail.direction)}
        onControlstoggle={(e) => console.log('控件显示:', e.detail.show)}
        onProgress={(e) => console.log('缓冲:', e.detail.buffered + '%')}
        onLoadedmetadata={(e) => console.log('元数据:', e.detail.width, 'x', e.detail.height)}
        onSeekcomplete={(e) => console.log('seek:', e.detail.position)}
      />
    </View>
  );
}
```


### 相关链接

相关 API: [createNativeVideoContext](/cn/miniapp/develop/miniapp/api/media/native-video/createNativeVideoContext)。这是基于异层渲染的原生组件, 请注意 [原生组件使用限制](/cn/miniapp/develop/miniapp/component/native-component/native-component)。

<DemoBlock 
  githubUrl="https://github.com/Tuya-Community/tuya-miniapp-demo/tree/master/rayVideo" 
  qrCodeUrl="/images/qrCode/rayVideo.png" 
  lang="zh">
</DemoBlock>

### 常见问题

1. `native-video` 默认宽度 300px、高度 225px，可通过 tyss 设置宽高。
2. 相关原理请参考 [基于异层渲染的原生组件](/cn/miniapp/develop/miniapp/component/native-component/native-component)。
3. 请注意 [原生组件使用限制](/cn/miniapp/develop/miniapp/component/native-component/native-component)。
4. `native-video` 支持的视频格式：MP4（MPEG 4 文件使用 H264 视频编解码器和 AAC 音频编解码器）。
