---
name: "video"
mode: "component"
versionRequirements:
  - { name: "Base Library", version: "2.10.0" }
title: "video - Video"
---

## video

> [VERSION] Base Library >= 2.10.0

### Description

Video component supporting playback controls, bullet comments (danmaku), and fullscreen.

### Props

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `src` | `string` | Yes | - | Video source URL. |
| `poster` | `string` | No | - | Cover image URL |
| `controls` | `boolean` | No | `true` | Whether to show default playback controls. |
| `duration` | `number` | No | `0` | Specified video duration |
| `autoplay` | `boolean` | No | `false` | Whether to autoplay |
| `loop` | `boolean` | No | `false` | Whether to loop |
| `muted` | `boolean` | No | `false` | Whether to play muted |
| `initial-time` | `number` | No | `0` | Initial playback position, in seconds |
| `object-fit` | `string` | No | `"contain"` | Behavior when the video size differs from the video container. Options: contain, fill, cover |
| `danmu-list` | `any[]` | No | `[]` | Bullet comment list |
| `danmu-btn` | `boolean` | No | `false` | Whether to show the bullet comment button |
| `enable-danmu` | `boolean` | No | `false` | Whether to display bullet comments |
| `show-fullscreen-btn` | `boolean` | No | `true` | Whether to show the fullscreen button |
| `show-play-btn` | `boolean` | No | `true` | Whether to show the play button in the bottom control bar |
| `show-mute-btn` | `boolean` | No | `false` | Whether to show the mute button |
| `show-center-play-btn` | `boolean` | No | `true` | Whether to show the play button in the center of the video |
| `auto-pause` | `boolean` | No | `true` | Whether to automatically pause when leaving the page |

#### Events

| Event | Type | Description |
| --- | --- | --- |
| `play` | `(event: Object) => void` | Fires when playback starts or resumes |
| `pause` | `(event: Object) => void` | Fires on pause |
| `ended` | `(event: Object) => void` | Fires when playback ends |
| `timeupdate` | `(event: VideoTimeupdateEvent) => void` | Triggered when the playback progress changes |
| `waiting` | `(event: Object) => void` | Triggered when buffering occurs |
| `error` | `(event: VideoErrorEvent) => void` | Triggered when a playback error occurs |
| `progress` | `(event: VideoProgressEvent) => void` | Fires when loading progress changes |
| `loadedmetadata` | `(event: VideoLoadedmetadataEvent) => void` | Triggered when video metadata is loaded |
| `seekcomplete` | `(event: Object) => void` | Triggered when seek completes |

**play callback object**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"play"` |  |

**pause callback object**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"pause"` |  |

**ended callback object**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"ended"` |  |

**VideoTimeupdateEvent**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"timeupdate"` | Event type |
| `detail` | `VideoTimeupdateDetail` | Event data |

**waiting callback object**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"waiting"` |  |

**VideoErrorEvent**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"error"` | Event type |
| `detail` | `VideoErrorDetail` | Event data |

**VideoProgressEvent**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"progress"` | Event type |
| `detail` | `VideoProgressDetail` | Event data |

**VideoLoadedmetadataEvent**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"loadedmetadata"` | Event type |
| `detail` | `VideoLoadedmetadataDetail` | Event data |

**seekcomplete callback object**

| Field | Type | Description |
| --- | --- | --- |
| `type` | `"seekcomplete"` |  |

### Examples

#### Basic usage

*index.tyml*

```xml
<video
  src="{{videoSrc}}"
  controls="{{true}}"
  class="video"
  bindplay="onPlay"
  bindpause="onPause"
  bindended="onEnded"
/>
```

*index.tyss*

```css
.video {
  width: 100%;
  height: 400rpx;
}
```

*index.js*

```javascript
Page({
  data: {
    videoSrc: 'https://images.tuyacn.com/rms-static/602542e0-48f8-11f1-95db-cfd3b8132c07-1778036702734.mp4',
  },
  onPlay() {
    console.log('Start playing');
  },
  onPause() {
    console.log('Paused');
  },
  onEnded() {
    console.log('Playback ended');
  },
});
```

#### Playback configuration and poster

*index.tyml*

```xml
<video
  src="{{videoSrc}}"
  poster="{{posterUrl}}"
  controls="{{true}}"
  autoplay="{{false}}"
  loop="{{true}}"
  muted="{{true}}"
  initial-time="{{5}}"
  object-fit="cover"
  show-fullscreen-btn="{{true}}"
  show-play-btn="{{true}}"
  show-center-play-btn="{{false}}"
  show-mute-btn="{{true}}"
  class="video"
  binderror="onError"
  bindwaiting="onWaiting"
/>
```

*index.tyss*

```css
.video {
  width: 100%;
  height: 400rpx;
}
```

*index.js*

```javascript
Page({
  data: {
    videoSrc: 'https://images.tuyacn.com/rms-static/602542e0-48f8-11f1-95db-cfd3b8132c07-1778036702734.mp4',
    posterUrl: 'https://vjs.zencdn.net/v/oceans.png',
  },
  onError(e) {
    console.log('Playback error:', e.detail.errMsg);
  },
  onWaiting() {
    console.log('Buffering');
  },
});
```

#### Bullet comments and events

*index.tyml*

```xml
<video
  src="{{videoSrc}}"
  controls="{{true}}"
  enable-danmu="{{true}}"
  danmu-btn="{{true}}"
  danmu-list="{{danmuList}}"
  class="video"
  bindprogress="onProgress"
  bindloadedmetadata="onLoadedmetadata"
  bindseekcomplete="onSeekComplete"
/>
```

*index.tyss*

```css
.video {
  width: 100%;
  height: 400rpx;
}
```

*index.js*

```javascript
Page({
  data: {
    videoSrc: 'https://images.tuyacn.com/rms-static/602542e0-48f8-11f1-95db-cfd3b8132c07-1778036702734.mp4',
    danmuList: [
      { text: 'Exciting', color: '#ff0000', time: 1 },
      { text: 'Nice', color: '#00ff00', time: 3 },
      { text: 'Awesome', color: '#0000ff', time: 5 },
    ],
  },
  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() {
    console.log('Seek completed');
  },
});
```


### Related Documents

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

### Notes

1. `video` has a default width of 300px and height of 225px. You can set the dimensions via tyss.

2. `video` supports three video formats: MP4, WebM, and Ogg.

- MP4 = MPEG-4 files using H264 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

### FAQ

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

You can use `bind:timeupdate` to get the video playback duration.
