You need to enable JavaScript to run this app.
导航
微信小程序直播拉流 UI 实现最佳实践
最近更新时间:2025.07.04 17:12:55首次发布时间:2024.03.06 19:52:42
复制全文
我的收藏
有用
有用
无用
无用

本文介绍如何使用 veplayer-live-mp-wx 组件,在微信小程序中实现直播拉流页面。文中提供了适配竖屏、横屏、沉浸式、低延迟等不同业务场景的 UI 示例,配合导航与消息组件,帮助你快速构建完整的直播观看体验。

适用场景

适用于以下场景中的微信小程序直播拉流功能:

场景类型说明
竖屏直播间适合内容展示类直播(如美妆等),可结合操作按钮展示在播放器下方。
横屏直播间常用于教育培训等场景,播放器位于页面上方,下方展示业务模块或互动内容。
全屏沉浸式观看播放器铺满整个页面,适合用户点击全屏后沉浸式观看。
低延迟拉流适用于互动性要求较高的场景,可启用 RTC 模式并设置合适缓存参数以降低延迟。

实现方案概览

  • 播放器核心组件:ve-live-player
  • 交互控制推荐:结合系统 API 实现全屏、静音、刷新等操作。
  • 样式适配方案:通过配置 fit-video-sizeobject-fit 实现布局控制。
  • 可复用 UI:如自定义导航栏组件 nav、消息互动组件 message

竖屏播放页面实现

竖屏播放页面适用于大多数移动场景。下方以不同布局方式展示典型竖屏直播间的实现方式,帮助你灵活适配业务场景。

上半屏播放

播放器位于页面上半部分,适合页面下方展示评论区、商品模块或其他业务组件。该模式通过配置播放器宽度铺满、固定高度,结合自定义导航组件和消息组件,实现内容与互动的良好分离。

  1. index.json 中设置自定义导航栏,并引入必要组件,包括播放器、导航栏、消息互动模块等。

    {
      "usingComponents": {
        "ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player",
        "nav": "../components/nav/nav",
        "message": "../components/message/message",
        "mp-icon": "weui-miniprogram/icon/icon"
      },
      "navigationStyle": "custom"
    }
    
  2. index.wxml 中,使用 <ve-live-player> 组件构建播放器区域,配合上下的 navmessage 模块,实现上播下聊的布局。播放器支持全屏切换,控制按钮通过 mp-icon 实现。

    <!-- index.wxml -->
    <view class="wrap">
      <image class="image" src="/assets/bg.jpeg" />
      <nav color="#000" />
      <ve-live-player
        id="player"
        ve-class="player"
        autoplay
        src="https://pull-demo.volcfcdnrd.com/live/st-4536523.flv"
        width="100vw"
        height="200px"
        object-fit="{{objectFit}}"
        fit-video-size="{{fitVideoSize}}"
      >
        <mp-icon
          wx:if="{{fullscreen}}"
          style="position: absolute; top: 12px; left: 12px"
          icon="back"
          color="#fff"
          size="{{12}}"
          bind:tap="exitFullscreen"
        ></mp-icon>
        <mp-icon
          wx:if="{{!fullscreen}}"
          style="position: absolute; bottom: 4px; right: 4px;"
          icon="max-window"
          color="#fff"
          size="{{20}}"
          bind:tap="requestFullscreen"
        ></mp-icon>
        <message wx:if="{{fullscreen}}" />
      </ve-live-player>
      <message wx:if="{{!fullscreen}}" />
    </view>
    
  3. index.wxss 中,通过样式确保背景图与播放器尺寸适配,避免出现留白或滚动问题。

    /** index.wxss */
    .wrap {
      width: 100vw;
      height: 100vh;
      overflow: hidden;
    }
    
    .image {
      position: absolute;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      object-fit: cover;
    }
    
  4. index.js 中,处理播放器全屏切换逻辑,并根据状态动态设置适配参数 fitVideoSizeobjectFit

    // index.js
    import { getVeLivePlayer } from 'veplayer-live-mp-wx';
    
    Page({
      data: {
        fullscreen: false,
        fitVideoSize: 'fixWidth',
        objectFit: 'fillCrop',
      },
      onLoad() {
        const veLivePlayer = getVeLivePlayer(this, '#player');
        this.veLivePlayer = veLivePlayer;
        this.veLivePlayer.on('fullscreenChange', fullscreen => {
          this.setData({
            fullscreen,
            fitVideoSize: fullscreen ? 'fixed' : 'fixWidth',
            objectFit: fullscreen ? 'contain' : 'fillCrop',
          });
        });
      },
      requestFullscreen() {
        this.veLivePlayer.requestFullscreen({
          direction: 90,
        });
      },
      exitFullscreen() {
        this.veLivePlayer.exitFullscreen();
      },
    });
    

居中播放

播放器位于页面中央,适合需要居中展示内容的直播场景。通过设置播放器宽高和背景图样式,实现播放器居中且覆盖背景。

  1. index.json 中引入必要组件,设置自定义导航栏。

    {
      "usingComponents": {
        "ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player",
        "nav": "../components/nav/nav",
        "message": "../components/message/message",
        "mp-icon": "weui-miniprogram/icon/icon"
      },
      "navigationStyle": "custom"
    }
    
  2. index.wxml 中,构建播放器居中布局,结合导航栏、背景图和消息组件。

    <!-- index.wxml -->
    <view class="wrap">
      <nav color="#000" />
      <image class="image" src="/assets/bg.jpeg" />
      <ve-live-player
        class="player"
        autoplay
        src="https://pull-demo.volcfcdnrd.com/live/st-4536523.flv"
        width="100vw"
        height="200px"
        fit-video-size="fixWidth"
      />
      <message />
    </view>
    
  3. index.wxss 中,设置父容器居中对齐,并确保背景图覆盖全屏,播放器层级高于背景。

    /** index.wxss */
    .wrap {
      width: 100vw;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .image {
      position: absolute;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      object-fit: cover;
    }
    
    .player {
      position: relative;
      z-index: 1;
    }
    
  4. 在 index.js 中,无需交互逻辑,保留空定义。

    // index.js
    import { getVeLivePlayer } from 'veplayer-live-mp-wx';
    
    Page({});
    

全屏播放

播放器铺满整个页面,适合沉浸式观看体验。布局简单,播放器占满视窗,搭配导航和消息组件。

  1. index.json 中配置组件及自定义导航栏。

    {
      "usingComponents": {
        "ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player",
        "nav": "../components/nav/nav",
        "message": "../components/message/message",
        "mp-icon": "weui-miniprogram/icon/icon"
      },
      "navigationStyle": "custom"
    }
    
  2. index.wxml 中,将播放器设置为根容器,嵌套导航和消息组件。

    <!-- index.wxml -->
    <view class="wrap">
      <ve-live-player
        ve-class="player"
        autoplay
        src="https://pull-demo.volcfcdnrd.com/live/st-4536524.flv"
        object-fit="fillCrop"
      >
        <nav />
        <message />
      </ve-live-player>
    </view>
    
  3. index.wxss 中,确保播放器绝对定位铺满全屏,无滚动。

    /** index.wxss */
    .wrap {
      width: 100vw;
      height: 100vh;
      overflow: hidden;
    }
    
    .wrap .player {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      width: 100%;
      height: 100%;
    }
    
  4. index.js 中,无需交互逻辑,保留空定义。

    // index.js
    Page({});
    

横屏播放页面实现

横屏直播画面位于顶部,下方支持业务内容及 Tab 组件。播放器支持播放控制,包括播放/暂停、静音、刷新和全屏操作,控制栏固定在播放器底部。

  1. index.json 中配置相关组件。

    {
      "usingComponents": {
        "ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player",
        "nav": "../components/nav/nav",
        "message": "../components/message/message",
        "mp-icon": "weui-miniprogram/icon/icon"
      },
      "navigationStyle": "custom"
    }
    
  2. index.wxml 中,播放器顶部展示,包含控制按钮,底部展示 Tab 列表及业务内容。

    <!-- index.wxml -->
    <view class="wrap">
      <nav color="#000" />
      <ve-live-player
        id="player"
        ve-class="player"
        autoplay
        src="https://pull-demo.volcfcdnrd.com/live/st-4536523.flv"
        width="100vw"
        height="200px"
        object-fit="{{objectFit}}"
        fit-video-size="{{fitVideoSize}}"
      >
        <view class="control">
          <view>
            <mp-icon
              icon='{{paused?"play":"pause"}}'
              color="#fff"
              size="{{20}}"
              bind:tap="handlePlay"
            ></mp-icon>
            <mp-icon
              style="margin-left: 8px"
              icon="refresh"
              color="#fff"
              size="{{16}}"
              bind:tap="handleRefresh"
            ></mp-icon>
          </view>
          <view>
            <mp-icon
              icon='{{muted?"volume-off":"volume-up"}}'
              color="#fff"
              size="{{20}}"
              bind:tap="handleMute"
            ></mp-icon>
            <mp-icon
              icon='{{fullscreen ? "close" : "max-window"}}'
              color="#fff"
              style="margin-left: 8px"
              size="{{16}}"
              bind:tap="handleFullscreen"
            >
              <message wx:if="{{fullscreen}}" />
              <message wx:if="{{!fullscreen}}" />
            </mp-icon>
          </view>
        </view>
      </ve-live-player>
      <view class="bottom">
        <view class="tab-list">
          <view
            wx:for="{{tabList}}"
            wx:key="index"
            wx:for-item="item"
            class="tab-item"
            >{{item.text}}</view
          >
        </view>
        <view class="content"
          >火山引擎是字节跳动旗下的云服务平台,将字节跳动快速发展过程中积累的增长方法、技术能力和应用工具开放给外部企业,提供云基础、视频与内容分发、数智平台VeDI、人工智能、开发与运维等服务,帮助企业在数字化升级中实现持续增长。</view
        >
      </view>
    </view>
    
  3. index.wxss 中,设置播放器及控制栏样式,底部内容自适应。

    /** index.wxss */
    .wrap {
      width: 100vw;
      height: 100vh;
      overflow: hidden;
      display: flex;
      flex-direction: column;
    }
    
    .image {
      position: absolute;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      object-fit: cover;
    }
    
    .control {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      padding: 4px 16px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      background-color: rgba(0, 0, 0, 0.5);
    }
    
    .bottom {
      flex-grow: 1;
    }
    
    .tab-list {
      display: flex;
      border-bottom: 1px solid #ccc;
      align-items: center;
      justify-content: space-between;
    }
    
    .tab-item {
      width: 33.333333333%;
      padding: 12px 20px;
      text-align: center;
    }
    
    .tab-item:first-child {
      background-color: #eee;
      font-weight: bold;
    }
    
    .tab-item:not(:first-child) {
      border-left: 1px solid #ccc;
    }
    
    .content {
      padding: 5px 8px;
      font-size: 16px;
      line-height: 24px;
    }
    
  4. index.js 中,实现播放控制逻辑,支持播放、静音、刷新和全屏切换等操作。

    // index.js
    import { getVeLivePlayer } from 'veplayer-live-mp-wx';
    
    Page({
      data: {
        fullscreen: false,
        fitVideoSize: 'fixWidth',
        objectFit: 'fillCrop',
        paused: false,
        muted: false,
        tabList: [
          {
            text: 'tab1',
          },
          {
            text: 'tab2',
          },
          {
            text: 'tab3',
          },
        ],
      },
      onLoad() {
        const veLivePlayer = getVeLivePlayer(this, '#player');
        this.veLivePlayer = veLivePlayer;
        this.veLivePlayer.on('fullscreenChange', fullscreen => {
          this.setData({
            fullscreen,
            fitVideoSize: fullscreen ? 'fixed' : 'fixWidth',
            objectFit: fullscreen ? 'contain' : 'fillCrop',
          });
        });
        this.veLivePlayer.on('playing', () => {
          this.setData({
            paused: false,
          });
        });
        this.veLivePlayer.on('pause', () => {
          this.setData({
            paused: true,
          });
        });
      },
      handleFullscreen() {
        if (this.data.fullscreen) {
          this.veLivePlayer.exitFullscreen();
        } else {
          this.veLivePlayer.requestFullscreen({
            direction: 90,
          });
        }
      },
      handlePlay() {
        const paused = !this.data.paused;
        if (paused) {
          this.veLivePlayer.pause();
        } else {
          this.veLivePlayer.play();
        }
      },
      handleMute() {
        const muted = !this.data.muted;
        if (muted) {
          this.veLivePlayer.mute();
        } else {
          this.veLivePlayer.unmute();
        }
        this.setData({
          muted,
        });
      },
      handleRefresh() {
        this.veLivePlayer.replay();
      },
    });
    

低延迟拉流实现

低延迟拉流适用于时效性强的直播场景。通过启用 RTC 模式并配置合理的缓存区参数,可实现更接近实时的播放体验。

  1. 无需引入额外组件,仅通过在 index.json 中设置 mode="RTC" 并控制最小/最大缓存区实现:

    <!-- index.wxml -->
    <ve-live-player
      autoplay
      src="https://pull-demo.volcfcdnrd.com/live/st-4536526.flv"
      mode="RTC"
      min-cache="{{0.2}}"
      max-cache="{{0.8}}"
    />
    
  2. index.js 中,无需交互逻辑,保留空定义。

    // index.js
    Page({});
    

公共组件实现

为了提升直播间的整体体验,以下示例展示了两个常用的公共组件:导航组件和消息组件。它们分别负责直播页面的导航展示与用户互动信息的呈现,是构建完善直播界面的基础模块。

导航组件 nav

用于展示页面顶部的返回与标题栏,提升直播间整体一致性。该组件使用 weuinavigation-bar 实现,支持颜色定制。

  1. 新建 nav.json 文件定义导航组件配置。

    // nav.json
    {
      "component": true,
      "usingComponents": {
        "mp-navigation-bar": "weui-miniprogram/navigation-bar/navigation-bar",
        "mp-icon": "weui-miniprogram/icon/icon"
      }
    }
    
  2. 新建 nav.wxml 文件定义导航组件界面结构。

    <!-- nav.wxml -->
    <mp-navigation-bar ext-class="nav-bar" color="{{color}}">
      <view slot="center" class="center">
        <view class="avatar">
          <mp-icon type="field" icon="me" size="{{24}}" color="{{color}}" />
        </view>
        <text style="margin-left: 8px;">小 A</text>
      </view>
    </mp-navigation-bar>
    
  3. 新建 nav.wxss 文件定义导航组件样式。

    /* nav.wxss */
    .center {
      display: flex;
      align-items: center;
    }
    
  4. 新建 nav.js 文件定义导航组件逻辑和行为。

    // nav.js
    Component({
      properties: {
        color: {
          type: String,
          value: '#fff',
        },
      },
    });
    

消息组件 message

用于展示用户评论与系统提示信息,适合放置在播放器下方或悬浮层。

  1. 新建 message.json 文件定义消息组件配置。

    // message.json
    {
      "component": true
    }
    
  2. 新建 message.wxml 文件定义消息组件界面结构。

    <!-- message.wxml -->
    <view class="message-wrap">
      <view class="message-list">
        <view
          class="message-list-item"
          wx:for="{{list}}"
          wx:key="index"
          wx:for-item="item"
        >
          <text style="color: khaki">{{item.name}}:</text>
          <text style="margin-left: 8px; color: {{item.color}}"
            >{{item.content}}</text
          >
        </view>
        <view class="message-input">
          <input placeholder="聊两句..." placeholder-style="color: #fff" />
        </view>
      </view>
    </view>
    
  3. 新建 message.wxss 文件定义消息组件样式。

    /* message.wxss */
    .message-wrap {
      position: absolute;
      left: 0;
      bottom: 0;
      padding: 16px 8px;
    }
    
    .message-list {
      max-width: 80%;
    }
    
    .message-list-item,
    .message-input {
      font-size: 12px;
      padding: 4px 8px;
      background-color: rgba(0, 0, 0, 0.5);
      border-radius: 6px;
      margin-top: 8px;
      width: fit-content;
    }
    
    .message-input {
      color: #fff;
      width: 100px;
    }
    
  4. 新建 message.js 文件定义消息组件逻辑和行为。

    // message.js
    Component({
      data: {
        list: [
          {
            name: '温馨提示',
            color: 'khaki',
            content:
              '欢迎来到直播间!如直播间出现违法违规、色情低俗、抽烟喝酒、诱导欺诈行为,请及时举报。管理员 24 小时在线巡查并接受举报,感谢你与平台一起努力,守护我们共同的社区',
          },
          {
            name: '用户B',
            color: '#fff',
            content: '你好,我是用户B!',
          },
          {
            name: '主播',
            color: '#fff',
            content: '@用户B 欢迎来到我的直播间',
          },
        ],
      },
    });