# video

组件类型:UniVideoElement

视频

# 兼容性

Web Android iOS
4.0 3.9 4.11

# 属性

名称 类型 默认值 兼容性 描述
loop boolean false
是否循环播放
src string(string.VideoURIString) -
视频资源地址
initial-time number 0
指定视频初始播放位置
duration number -
指定视频长度
controls boolean true
是否显示默认播放控件(播放/暂停按钮、播放进度、时间)
danmu-list array -
弹幕列表
danmu-btn boolean false
是否显示弹幕按钮,只在初始化时有效,不能动态变更
enable-danmu boolean false
是否展示弹幕,只在初始化时有效,不能动态变更
autoplay boolean false
是否自动播放
muted boolean false
是否静音播放
page-gesture boolean false
在非全屏模式下,是否开启亮度与音量调节手势
direction number -
设置全屏时视频的方向,不指定则根据宽高比自动判断。有效值为 0(正常竖向), 90(屏幕逆时针90度), -90(屏幕顺时针90度)
show-progress boolean true
若不设置,宽度大于240时才会显示
show-fullscreen-btn boolean true
是否显示全屏按钮
show-play-btn boolean true
是否显示视频底部控制栏的播放按钮
show-center-play-btn boolean true
是否显示视频中间的播放按钮
show-loading boolean true
是否显示loading控件
enable-progress-gesture boolean true
是否开启控制进度的手势
object-fit string "contain"
当视频大小与 video 容器大小不一致时,视频的表现形式。
合法值 兼容性 描述
contain
包含
fill
填充
cover
覆盖
poster string -
视频封面的图片网络资源地址,如果 controls 属性值为 false 则设置 poster 无效
show-mute-btn boolean false
是否显示静音按钮
title string -
视频的标题,全屏时在顶部展示
play-btn-position string -
播放按钮的位置
enable-play-gesture boolean false
是否开启播放手势,即双击切换播放、暂停
auto-pause-if-navigate boolean -
当跳转到其它页面时,是否自动暂停本页面的视频
auto-pause-if-open-native boolean -
当跳转到其它小程序宿主原生页面时,是否自动暂停本页面的视频
vslide-gesture boolean false
在非全屏模式下,是否开启亮度与音量调节手势(同 page-gesture)
vslide-gesture-in-fullscreen boolean true
在全屏模式下,是否开启亮度与音量调节手势
ad-unit-id string -
视频前贴广告单元ID
poster-for-crawler string -
用于给搜索等场景作为视频封面展示,建议使用无播放 icon 的视频封面图,只支持网络地址
codec string "hardware"
解码器选择
http-cache boolean false
是否对 http、https 视频源开启本地缓存
play-strategy number 0
播放策略
is-live boolean -
是否为直播源
@loadedmetadata (event: UniVideoLoadedMetadataEvent) => void -
视频元数据加载完成时触发
@play (event: UniEvent) => void -
当开始/继续播放时触发
@pause (event: UniEvent) => void -
当暂停播放时触发
@ended (event: UniEvent) => void -
当播放到视频末尾时触发
@timeupdate (event: UniVideoTimeUpdateEvent) => void -
播放进度变化时触发,event.detail = { currentTime, duration }。触发频率 250ms 一次
@fullscreenchange (event: UniVideoFullScreenChangeEvent) => void -
当视频进入和退出全屏时触发,event.detail = { fullScreen, direction },direction取为 vertical 或 horizontal
@waiting (event: UniEvent) => void -
视频出现缓冲时触发
@error (event: UniVideoErrorEvent) => void -
播放出错时触发
@progress (event: UniVideoProgressEvent) => void -
加载进度变化时触发,只支持一段加载。event.detail = { buffered },百分比
@fullscreenclick (event: UniVideoFullScreenClickEvent) => void -
视频全屏播放时点击屏幕触发。event.detail = { screenX, screenY, screenWidth, screenHeight }
@controlstoggle (event: UniVideoControlsToggleEvent) => void -
切换 controls 显示隐藏时触发。event.detail = { show }

# 事件

# UniVideoTimeUpdateEvent

timeupdate 事件
播放进度变化时触发

# UniVideoTimeUpdateEvent 的属性值
名称 类型 必填 默认值 兼容性 描述
detail UniVideoTimeUpdateEventDetail - - -
名称 类型 必备 默认值 兼容性 描述
currentTime number - - 当前进度
duration number - - 总进度
bubbles boolean - - 是否冒泡
cancelable boolean - - 是否可以取消
type string - - 事件类型
target UniElement - - 触发事件的组件
currentTarget UniElement - - 当前组件
timeStamp Long - - 事件发生时的时间戳
# UniVideoTimeUpdateEvent 的方法
名称 类型 必填 默认值 兼容性 描述
stopPropagation () => void - - 阻止当前事件的进一步传播
preventDefault () => void - - 阻止当前事件的默认行为

# UniVideoFullScreenChangeEvent

fullscreenchange 事件
当视频进入和退出全屏是触发

# UniVideoFullScreenChangeEvent 的属性值
名称 类型 必填 默认值 兼容性 描述
detail UniVideoFullScreenChangeEventDetail - - -
名称 类型 必备 默认值 兼容性 描述
fullScreen boolean - - 是否全屏
direction string - - 横竖屏,取值 vertical 或 horizontal
bubbles boolean - - 是否冒泡
cancelable boolean - - 是否可以取消
type string - - 事件类型
target UniElement - - 触发事件的组件
currentTarget UniElement - - 当前组件
timeStamp Long - - 事件发生时的时间戳
# UniVideoFullScreenChangeEvent 的方法
名称 类型 必填 默认值 兼容性 描述
stopPropagation () => void - - 阻止当前事件的进一步传播
preventDefault () => void - - 阻止当前事件的默认行为

# UniVideoErrorEvent

error 事件
视频播放出错时触发

# UniVideoErrorEvent 的属性值
名称 类型 必填 默认值 兼容性 描述
detail VideoError - - -
名称 类型 必备 默认值 兼容性 描述
errCode number - - 统一错误码
100001 网络错误
200001 内部错误
300001 SDK错误
合法值 兼容性 描述
100001 - -
200001 - -
300001 - -
errSubject string - - 统一错误主题(模块)名称
data any - - 错误信息中包含的数据
cause Error - - 源错误信息,可以包含多个错误,详见SourceError
errMsg string - - -
bubbles boolean - - 是否冒泡
cancelable boolean - - 是否可以取消
type string - - 事件类型
target UniElement - - 触发事件的组件
currentTarget UniElement - - 当前组件
timeStamp Long - - 事件发生时的时间戳
# UniVideoErrorEvent 的方法
名称 类型 必填 默认值 兼容性 描述
stopPropagation () => void - - 阻止当前事件的进一步传播
preventDefault () => void - - 阻止当前事件的默认行为

# UniVideoProgressEvent

progress 事件
加载进度变化时触发

# UniVideoProgressEvent 的属性值
名称 类型 必填 默认值 兼容性 描述
detail UniVideoProgressEventDetail - - -
名称 类型 必备 默认值 兼容性 描述
buffered number - - 加载进度百分比
bubbles boolean - - 是否冒泡
cancelable boolean - - 是否可以取消
type string - - 事件类型
target UniElement - - 触发事件的组件
currentTarget UniElement - - 当前组件
timeStamp Long - - 事件发生时的时间戳
# UniVideoProgressEvent 的方法
名称 类型 必填 默认值 兼容性 描述
stopPropagation () => void - - 阻止当前事件的进一步传播
preventDefault () => void - - 阻止当前事件的默认行为

# UniVideoFullScreenClickEvent

fullscreenclick 事件
视频播放全屏播放时点击事件

# UniVideoFullScreenClickEvent 的属性值
名称 类型 必填 默认值 兼容性 描述
detail UniVideoFullScreenClickEventDetail - - -
名称 类型 必备 默认值 兼容性 描述
screenX number - - 点击点相对于屏幕左侧边缘的 X 轴坐标
screenY number - - 点击点相对于屏幕顶部边缘的 Y 轴坐标
screenWidth number - - 屏幕总宽度
screenHeight number - - 屏幕总高度
bubbles boolean - - 是否冒泡
cancelable boolean - - 是否可以取消
type string - - 事件类型
target UniElement - - 触发事件的组件
currentTarget UniElement - - 当前组件
timeStamp Long - - 事件发生时的时间戳
# UniVideoFullScreenClickEvent 的方法
名称 类型 必填 默认值 兼容性 描述
stopPropagation () => void - - 阻止当前事件的进一步传播
preventDefault () => void - - 阻止当前事件的默认行为

# UniVideoControlsToggleEvent

controlstoggle 事件
切换播放控件显示隐藏时触发

# UniVideoControlsToggleEvent 的属性值
名称 类型 必填 默认值 兼容性 描述
detail UniVideoControlsToggleEventDetail - - -
名称 类型 必备 默认值 兼容性 描述
show boolean - - 是否显示
bubbles boolean - - 是否冒泡
cancelable boolean - - 是否可以取消
type string - - 事件类型
target UniElement - - 触发事件的组件
currentTarget UniElement - - 当前组件
timeStamp Long - - 事件发生时的时间戳
# UniVideoControlsToggleEvent 的方法
名称 类型 必填 默认值 兼容性 描述
stopPropagation () => void - - 阻止当前事件的进一步传播
preventDefault () => void - - 阻止当前事件的默认行为

# 视频格式

web端支持的视频格式,不同浏览器有差异,可查询caniuse。

app端支持的视频格式如下:

  • mp4
  • m4v
  • mov
  • webm (安卓端支持,iOS端不支持)
  • 3gp
  • flv
  • m3u8 (本地m3u8文件安卓端需3.99+,iOS端需4.11+)

# src路径支持说明

  • 本地路径/static方式
    由于uni-app/uni-app x编译时,只把/static目录下的静态资源copy到app中,所以src均需指向/static目录下。
    其他目录的视频文件由于不会被打包进去,所以无法访问。
    app平台文件路径会存在大小写敏感问题,为了有更好的兼容性,建议统一按大小写敏感原则处理 详情

  • 支持网络路径
    网络媒体 http、https协议
    流媒体 rtmp/hls/rtsp 协议

# app平台组件实现

App-Android平台video组件使用ijkplayer库实现:https://github.com/bilibili/ijkplayer

弹幕功能使用DanmakuFlameMaster库实现:https://github.com/bilibili/DanmakuFlameMaster

ijkplayer库底层又使用了ffmpeg,这些库的功能较多,官方的video组件并非完全封装。有需要的开发者可以使用uts直接操作这些库。插件市场已经有一批uts库直接调用该库,见插件市场

video组件的源码详见。下载该uni_modules到工程下,修改源码打包,可覆盖内置的video组件。

另外ijkplayer作为一个开源库,比腾讯视频等商业sdk仍有差距。如无法在开源库上满足需求,可在插件市场寻找其他插件:见插件市场视频播放

# 子组件

支持所有组件

  • App-Android平台需HBuilderX 4.25+
  • App-iOS平台需HBuilderX 4.33+

子组件,可自定义视频全屏时的UI表现。开发者可以通过子组件替换默认的控件样式以及进一步扩展组件能力。hello uni-app x中给出了如何通过子组件实现自定义快进、快退控件的示例。

# 上下文对象API

video的操作api为uni.createVideoContext()

给video组件设一个id属性,将id的值传入uni.createVideoContext(),即可得到video组件的上下文对象,进一步可使用.play().stop()等方法。

# 示例

hello uni-app x

扫码体验(手机浏览器跳转到App直达页)

Template

Script

<template>
  <view class="uni-flex-item">
    <video class="video" ref="video" id="video" :header="header" :src=src :autoplay="autoplay" :loop="loop"
      :muted="muted" :initial-time="initialTime" :duration="duration" :controls="controls" :danmu-btn="danmuBtn"
      :enable-danmu="enableDanmu" :page-gesture="pageGesture" :direction="direction" :show-progress="showProgress"
      :show-fullscreen-btn="showFullscreenBtn" :show-play-btn="showPlayBtn" :show-center-play-btn="showCenterPlayBtn"
      :show-loading="showLoading" :enable-progress-gesture="enableProgressGesture" :object-fit="objectFit"
      :poster="poster" :show-mute-btn="showMuteBtn" :title="title" :enable-play-gesture="enablePlayGesture"
      :vslide-gesture="vslideGesture" :vslide-gesture-in-fullscreen="vslideGestureInFullscreen" :codec="codec"
      :http-cache="httpCache" :play-strategy="playStrategy" :danmu-list="danmuList" @play="onPlay" @pause="onPause"
      @ended="onEnded" @timeupdate="onTimeUpdate" @waiting="onWaiting" @error="onError" @progress="onProgress"
      @fullscreenclick="onFullScreenClick" @controlstoggle="onControlsToggle" @fullscreenchange="onFullScreenChange">
      <!-- #ifdef APP -->
      <image v-if="subCompEnable && subCompShow" class="img-fast-backward"
        src="../../../static/test-video/fast-backward.png" @tap="fastBackward"></image>
      <image v-if="subCompEnable && subCompShow" class="img-fast-forward"
        src="../../../static/test-video/fast-forward.png" @tap="fastForward"></image>
      <input id="input-send-danmu" class="input-send-danmu" v-if="subCompEnable && subCompShow" placeholder="请输入弹幕内容"
        placeholder-style="color: white;" confirm-type="send" @confirm="onSendDanmuConfirm"
        @keyboardheightchange="onSendDanmuKeyboardHeightChange" @blur="onSendDanmuBlur"></input>
      <!-- #endif -->
    </video>
    <scroll-view class="uni-padding-wrap uni-common-mt uni-flex-item">
      <view class="uni-btn-v">
        <navigator url="/pages/component/video/video-format">
          <button type="primary" @click="pause">视频格式示例</button>
        </navigator>
      </view>
      <!-- #ifdef APP -->
      <view class="uni-flex uni-btn-v" style="justify-content: space-between;align-items: center;">
        <text class="uni-title" style="width: 80%;">子组件实现快进、快退、发送弹幕功能(全屏后显示)</text>
        <switch :checked="subCompEnable" @change="onSubCompEnableChange" />
      </view>
      <!-- #endif -->
      <view class="uni-title">
        <text class="uni-title-text">API示例</text>
      </View>
      <view class="uni-btn-v">
        <button type="primary" @click="play">播放</button>
      </view>
      <view class="uni-btn-v">
        <button type="primary" @click="pause">暂停</button>
      </view>
      <view class="uni-btn-v">
        <input class="input" placeholder="输入要跳转的位置,单位s" type="number" @input="onSeekInput"></input>
        <button type="primary" @click="seek(this.pos)">跳转到指定位置</button>
      </view>
      <view class="uni-btn-v">
        <enum-data title="选择进入全屏时的视频方向" :items="directionItemTypes"
          @change="onRequestFullScreenDirectionChange"></enum-data>
        <button type="primary" @click="requestFullScreen">进入全屏</button>
      </view>
      <view class="uni-btn-v">
        <button type="primary" @click="exitFullScreen">退出全屏</button>
      </view>
      <view class="uni-btn-v">
        <button type="primary" @click="stop">停止</button>
      </view>
      <view class="uni-btn-v">
        <input class="input" placeholder="输入弹幕" value="{ 'text': '要显示的文本', 'color': '#FF0000' }" type="string"
          @input="onSendDanmuInput"></input>
        <button type="primary" :disabled="!enableDanmu" @click="sendDanmu">发送弹幕</button>
      </view>
      <view class="uni-btn-v">
        <enum-data title="选择倍速" :items="rateItemTypes" @change="onPlaybackRateChange"></enum-data>
        <button type="primary" @click="playbackRate">设置倍速</button>
      </view>
      <view class="uni-title">
        <text class="uni-title-text">属性示例</text>
      </view>
      <input class="input margin-10" type="string" placeholder="设置播放资源" @confirm="onSrcComfirm"></input>
      <input class="input margin-10" type="number" placeholder="设置初始播放位置(播放前设置有效)"
        @confirm="onInitialTimeComfirm"></input>
      <input class="input margin-10" type="number" placeholder="设置视频时长(播放前设置有效)" @confirm="onDurationComfirm"></input>
      <input class="input margin-10" type="string" placeholder="设置视频封面" @confirm="onPosterComfirm"></input>
      <input class="input margin-10" type="string" placeholder="设置视频标题(仅限非 Web 平台)" @confirm="onTitleComfirm"></input>
      <input class="input margin-10" type="string" placeholder="设置header(json格式)" @confirm="onHeaderComfirm"></input>
      <boolean-data title="设置是否展示弹幕(播放前设置有效)" :defaultValue="enableDanmu" @change="onEnableDanmuChange"></boolean-data>
      <boolean-data title="设置是否自动播放(播放前设置有效)" :defaultValue="autoplay" @change="onAutoplayChange"></boolean-data>
      <boolean-data title="设置是否循环播放(播放完成后生效)" :defaultValue="loop" @change="onLoopChange"></boolean-data>
      <boolean-data title="设置是否静音播放" :defaultValue="muted" @change="onMutedChange"></boolean-data>
      <boolean-data title="设置是否显示默认播放控件" :defaultValue="controls" @change="onControlsChange"></boolean-data>
      <boolean-data title="设置是否显示弹幕按钮" :defaultValue="danmuBtn" @change="onDanmuBtnChange"></boolean-data>
      <boolean-data title="设置是否显示进度条" :defaultValue="showProgress" @change="onShowProgressChange"></boolean-data>
      <boolean-data title="设置是否显示全屏按钮" :defaultValue="showFullscreenBtn"
        @change="onShowFullscreenBtnChange"></boolean-data>
      <boolean-data title="设置是否显示视频底部控制栏的播放按钮" :defaultValue="showPlayBtn" @change="onShowPlayBtnChange"></boolean-data>
      <boolean-data title="设置是否显示静音按钮(仅限非 Web 平台)" :defaultValue="showMuteBtn"
        @change="onShowMuteBtnChange"></boolean-data>
      <enum-data title="设置全屏时视频的方向" :items="directionItemTypes" @change="onDirectionChange"></enum-data>
      <boolean-data title="设置是否显示视频中间的播放按钮" :defaultValue="showCenterPlayBtn"
        @change="onShowCenterPlayBtnChange"></boolean-data>
      <boolean-data title="设置是否显示loading控件" :defaultValue="showLoading" @change="onShowLoadingChange"></boolean-data>
      <boolean-data title="设置是否开启控制进度的手势" :defaultValue="enableProgressGesture"
        @change="onEnableProgressGestureChange"></boolean-data>
      <boolean-data title="设置是否开启播放手势(仅限非 Web 平台)" :defaultValue="enablePlayGesture"
        @change="onEnablePlayGestureChange"></boolean-data>
      <!-- #ifndef WEB -->
      <boolean-data title="非全屏模式下,设置是否开启亮度与音量调节手势" :defaultValue="pageGesture"
        @change="onPageGestureChange"></boolean-data>
      <!-- #endif -->
      <boolean-data title="非全屏模式下,设置是否开启亮度与音量调节手势(仅限非 Web 平台)" :defaultValue="vslideGesture"
        @change="onVslideGestureChange"></boolean-data>
      <boolean-data title="全屏模式下,设置是否开启亮度与音量调节手势(仅限非 Web 平台)" :defaultValue="vslideGestureInFullscreen"
        @change="onVslideGestureInFullscreenChange"></boolean-data>
      <boolean-data title="设置是否对http、https视频源开启本地缓存(仅 App 平台,播放前设置有效)" :defaultValue="httpCache"
        @change="onHttpCacheChange"></boolean-data>
      <enum-data title="设置视频大小与video容器大小不一致时,视频的表现形式" :items="objectFitItemTypes"
        @change="onObjectFitChange"></enum-data>
      <enum-data title="设置解码器(仅 App 平台,播放前设置有效)" :items="codecItemTypes" @change="onCodecChange"></enum-data>
      <enum-data title="设置播放策略(仅 App 平台,播放前设置有效)" :items="playStrategyItemTypes"
        @change="onPlayStrategyChange"></enum-data>
    </scroll-view>
  </view>
</template>



<style>
  .video {
    width: 100%;
    height: 200px;
  }

  .input {
    height: 40px;
    background: #FFF;
    padding: 8px 13px;
  }

  .margin-10 {
    margin: 10px;
  }

  .img-fast-backward {
    width: 40px;
    height: 40px;
    top: 50%;
    left: 12%;
    transform: translate(-50%, -50%);
    position: absolute;
  }

  .img-fast-forward {
    width: 40px;
    height: 40px;
    top: 50%;
    right: 12%;
    transform: translate(50%, -50%);
    position: absolute;
  }

  .input-send-danmu {
    height: 40px;
    padding: 8px 13px;
    margin: 0 var(--status-bar-height);
    bottom: 50px;
    position: absolute;
    background-color: rgba(0, 0, 0, 0.5);
    color: #FFF;
  }
</style>

# 参见

# Bug & Tips

  • App-iOS平台暂不支持横屏全屏后放置子组件
  • 标准运行基座默认不包含intel x86 cpu的兼容so库,所以video组件在标准基座运行时无法在x86 cpu的设备上运行(常见于模拟器)。如需支持x86 cpu,请在manifest里配置abiFilters,打包或自定义基座后生效 详见
  • App默认拦截触摸事件,目前会导致父组件无法响应触摸事件
  • video 默认宽度为300px,高度为225px。(App平台从 uni-app x 4.0起支持该默认宽高)

# 本地文件播放

本地视频文件,有2种方式:

  • static目录下(项目下或uni_modules下都支持static目录)
  • 使用绝对路径。相对路径转绝对路径详见