You need to enable JavaScript to run this app.
视频直播

视频直播

Copy page
Download PDF
HarmonyOS NEXT
基础功能
Copy page
Download PDF
基础功能

本章节为您介绍拉流基础功能的接入方法,根据文档提供的操作步骤进行配置,您可接入直播拉流播放控制能力。

前提条件

已集成并初始化 HarmonyOS NEXT 拉流 SDK。详见集成 HarmonyOS NEXT 拉流 SDK初始化 HarmonyOS NEXT 拉流 SDK

注意事项

真机调试:由于 SDK 使用了大量 HarmonyOS NEXT 系统的音视频接口,这些接口在仿真模拟器下可能会出现异常,推荐您使用真机进行代码调试。

功能接入

本节为您详细介绍如何通过拉流 SDK 实现直播拉流播放控制的能力,包括但不限于创建播放器、初始化配置、事件监听、设置渲染 View、设置播放地址。

创建播放器

使用拉流 SDK,需要先创建直播播放器。您可以参考以下代码创建播放器。

  1. 获取全局的 appContext 和 mainWindow。

    1. 在 module.json5 文件中配置 mainElement,代码示例如下。

      {
        "module": {
          "mainElement": "AppAbility"
        }
      }
      
    2. 在 src/main/ets 目录中新建 AppAbility.ets 文件,写入如下内容。

      export default class AppAbility extends UIAbility {
        onWindowStageCreate(windowStage: window.WindowStage): void {
          AppEnv.appContext = this.context
          windowStage.loadContent('Index.ets', (err) => {
             // 获取应用主窗口
             let mainWindow: window.Window = windowStage.getMainWindowSync();
             AppEnv.mainWindow = mainWindow    
          });
        }
      }
      

    tip

    AppEnv 用于保存应用的上下文和窗口引用。该名称仅为示例,您可以根据实际需求自定义命名和实现方式。只要能够有效记录 window 对象,方便在创建播放器时调用即可。

  2. 创建播放器,代码示例如下。

    let livePlayer = new LivePlayer(AppEnv.appContext, AppEnv.mainWindow)
    

warning

为确保播放效果,建议每次播放时创建新的播放器实例,而非复用播放器实例。

初始化配置

您可以通过 VeLivePlayerConfiguration 对播放器进行初始化相关配置。详细参数说明如下表所示。

参数

类型

说明

enableHardwareDecode

boolean

是否开启硬件解码功能。默认值为 true。开启后,如果硬件解码失败,播放器会自动切换为软解码。

retryIntervalTimeMs

number

重试时间间隔,单位为 ms。默认值为 5000。在播放直播时,如果出现网络异常等导致播放中断,播放器会尝试进行重试。

retryMaxCount

number

播放器在网络连接错误的情况下的最大重试次数。默认值为 5。如果配置为 0,表示关闭播放器内部的重试机制。

enableStatisticsCallback

boolean

是否开启播放信息周期性回调。默认值为 false

statisticsCallbackInterval

number

播放信息周期性回调的时间间隔,单位为 s。默认值为 5

您可以参考以下代码示例进行初始化配置。

// 创建配置
const config = new VeLivePlayerConfiguration()
// 打开周期性回调
config.enableStatisticsCallback = true;
// 初始化播放器
livePlayer.setConfig(config);

配置事件监听

您可以通过配置事件回调监听来获取播放器的内部状态信息,包括播放器状态、错误信息、音视频首帧回调以及周期性统计数据等。代码示例如下所示。

export class VeLivePlayerObserverImp implements VeLivePlayerObserver {
   onError(player: VeLivePlayer, error: VeLivePlayerError): void {
    // 错误回调
  }

  onFirstVideoFrameRender(player: VeLivePlayer, isFirstFrame: boolean): void {
    // 视频首帧回调
  }

  onFirstAudioFrameRender(player: VeLivePlayer, isFirstFrame: boolean): void {
    // 音频首帧回调
  }

  onStallStart(player: VeLivePlayer): void {
    // 卡顿开始回调
  }

  onStallEnd(player: VeLivePlayer): void {
    // 卡顿结束回调
  }

  onVideoRenderStall(player: VeLivePlayer, stallTime: number): void {
    // 视频渲染卡顿
  }

  onAudioRenderStall(player: VeLivePlayer, stallTime: number): void {
    // 音频渲染卡顿
  }

  onResolutionSwitch(player: VeLivePlayer, resolution: VeLivePlayerResolution, error: VeLivePlayerError,
    reason: VeLivePlayerResolutionSwitchReason): void {
       // 清晰度切换回调
  }

  onVideoSizeChanged(player: VeLivePlayer, width: number, height: number): void {
    // 视频尺寸变化回调
  }

  onMainBackupSwitch(player: VeLivePlayer, streamType: VeLivePlayerStreamType, error: VeLivePlayerError): void {
     // 主备切换回调  
  }

  onPlayerStatusUpdate(player: VeLivePlayer, status: VeLivePlayerStatus): void {
    // 播放器状态变更回调
  }

  onStatistics(player: VeLivePlayer, statistics: VeLivePlayerStatistics): void {
    // 拉流周期性信息回调
  }

  onSnapshotComplete(player: VeLivePlayer, bitmap: image.PixelMap): void {
     // 截图完成回调  
  }
}

// 配置播放器回调
livePlayer.setObserver(new VeLivePlayerObserverImp())

配置渲染 View

为了展示播放器的视频画面,您需要配置一个渲染 View。

@Component
export struct PlayerContentView {
  livePlayer?: VeLivePlayer
  playerObserver: VeLivePlayerObserverImp = new VeLivePlayerObserverImp()
  aboutToAppear(): void {
    // 初始化播放器
    let livePlayer = new VeLivePlayer(AppEnv.appContext, AppEnv.mainWindow)
    // 创建配置
    const config = new VeLivePlayerConfiguration()
    // 打开周期性回调
    config.enableStatisticsCallback = true;
    // 配置播放器
    livePlayer.setConfig(config);
    // 配置 Observer
    livePlayer.setObserver(this.playerObserver)
    this.livePlayer = livePlayer
  }

  aboutToDisappear(): void {
     // 销毁播放器
    this.livePlayer?.destroy()
  }

  build() {
    Stack() {
      Column() {
        VeLivePlayerView({
          onLoad: (window) => {
            this.livePlayer?.setWindow(window)
          }
        })
          .width(this.playerObserver.liveWindowWidth)
          .height(this.playerObserver.liveWindowHeight)
          .backgroundColor(Colors.blackColor)
      }
      .width('100%')
      .height('100%')
      .alignItems(HorizontalAlign.Center)
      .justifyContent(FlexAlign.Center)
      .backgroundColor(Colors.blackColor)
    }.width('100%').height('100%')
  }
}

配置播放地址

通过 setPlayUrl 接口配置单一播放地址,支持FLV、HLS 等直播协议地址。代码示例如下所示。

// 通过 URL 进行播放
String playUrl = "https://pull.example.com/live/stream.flv";
// 配置播放地址
this.livePlayer?.setPlayUrl(playUrl);

tip

如果您需要配置多路组合播放地址,可使用 setPlayStreamData 接口,该接口支持主备流功能,详细的代码示例和接入方法请参考进阶功能接入

开始播放

调用播放器的 play 接口开始播放。代码示例如下所示。

this.livePlayer?.play(); // 开始播放。

调用播放器的 isPlaying 接口可以获取当前的播放状态。代码示例如下所示。

boolean isPlaying = this.livePlayer?.isPlaying() || false; //获取播放状态

暂停播放

调用播放器的 pause 接口暂停播放,代码示例如下所示。

this.livePlayer?.pause(); // 暂停播放

tip

在直播中,暂停和停止的行为相同。暂停后再调用 play 方法,播放器将重新拉流。

停止播放

调用播放器的 stop 接口停止播放。代码示例如下所示。

this.livePlayer?.stop(); // 停止播放

销毁播放器

调用播放器的 destroy 接口销毁播放器并释放内存。当您停止播放后需要销毁播放器时,请调用该接口。代码示例如下所示。

this.livePlayer?.destroy(); // 销毁拉流引擎,退出前释放播放器和内存

前后台切换

在应用程序从前台切换到后台时,播放器默认会继续播放音频。如果您希望在后台状态停止播放,可参考以下示例代码。

// EntryAbility 中 
export default class EntryAbility extends UIAbility { 
  onWindowStageCreate(windowStage: window.WindowStage): void { 
    AppStorage.setOrCreate<boolean>('isOnForeground', true); 
  } 
 
  onForeground(): void { 
    AppStorage.set<boolean>('isOnForeground', true); 
  } 
 
  onBackground(): void { 
    AppStorage.set<boolean>('isOnForeground', false); 
 } 
}

// Component 中
@Component
export struct PlayerContentView {
   @StorageLink('isOnForeground') @Watch('foregroundChanged')isOnForeground: boolean = true; 
   foregroundChanged() { 
    if (this.isOnForeground) { 
      this.livePlayer?.play(); // 回到前台,继续播放
    } else { 
       this.livePlayer?.pause(); // 退到后台,暂停播放
    } 
  }
}

静音配置

调用播放器的 setMute 接口可以控制是否静音播放。代码示例如下所示。

this.livePlayer?.setMute(true); // 配置静音播放

调用播放器的 isMute 接口可以获取当前是否为静音状态。代码示例如下所示。

boolean isMute = this.livePlayer?.isMute() || true; // 获取静音状态

日志级别

您可以通过调用 setLogLevel 设置打印到控制台的日志级别,代码示例如下:

// 输出 DEBUG、INFO、WARNING 和 ERROR 级别的日志
VeLivePlayer.setLogLevel(VeLivePlayerLogLevel.VeLivePlayerLogLevelDebug)
Last updated: 2026.03.31 15:33:48