---
name: "Video"
mode: "component"
versionRequirements:
  - { name: "@ray-js/ray", version: "1.4.24" }
title: "Video - Video"
---

## Video

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

### Description

Video component supporting playback controls, bullet comments, and full screen.

### Props

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `src` | `string` | Yes | - | Source URL of the video to play; network URLs are supported |
| `duration` | `number` | No | `0` | Specify the video duration |
| `controls` | `boolean` | No | `true` | Whether to show the default controls (play/pause button, progress, time) |
| `danmuList` | `VideoDanmuItem[]` | No | - | Bullet comment list |
| `danmuBtn` | `boolean` | No | `false` | Whether to show the bullet comment button; only effective at initialization and cannot be changed dynamically |
| `enableDanmu` | `boolean` | No | `false` | Whether to display bullet comments; only effective at initialization and cannot be changed dynamically |
| `autoplay` | `boolean` | No | `false` | Whether to autoplay |
| `loop` | `boolean` | No | `false` | Whether to loop |
| `muted` | `boolean` | No | `false` | Whether to mute |
| `initialTime` | `number` | No | `0` | Initial playback position |
| `showFullscreenBtn` | `boolean` | No | `true` | Whether to show the fullscreen button |
| `showPlayBtn` | `boolean` | No | `true` | Whether to show the play button in the bottom control bar |
| `showCenterPlayBtn` | `boolean` | No | `true` | Whether to show the center play button |
| `objectFit` | `"contain" \| "fill" \| "cover"` | No | `"contain"` | How the video is fitted when its size differs from the video container |
| `poster` | `string` | No | - | URL of the video poster image |
| `showMuteBtn` | `boolean` | No | `false` | Whether to show the mute button |
| `autoPause` | `boolean` | No | `true` | Whether to auto-pause when out of the viewport |
| `onPlay` | `(event: BaseEvent) => void` | No | - | Triggers when playback starts or resumes |
| `onPause` | `(event: BaseEvent) => void` | No | - | Triggers when playback is paused |
| `onEnded` | `(event: BaseEvent) => void` | No | - | Triggers when playback reaches the end |
| `onWaiting` | `(event: BaseEvent) => void` | No | - | Triggers when buffering occurs |
| `onError` | `(event: VideoErrorEvent) => void` | No | - | Triggers on playback error |
| `onProgress` | `(event: VideoProgressEvent) => void` | No | - | Triggers when load progress changes; only a single segment is supported |
| `onLoadedmetadata` | `(event: VideoLoadedmetadataEvent) => void` | No | - | Triggers when video metadata has loaded |
| `onCanplay` | `(event: BaseEvent) => void` | No | - | Triggered when the browser can play the video |
| `onCanplayThrough` | `(event: BaseEvent) => void` | No | - | Triggered when the browser can play without stalling for buffering |
| `onPlaying` | `(event: BaseEvent) => void` | No | - | Triggered when the video is ready after being paused or stopped due to buffering |
| `onRateChange` | `(event: BaseEvent) => void` | No | - | Triggered when the playback speed changes |
| `onVolumeChange` | `(event: BaseEvent) => void` | No | - | Triggered when the volume changes |
| `onSeekComplete` | `(event: VideoSeekCompleteEvent) => void` | No | - | Triggers when seek completes |

### Referenced Types

##### `interface` VideoDanmuItem

| Property | Type | Description |
| --- | --- | --- |
| `text` | `string` | Bullet comment text |
| `color` | `string` | Bullet comment color |
| `time` | `number` | Bullet comment start time, in seconds |

##### `interface` BaseEvent

| Property | Type | Description |
| --- | --- | --- |
| `type` | `string` | Event type |
| `timeStamp` | `number` | Time in milliseconds since the page opened |
| `target` | `Target` | Source component of the event |
| `currentTarget` | `Target` | Collection of property values for the current component |
| `mark` | `any` | Event mark data |

##### `interface` VideoErrorEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `VideoErrorDetail` |  |

##### `interface` VideoProgressEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `VideoProgressDetail` |  |

##### `interface` VideoLoadedmetadataEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `VideoLoadedmetadataDetail` |  |

##### `interface` VideoSeekCompleteEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `VideoSeekCompleteDetail` |  |

##### `interface` Target

| Property | Type | Description |
| --- | --- | --- |
| `id` | `string` | id of the event source component |
| `dataset` | `Record<string, unknown>` | Collection of custom attributes from the `dataset` on the event source component |

##### `interface` VideoErrorDetail

| Property | Type | Description |
| --- | --- | --- |
| `errMsg` | `string` | Error message |

##### `interface` VideoProgressDetail

| Property | Type | Description |
| --- | --- | --- |
| `buffered` | `number` | Buffering percentage |

##### `interface` VideoLoadedmetadataDetail

| Property | Type | Description |
| --- | --- | --- |
| `width` | `number` | Video width |
| `height` | `number` | Video height |
| `duration` | `number` | Video duration |

##### `interface` VideoSeekCompleteDetail

| Property | Type | Description |
| --- | --- | --- |
| `position` | `number` | Playback position (seconds on iOS, milliseconds on Android; subject to platform) |


### Examples

#### Basic usage

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

export default function () {
  return (
    <View style={{ padding: '20px' }}>
      <Video
        src="https://images.tuyacn.com/rms-static/602542e0-48f8-11f1-95db-cfd3b8132c07-1778036702734.mp4"
        controls
        style={{ width: '100%', height: '200px' }}
        onPlay={() => console.log('Playback started')}
        onPause={() => console.log('Playback paused')}
        onEnded={() => console.log('Playback ended')}
      />
    </View>
  );
}
```

#### Playback configuration

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

export default function () {
  return (
    <View style={{ padding: '20px' }}>
      <Video
        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={5}
        objectFit="cover"
        showFullscreenBtn
        showPlayBtn
        showCenterPlayBtn={false}
        showMuteBtn
        autoPause
        style={{ width: '100%', height: '200px' }}
        onError={(e) => console.log('Playback error:', e.detail.errMsg)}
        onWaiting={() => console.log('Buffering')}
      />
    </View>
  );
}
```

#### Danmaku and events

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

export default function () {
  return (
    <View style={{ padding: '20px' }}>
      <Video
        src="https://images.tuyacn.com/rms-static/602542e0-48f8-11f1-95db-cfd3b8132c07-1778036702734.mp4"
        controls
        enableDanmu
        danmuBtn
        danmuList={[
          { text: 'Great', color: '#ff0000', time: 1 },
          { text: 'Nice', color: '#00ff00', time: 3 },
          { text: 'Awesome', color: '#0000ff', time: 5 },
        ]}
        style={{ width: '100%', height: '200px' }}
        onPlay={() => console.log('Playback started')}
        onPause={() => console.log('Paused')}
        onEnded={() => console.log('Playback ended')}
        onProgress={(e) => console.log('Buffered:', e.detail.buffered + '%')}
        onLoadedmetadata={(e) => console.log('Metadata:', e.detail.width, 'x', e.detail.height, 'Duration:', e.detail.duration)}
        onSeekComplete={(e) => console.log('Seek complete:', e.detail.position)}
      />
    </View>
  );
}
```


### Related Links

Related API: [createVideoContext](/en/miniapp/develop/miniapp/api/media/video/createVideoContext)

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

### FAQ

#### Default width, height, and supported formats of Video

1. `video` default width is 300px and height is 225px. You can set the width and height via tyss.
2. `video` supports three video formats: MP4, WebM, and Ogg.
   - MP4 = MPEG-4 files using H.264 video codec and AAC audio codec
   - WebM = WebM files using VP8 video codec and Vorbis audio codec
   - Ogg = Ogg files using Theora video codec and Vorbis audio codec

#### How do I get the video playback progress?

You can use `onTimeupdate` to get the playback duration of the video.
