保利威文档中心

幫助中心

微信小程式背景播放接入說明

更新時間:2026-08-06 23:47:16

微信小程式背景播放接入說明

本文介紹保利威直播在微信小程式中的背景小視窗播放對接方式,涵蓋以下兩種觀看場景:

  • 原生小程式觀看頁:由觀看頁播放器直接請求背景小視窗播放。
  • 小程式 WebView 觀看頁:H5 觀看頁跳轉到小程式原生中轉頁,由中轉頁建立原生 <video> 並請求背景小視窗播放。

背景小視窗始終由微信小程式原生 <video><live-player> 元件承載。requestBackgroundPlayback() 不接收播放位址,直播流或回放位址必須先繫結到當前正在播放的原生元件,再透過對應的 Context 請求背景播放。

微信小程式核心 API

微信小程式實現背景播放的核心是播放器 Context 上的 requestBackgroundPlayback()。Polyv SDK 提供的 watchCore.player.requestBackgroundPlayback() 是對微信原生 Context API 的統一封裝,不是另一套系統小視窗能力。

進入背景小視窗

微信原生 API 官方說明 最低基礎庫 適用元件
VideoContext.requestBackgroundPlayback() 進入背景小視窗播放模式 2.14.3 <video>
LivePlayerContext.requestBackgroundPlayback() 進入背景小視窗播放模式 2.14.3 <live-player>

兩個 API 均無參數、回傳 void。使用方式如下:

// video
const videoContext = wx.createVideoContext('videoId', this);
videoContext.requestBackgroundPlayback();

// live-player
const livePlayerContext = wx.createLivePlayerContext('livePlayerId', this);
livePlayerContext.requestBackgroundPlayback();

Context 的建立方式可參考微信官方文件:

在 Polyv 原生觀看頁中,業務程式碼只需要呼叫:

watchCore.player.requestBackgroundPlayback();

SDK 會根據當前實際播放節點,向下轉發到 VideoContext.requestBackgroundPlayback()LivePlayerContext.requestBackgroundPlayback()

退出背景小視窗

微信原生 API 官方說明 最低基礎庫 適用元件
VideoContext.exitBackgroundPlayback() 退出背景小視窗播放模式 2.14.3 <video>
LivePlayerContext.exitBackgroundPlayback() 退出背景小視窗播放模式 2.14.3 <live-player>

WebView 中轉頁返回 H5 前使用的是 VideoContext.exitBackgroundPlayback()

const videoContext = wx.createVideoContext('polyvLiveVideo', this);
videoContext.exitBackgroundPlayback();
wx.navigateBack({ delta: 1 });

原生控制欄按鈕

video 元件的 show-background-playback-button 用於控制原生控制欄是否展示背景播放按鈕。該屬性只控制按鈕展示,不代替 Context API;使用自訂按鈕時仍需主動呼叫 requestBackgroundPlayback()

接入前準備

接入前請確認:

  • 已在保利威直播管理後台開啟對應的小視窗播放設定。
  • 微信小程式基礎庫需要為 2.14.3 或以上,低版本必須做相容處理。
  • 使用 iOS、Android 真機驗證。開發者工具不能替代應用切背景場景的真機結果。
  • 呼叫時播放器已經完成初始化並進入播放狀態,原生播放器節點仍然掛載在頁面中。
  • 當前微信版本和作業系統支援背景小視窗播放。

該方案不依賴 app.jsonrequiredBackgroundModesrequiredBackgroundModes 中的 audio 是背景音訊能力,不是影片背景小視窗開關。

管理後台設定

在直播管理後台的頻道小程式設定中,可以看到以下配置:

設定項 作用 當前適用範圍
小程式原生小視窗播放 控制原生小程式觀看頁是否展示小視窗入口 直播、回放
小程式 WebView 小視窗播放 控制 WebView H5 觀看頁是否展示小視窗入口 直播
小程式原生中間頁路徑 WebView 觀看頁點選小視窗後跳轉的原生小程式頁面路徑 僅 WebView 方案

中轉頁路徑

當前 Polyv 觀看端提供的參考中轉頁是:

/pages-other/pages/window/window

實現可參考 Polyv 觀看端原始碼中的:

src/pages-other/pages/window/

中轉頁必須在小程式 app.jsonpages 或分包頁面中完成註冊。WebView 觀看頁必須使用 wx.miniProgram.navigateTo 開啟該頁面,以保留上一層 WebView 頁面;不要使用 redirectTo 替換 WebView 頁面,否則中轉頁無法透過 navigateBack 返回原觀看頁。

截圖中的配置範例為:

/pages-other/pages/window/window?appId=xxxx&appSecret=xxxx&accountId=xxxx

當前參考頁實際需要以下四個參數:

參數 必填 說明
channelId 當前直播頻道 ID,通常由 H5 觀看頁在點選時追加
accountId 保利威帳號 ID,不是觀眾 userId
appId 當前驗證實現使用的播放器鑑權 App ID
appSecret 僅當前驗證實現用於前端計算簽名

參數名區分大小寫。accountId 表示保利威帳號 ID,觀眾 userId 表示觀看使用者識別,二者是完全不同的業務欄位,不能互相替代,也不能把觀眾 userId 作為 accountId 傳入。所有動態參數都應執行 encodeURIComponent

安全提示:截圖展示的是當前驗證環境的配置方式。生產環境禁止把長期 appSecret 放在管理後台頁面路徑、H5 JavaScript、小程式路由參數或小程式程式碼中。正式接入應由業務服務端保管金鑰,只向前端簽發短時、最小權限的播放憑證。中轉頁可接收一次性 ticket,再向業務服務端換取短時 sign + timestamp 或播放 token。採用該方式前,需要同步改造當前 Polyv window 參考頁的鑑權入參。

原生小程式觀看頁實現

實現流程

當前 Polyv 觀看端只在豎屏觀看頁展示小視窗按鈕。按鈕位於頻道資訊膠囊旁,顯示條件為:

  • 後台已開啟「小程式原生小視窗播放」。
  • 當前頻道狀態為直播中或回放中。

呼叫鏈如下:

sequenceDiagram
  participant User as 用户
  participant Page as 原生观看页
  participant SDK as watchCore.player
  participant Controller as 播放器控制器
  participant Context as VideoContext 或 LivePlayerContext
  participant System as 微信或系统小窗
  User->>Page: 点击小窗按钮
  Page->>SDK: requestBackgroundPlayback()
  SDK->>Controller: 转发到当前直播或点播控制器
  Controller->>Context: requestBackgroundPlayback()
  Context->>System: 请求进入后台小窗

對應的核心呼叫是:

watchCore.player.requestBackgroundPlayback();

SDK 會根據當前播放器類型轉發呼叫:

  • 直播播放器:獲取當前播放器元件暴露的 getVideoContext(),最終呼叫 VideoContextLivePlayerContext
  • 點播播放器:呼叫點播播放器上下文的 requestBackgroundPlayback()

當前本地播放器會根據媒體類型選擇原生節點:

  • 普通直播流優先使用 <live-player>
  • .m3u8、回放、暖場影片或開啟 forceVideo 時使用 <video>

推薦呼叫時機

應在播放器真正開始播放後開放小視窗按鈕。觀看頁 SDK 可以監聽 PlayerEvents.PlayerPlaying

import { PlayerEvents } from '@polyv/live-watch-miniprogram-sdk';

let canRequestBackgroundPlayback = false;

watchCore.player.eventEmitter.on(PlayerEvents.PlayerPlaying, () => {
  canRequestBackgroundPlayback = true;
});

function onTapBackgroundPlayback() {
  if (!canRequestBackgroundPlayback) {
    wx.showToast({
      title: '请先开始播放',
      icon: 'none',
    });
    return;
  }

  try {
    watchCore.player.requestBackgroundPlayback();
  } catch (error) {
    wx.showToast({
      title: '小窗打开失败',
      icon: 'none',
    });
  }
}

requestBackgroundPlayback() 無參數、回傳 void。呼叫沒有回傳成功回呼,因此不能把「方法未拋錯」直接等同於「系統小視窗已經開啟」。

直接使用原生 video

如果沒有使用觀看頁 SDK,也可以直接對原生 <video> 建立 Context:

<video
  id="liveVideo"
  src="{{ videoSrc }}"
  autoplay
  show-background-playback-button="{{ true }}"
  bindplay="onVideoPlay"
/>

<button bind:tap="onTapBackgroundPlayback">小窗播放</button>
Page({
  data: {
    isPlaying: false,
  },

  onVideoPlay() {
    this.setData({ isPlaying: true });
  },

  onTapBackgroundPlayback() {
    if (!this.data.isPlaying) {
      wx.showToast({ title: '请先开始播放', icon: 'none' });
      return;
    }

    const videoContext = wx.createVideoContext('liveVideo', this);
    if (typeof videoContext.requestBackgroundPlayback !== 'function') {
      wx.showToast({ title: '当前环境不支持小窗播放', icon: 'none' });
      return;
    }

    try {
      videoContext.requestBackgroundPlayback();
    } catch (error) {
      wx.showToast({ title: '小窗打开失败', icon: 'none' });
    }
  },
});

show-background-playback-button 只控制原生控制欄是否顯示背景播放按鈕;使用自訂按鈕時仍需主動呼叫 Context API。

頁面生命週期

系統小視窗依賴原播放器頁面和原生節點存活。背景播放期間不要執行以下操作:

  • navigateBackredirectTo 或其他會卸載播放器頁面的路由操作。
  • 銷毀觀看頁 SDK 或播放器實例。
  • 透過 wx:if 移除 <video> / <live-player>
  • 清空 src 或切換到另一個播放器 Context。

當前 Polyv 原生觀看頁針對 iOS 返回頁面後的恢復問題做了相容處理:觸發過背景播放後,頁面再次顯示會立即呼叫一次 play(),並在 1 秒後再次呼叫。該處理可以緩解 <video> 播放 m3u8 時第一次 play() 無效的問題;當前 <live-player> 在系統小視窗中暫停後返回,仍可能無法透過 play() 恢復,需要結合真機結果繼續處理。

WebView 觀看頁實現

方案定位

WebView 頁面不能直接獲取小程式原生 VideoContext。當前方案透過一個可見的原生中轉頁接管播放:

sequenceDiagram
  participant User as 用户
  participant H5 as WebView 观看页
  participant Window as 原生 window 中转页
  participant Core as wx-live-player-core
  participant Video as 原生 video
  participant System as 微信或系统小窗
  User->>H5: 点击小窗播放
  H5->>Window: wx.miniProgram.navigateTo
  Window->>Core: 创建播放器并请求媒体信息
  Core-->>Window: 返回 mediaInfo.src
  Window->>Video: 设置 src 并自动播放
  Video-->>Window: bindplay
  Window->>System: requestBackgroundPlayback()
  System-->>Window: 用户返回微信
  Window->>Video: exitBackgroundPlayback()
  Window->>H5: navigateBack 返回 WebView

當前完整流程是:

  1. 小程式登入頁透過 redirectTo 開啟承載 H5 觀看頁的 WebView 頁面。
  2. H5 根據後台的「小程式 WebView 小視窗播放」開關決定是否展示小視窗按鈕。
  3. 使用者點選後,H5 暫停自身播放器,並使用 wx.miniProgram.navigateTo 開啟後台配置的原生中轉頁。
  4. 中轉頁獲取直播流位址,掛載原生 <video>
  5. <video> 觸發 bindplay 後,中轉頁呼叫 requestBackgroundPlayback()
  6. 使用者從系統小視窗返回微信時,中轉頁在後續 onShow 中退出背景播放,再 navigateBack 返回原 WebView 頁面。
  7. 中轉頁 onUnload 時銷毀播放器。

因此該方案的播放歸屬會發生切換:進入中轉頁後由原生播放器播放;返回 WebView 前會結束原生系統小視窗並銷毀中轉播放器。它不支援「已經返回 WebView 頁面,但原生系統小視窗仍繼續播放」的並行狀態。

H5 跳轉中轉頁

WebView 網頁需要引入微信 JSSDK,並在使用者點選時呼叫:

<script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
function openBackgroundPlayback(options) {
  const intermediatePagePath = options.intermediatePagePath;
  const channelId = options.channelId;
  const separator = intermediatePagePath.includes('?') ? '&' : '?';
  const targetUrl =
    intermediatePagePath +
    separator +
    'channelId=' +
    encodeURIComponent(channelId);

  // 跳转前暂停 H5 播放器,避免双音频和重复统计。
  options.pauseWebPlayer();

  wx.miniProgram.navigateTo({
    url: targetUrl,
    fail(error) {
      console.error('打开小窗中转页失败', error);
      options.resumeWebPlayer();
    },
  });
}

intermediatePagePath 使用管理後台返回的中轉頁路徑。當前截圖中的路徑已經包含 appIdappSecretaccountId,H5 在點選時追加當前 channelId。正式環境應改為追加短時 ticket,不要傳遞長期 appSecret

Polyv window 中轉頁邏輯

Polyv 觀看端的 pages-other/pages/window/window 當前使用原生 Page({...}) 生命週期,核心邏輯如下:

  1. 解析並校驗 channelIdaccountIdappIdappSecret
  2. 生成時間戳和 MD5 簽名,建立 @polyv/wx-live-player-core 播放器。
  3. 設定 forceVideo: true,確保直播由原生 <video> 承載。
  4. 監聽 UPDATE_MEDIA_INFO,把 mediaInfo.src 寫入頁面的 videoSrc
  5. 原生 <video> 起播後建立 VideoContext,並且只發起一次 requestBackgroundPlayback()
  6. 後續 onShow 檢查上一頁是否為 WebView;滿足條件時先退出背景播放,再返回 WebView。
  7. onUnload 銷毀 PolyvLive,避免播放器和事件監聽殘留。

參考頁會把 accountId 傳給 PolyvLiveuid 配置,並用於 statistics.param1。這裡的 accountId 仍然是保利威帳號 ID,不代表觀眾 userId

中轉頁的原生節點應保持可見和掛載:

<video
  wx:if="{{ videoSrc }}"
  id="polyvLiveVideo"
  src="{{ videoSrc }}"
  autoplay
  controls="{{ false }}"
  enable-progress-gesture="{{ false }}"
  show-fullscreen-btn="{{ false }}"
  object-fit="contain"
  bindplay="onVideoPlay"
  binderror="onVideoError"
/>

不要對播放器使用 display: nonevisibility: hiddenopacity: 0,也不要在發起背景播放後立即卸載中轉頁。

生產鑑權改造

當前參考頁把 appSecret 帶到前端並在小程式中計算簽名,只能用於內部驗證。推薦的生產流程是:

  1. H5 向業務服務端申請一次性、短有效期的 ticket
  2. H5 只把 channelIdticket 傳給原生中轉頁;如果業務還需要觀眾 userId,應使用獨立欄位傳遞,不能覆蓋 accountId
  3. 中轉頁用 ticket 向業務服務端換取短時播放器鑑權資訊。
  4. 業務服務端持有 appSecret 並完成簽名,前端永遠不接觸長期金鑰。
  5. 中轉頁使用返回的短時 appId + sign + timestamp 或播放 token 建立播放器。

ticket 應綁定頻道、觀眾、過期時間和使用次數,並在服務端校驗,避免被複製到其他頻道或重複使用。

使用者互動與呼叫時機

微信官方對 requestBackgroundPlayback() 的介面說明沒有標註「只能由使用者點選呼叫」,但這不等於進入頁面後可以無條件立即呼叫:

  • 原生媒體可能尚未建立 Context 或尚未開始播放。
  • 自動播放可能受終端、系統或媒體策略影響。
  • 背景小視窗是否出現仍由微信和作業系統共同決定。

推薦做法:

  • 原生觀看頁由使用者點選小視窗按鈕觸發。
  • WebView 方案由使用者點選 H5 小視窗按鈕進入中轉頁,並等原生 <video>bindplay 後呼叫。
  • 不要在 onLoad 中建立 Context 後立即呼叫。
  • 不要在呼叫後緊接著執行 wx.exitMiniProgram()。微信沒有保證這組呼叫的組合時序。

狀態判斷與錯誤處理

建議同時使用以下方式維護狀態:

  • 呼叫前檢查 requestBackgroundPlayback 是否存在,並捕獲同步異常。
  • 提供手動重試入口,不要只依賴自動呼叫一次。
  • 在頁面生命週期中記錄是否已經發起背景播放請求,避免重複呼叫。

當前 Polyv window 參考頁中的 backgroundPlaybackRequested 只表示「已經發起呼叫且未同步拋錯」,不代表背景小視窗真實進入。業務側需要保留失敗提示和手動重試入口。

背景播放限制

  • 微信沒有提供直接把流位址傳給背景小視窗的全域 API。
  • 必須先讓微信原生 <video><live-player> 播放,再呼叫對應 Context。
  • 強制結束微信程序、卸載播放器頁面、銷毀播放器或清空媒體源後,背景播放無法繼續。
  • 使用者把微信切到背景後小視窗立即消失時,應優先
联系客服,在线咨询