使用AVPlayer在HarmonyOS中实现视频播放(ArkTS)

使用AVPlayer在HarmonyOS中实现视频播放(ArkTS)

在HarmonyOS应用开发中,视频播放功能通过强大的AVPlayer组件实现,它提供了完整的音视频播放解决方案。

1. AVPlayer概述

AVPlayer是HarmonyOS多媒体框架中的重要组件,它是一个功能完善的音视频播放API,集成了流媒体和本地资源解析、媒体资源解封装、视频解码和渲染功能。

核心特性:

  • 格式支持广泛:支持MP4、MKV等主流视频格式,以及M4A、AAC、MP3等音频格式
  • 播放源灵活:支持本地文件、网络流媒体等多种数据源
  • 功能全面:提供播放控制、音量调节、倍速播放、画面缩放等丰富功能
  • 高性能:底层硬件加速,保证播放流畅性

2. 开发环境准备

在开始编码前,需要确保开发环境正确配置:

  1. DevEco Studio:建议使用4.0 Release或更高版本
  2. SDK:API 9或更高版本
  3. 权限配置 :如使用网络视频,需在module.json5中声明权限:
json 复制代码
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
  }
}

3. AVPlayer完整开发流程

3.1 创建AVPlayer实例

首先需要导入媒体模块并创建AVPlayer实例:

typescript 复制代码
import { media } from '@kit.MediaKit';
import { BusinessError } from '@ohos.base';

class VideoPlayer {
  private avPlayer: media.AVPlayer | null = null;
  
  // 创建AVPlayer实例
  async createAVPlayer(): Promise<void> {
    try {
      this.avPlayer = await media.createAVPlayer();
      console.info('AVPlayer创建成功');
      // 设置监听器
      this.setAVPlayerCallback();
    } catch (error) {
      console.error(`AVPlayer创建失败: ${(error as BusinessError).message}`);
    }
  }
}

3.2 设置状态和事件监听

AVPlayer通过状态机管理播放生命周期,必须设置状态和错误监听:

typescript 复制代码
private setAVPlayerCallback(): void {
  if (!this.avPlayer) {
    return;
  }

  // 状态变化监听
  this.avPlayer.on('stateChange', (state: string, reason: media.StateChangeReason) => {
    console.info(`状态变化: ${state}`);
    switch (state) {
      case 'initialized':
        console.info('资源初始化完成');
        this.avPlayer?.prepare();
        break;
      case 'prepared':
        console.info('资源准备完成,开始播放');
        this.avPlayer?.play();
        break;
      case 'playing':
        console.info('播放中');
        break;
      case 'paused':
        console.info('已暂停');
        break;
      case 'completed':
        console.info('播放完成');
        break;
      case 'stopped':
        console.info('已停止');
        break;
      case 'idle':
        console.info('重置状态,可重新设置资源');
        break;
      case 'released':
        console.info('资源已释放');
        break;
    }
  });

  // 错误监听
  this.avPlayer.on('error', (error: BusinessError) => {
    console.error(`播放错误: code=${error.code}, message=${error.message}`);
    // 出错时重置播放器
    this.avPlayer?.reset();
  });

  // 其他有用的监听器
  this.avPlayer.on('durationUpdate', (duration: number) => {
    console.info(`视频总时长: ${duration}ms`);
  });

  this.avPlayer.on('timeUpdate', (time: number) => {
    console.info(`当前播放位置: ${time}ms`);
  });

  this.avPlayer.on('seekDone', (seekDoneTime: number) => {
    console.info(`跳转完成,时间: ${seekDoneTime}ms`);
  });

  this.avPlayer.on('bufferingUpdate', (infoType: media.BufferingInfoType, value: number) => {
    console.info(`缓冲更新: type=${infoType}, value=${value}`);
  });
}

3.3 设置播放资源

AVPlayer支持多种资源设置方式:

3.3.1 设置网络视频
typescript 复制代码
// 设置网络视频URL
setNetworkVideo(url: string): void {
  if (!this.avPlayer) {
    console.error('AVPlayer未初始化');
    return;
  }
  
  // 确保在idle状态下设置URL
  if (this.avPlayer.state === 'idle') {
    this.avPlayer.url = url;
  } else {
    console.error('当前状态不能设置URL');
  }
}
3.3.2 设置本地视频
typescript 复制代码
import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';

// 设置本地文件
async setLocalVideo(filePath: string): Promise<void> {
  if (!this.avPlayer) {
    return;
  }

  try {
    // 检查文件是否存在
    const isAccess = fs.accessSync(filePath);
    if (!isAccess) {
      console.error('文件不存在');
      return;
    }

    // 打开文件获取文件描述符
    const file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
    
    // 使用fdSrc设置文件描述符
    const avFileDescriptor: media.AVFileDescriptor = {
      fd: file.fd,
      offset: 0,
      length: fs.statSync(filePath).size
    };
    
    this.avPlayer.fdSrc = avFileDescriptor;
    console.info('本地视频设置成功');
  } catch (error) {
    console.error(`设置本地视频失败: ${(error as BusinessError).message}`);
  }
}
3.3.3 使用资源管理器
typescript 复制代码
// 使用ResourceManager获取RawFile资源
async setRawFileResource(resourceName: string): Promise<void> {
  try {
    const context = getContext(this) as common.UIAbilityContext;
    const resourceMgr = context.resourceManager;
    const rawFileDescriptor = await resourceMgr.getRawFd(resourceName);
    
    const avFileDescriptor: media.AVFileDescriptor = {
      fd: rawFileDescriptor.fd,
      offset: rawFileDescriptor.offset,
      length: rawFileDescriptor.length
    };
    
    if (this.avPlayer) {
      this.avPlayer.fdSrc = avFileDescriptor;
    }
  } catch (error) {
    console.error(`设置资源文件失败: ${(error as BusinessError).message}`);
  }
}

3.4 设置视频显示窗口

视频播放需要与XComponent组件配合,提供渲染表面:

typescript 复制代码
import { XComponentController, XComponent } from '@ohos.arkui.xcomponent';

@Entry
@Component
struct VideoPlayerComponent {
  private avPlayer: VideoPlayer = new VideoPlayer();
  private xComponentController: XComponentController = new XComponentController();
  @State isPlaying: boolean = false;

  build() {
    Column() {
      // 视频显示区域
      XComponent({
        id: 'video_surface',
        type: 'surface',
        controller: this.xComponentController
      })
        .width('100%')
        .height(300)
        .backgroundColor('#000000')
        .onLoad(() => {
          // XComponent加载完成后获取surfaceId
          let surfaceId = this.xComponentController.getXComponentSurfaceId();
          console.info('SurfaceId: ' + surfaceId);
          
          // 创建AVPlayer并设置surface
          this.avPlayer.createAVPlayer().then(() => {
            if (this.avPlayer.avPlayer) {
              this.avPlayer.avPlayer.surfaceId = surfaceId;
            }
          });
        })

      // 播放控制区域
      Row({ space: 20 }) {
        Button('播放网络视频')
          .onClick(() => {
            let url = 'https://example.com/sample.mp4';
            this.avPlayer.setNetworkVideo(url);
          })

        Button(this.isPlaying ? '暂停' : '播放')
          .onClick(() => {
            if (this.isPlaying) {
              this.avPlayer.avPlayer?.pause();
            } else {
              this.avPlayer.avPlayer?.play();
            }
            this.isPlaying = !this.isPlaying;
          })

        Button('停止')
          .onClick(() => {
            this.avPlayer.avPlayer?.stop();
            this.isPlaying = false;
          })
      }
      .margin(10)
    }
    .width('100%')
    .height('100%')
  }
}

4. 播放控制与状态管理

4.1 完整的播放控制方法

typescript 复制代码
class AdvancedVideoPlayer extends VideoPlayer {
  private currentPosition: number = 0;
  private duration: number = 0;
  private playbackSpeed: number = 1.0;

  // 播放控制
  async play(): Promise<void> {
    if (!this.avPlayer) return;
    
    try {
      if (this.avPlayer.state === 'prepared' || 
          this.avPlayer.state === 'paused' || 
          this.avPlayer.state === 'completed') {
        await this.avPlayer.play();
      }
    } catch (error) {
      console.error(`播放失败: ${(error as BusinessError).message}`);
    }
  }

  async pause(): Promise<void> {
    if (!this.avPlayer) return;
    
    try {
      if (this.avPlayer.state === 'playing') {
        await this.avPlayer.pause();
      }
    } catch (error) {
      console.error(`暂停失败: ${(error as BusinessError).message}`);
    }
  }

  async stop(): Promise<void> {
    if (!this.avPlayer) return;
    
    try {
      if (['prepared', 'playing', 'paused', 'completed'].includes(this.avPlayer.state)) {
        await this.avPlayer.stop();
      }
    } catch (error) {
      console.error(`停止失败: ${(error as BusinessError).message}`);
    }
  }

  // 跳转到指定位置
  async seekTo(position: number): Promise<void> {
    if (!this.avPlayer) return;
    
    try {
      // 确保位置在有效范围内
      const validPosition = Math.max(0, Math.min(position, this.duration));
      await this.avPlayer.seek(validPosition);
    } catch (error) {
      console.error(`跳转失败: ${(error as BusinessError).message}`);
    }
  }

  // 设置播放速度
  setSpeed(speed: number): void {
    if (!this.avPlayer) return;
    
    const validSpeeds = [0.75, 1.0, 1.25, 1.75, 2.0];
    if (validSpeeds.includes(speed)) {
      try {
        this.avPlayer.setSpeed(speed);
        this.playbackSpeed = speed;
      } catch (error) {
        console.error(`设置播放速度失败: ${(error as BusinessError).message}`);
      }
    }
  }

  // 设置音量
  setVolume(volume: number): void {
    if (!this.avPlayer) return;
    
    // 音量范围 0.0 - 1.0
    const safeVolume = Math.max(0.0, Math.min(1.0, volume));
    try {
      this.avPlayer.setVolume(safeVolume);
    } catch (error) {
      console.error(`设置音量失败: ${(error as BusinessError).message}`);
    }
  }

  // 获取当前播放信息
  getPlaybackInfo(): PlaybackInfo {
    return {
      currentPosition: this.currentPosition,
      duration: this.duration,
      playbackSpeed: this.playbackSpeed,
      state: this.avPlayer?.state || 'unknown'
    };
  }
}

interface PlaybackInfo {
  currentPosition: number;
  duration: number;
  playbackSpeed: number;
  state: string;
}

4.2 增强的事件监听

typescript 复制代码
private setEnhancedAVPlayerCallback(): void {
  if (!this.avPlayer) return;

  // 基础状态监听
  this.avPlayer.on('stateChange', (state: string, reason: media.StateChangeReason) => {
    console.info(`状态变化: ${state}, 原因: ${reason}`);
    this.handleStateChange(state, reason);
  });

  // 错误监听
  this.avPlayer.on('error', (error: BusinessError) => {
    console.error(`播放错误: code=${error.code}, message=${error.message}`);
    this.handlePlaybackError(error);
  });

  // 时间更新 - 用于进度显示
  this.avPlayer.on('timeUpdate', (time: number) => {
    this.currentPosition = time;
    this.updateProgressDisplay(time, this.duration);
  });

  // 时长更新
  this.avPlayer.on('durationUpdate', (duration: number) => {
    this.duration = duration;
    console.info(`视频总时长: ${this.formatTime(duration)}`);
  });

  // 缓冲更新
  this.avPlayer.on('bufferingUpdate', (infoType: media.BufferingInfoType, value: number) => {
    this.handleBufferingUpdate(infoType, value);
  });

  // 跳转完成
  this.avPlayer.on('seekDone', (seekDoneTime: number) => {
    console.info(`跳转完成: ${this.formatTime(seekDoneTime)}`);
    this.currentPosition = seekDoneTime;
  });

  // 视频尺寸变化
  this.avPlayer.on('videoSizeChange', (width: number, height: number) => {
    console.info(`视频尺寸: ${width}x${height}`);
    this.adjustVideoLayout(width, height);
  });

  // 音频中断处理
  this.avPlayer.on('audioInterrupt', (info: audio.InterruptEvent) => {
    this.handleAudioInterruption(info);
  });
}

private handleStateChange(state: string, reason: media.StateChangeReason): void {
  switch (state) {
    case 'idle':
      this.onIdleState();
      break;
    case 'initialized':
      this.onInitializedState();
      break;
    case 'prepared':
      this.onPreparedState();
      break;
    case 'playing':
      this.onPlayingState();
      break;
    case 'paused':
      this.onPausedState();
      break;
    case 'completed':
      this.onCompletedState();
      break;
    case 'stopped':
      this.onStoppedState();
      break;
    case 'released':
      this.onReleasedState();
      break;
    case 'error':
      this.onErrorState(reason);
      break;
  }
}

private formatTime(milliseconds: number): string {
  const seconds = Math.floor(milliseconds / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  
  const displayMinutes = minutes % 60;
  const displaySeconds = seconds % 60;
  
  if (hours > 0) {
    return `${hours}:${displayMinutes.toString().padStart(2, '0')}:${displaySeconds.toString().padStart(2, '0')}`;
  } else {
    return `${minutes}:${displaySeconds.toString().padStart(2, '0')}`;
  }
}

5. 高级功能实现

5.1 视频缩放模式设置

typescript 复制代码
// 设置视频缩放模式
setVideoScaleType(scaleType: media.VideoScaleType): void {
  if (!this.avPlayer) return;
  
  try {
    if (['prepared', 'playing', 'paused', 'completed'].includes(this.avPlayer.state)) {
      this.avPlayer.videoScaleType = scaleType;
    }
  } catch (error) {
    console.error(`设置缩放模式失败: ${(error as BusinessError).message}`);
  }
}

// 获取支持的缩放模式
getSupportedScaleTypes(): media.VideoScaleType[] {
  return [
    media.VideoScaleType.VIDEO_SCALE_TYPE_FIT,
    media.VideoScaleType.VIDEO_SCALE_TYPE_FIT_CROP,
    media.VideoScaleType.VIDEO_SCALE_TYPE_FILL
  ];
}

5.2 循环播放设置

typescript 复制代码
// 设置循环播放
setLooping(loop: boolean): void {
  if (!this.avPlayer) return;
  
  try {
    this.avPlayer.loop = loop;
  } catch (error) {
    console.error(`设置循环播放失败: ${(error as BusinessError).message}`);
  }
}

5.3 音频焦点管理

typescript 复制代码
import { audio } from '@kit.AudioKit';

private handleAudioInterruption(info: audio.InterruptEvent): void {
  console.info(`音频中断事件: forceType=${info.forceType}, hintType=${info.hintType}`);
  
  switch (info.forceType) {
    case audio.InterruptForceType.INTERRUPT_FORCE:
      // 强制中断(如来电)
      if (this.isPlaying) {
        this.pause();
        // 保存状态以便恢复
        this.shouldResumeOnFocusGain = true;
      }
      break;
      
    case audio.InterruptForceType.INTERRUPT_SHARE:
      // 共享模式,可降低音量但不暂停
      if (info.hintType === audio.InterruptHint.INTERRUPT_HINT_PAUSE) {
        this.pause();
      } else if (info.hintType === audio.InterruptHint.INTERRUPT_HINT_RESUME) {
        this.play();
      }
      break;
  }
}

// 设置音频中断模式
setAudioInterruptMode(mode: audio.InterruptMode): void {
  if (!this.avPlayer) return;
  
  try {
    if (['prepared', 'playing', 'paused', 'completed'].includes(this.avPlayer.state)) {
      this.avPlayer.audioInterruptMode = mode;
    }
  } catch (error) {
    console.error(`设置音频中断模式失败: ${(error as BusinessError).message}`);
  }
}

6. 完整的UI组件实现

下面是一个完整的视频播放器UI组件实现:

typescript 复制代码
@Entry
@Component
struct FullFeaturedVideoPlayer {
  private avPlayer: AdvancedVideoPlayer = new AdvancedVideoPlayer();
  private xComponentController: XComponentController = new XComponentController();
  @State isPlaying: boolean = false;
  @State currentTime: string = '00:00';
  @State totalTime: string = '00:00';
  @State progress: number = 0;
  @State showControls: boolean = true;
  @State isBuffering: boolean = false;
  @State bufferProgress: number = 0;

  build() {
    Column() {
      // 视频播放区域
      Stack() {
        XComponent({
          id: 'video_surface',
          type: 'surface',
          controller: this.xComponentController
        })
          .width('100%')
          .height(240)
          .backgroundColor('#000000')
          .onLoad(() => {
            this.initializePlayer();
          })

        // 缓冲指示器
        if (this.isBuffering) {
          Progress({ value: 0, total: 100 })
            .width(100)
            .height(100)
            .color('#FFFFFF')
        }

        // 控制层
        if (this.showControls) {
          Column() {
            // 顶部控制栏
            Row() {
              Button('返回')
                .fontSize(16)
                .fontColor('#FFFFFF')
                .backgroundColor('#66000000')
                .borderRadius(20)
                
              Blank()
              
              Text('视频播放器')
                .fontSize(18)
                .fontColor('#FFFFFF')
                
              Blank()
              
              Button('设置')
                .fontSize(16)
                .fontColor('#FFFFFF')
                .backgroundColor('#66000000')
                .borderRadius(20)
            }
            .width('100%')
            .padding(10)

            Blank()

            // 中间播放控制
            Row() {
              Button('前一个')
                .onClick(() => {
                  // 前一个视频逻辑
                })
                
              Button(this.isPlaying ? '❚❚' : '▶')
                .fontSize(24)
                .fontColor('#FFFFFF')
                .backgroundColor('#CC000000')
                .width(60)
                .height(60)
                .borderRadius(30)
                .onClick(() => {
                  this.togglePlayPause();
                })
                
              Button('后一个')
                .onClick(() => {
                  // 后一个视频逻辑
                })
            }

            Blank()

            // 底部进度控制
            Column() {
              // 进度条
              Row() {
                Text(this.currentTime)
                  .fontSize(12)
                  .fontColor('#FFFFFF')
                  
                Slider({
                  value: this.progress,
                  min: 0,
                  max: 100,
                  step: 1,
                  style: SliderStyle.OutSet
                })
                  .width('70%')
                  .onChange((value: number) => {
                    this.onProgressChange(value);
                  })
                  
                Text(this.totalTime)
                  .fontSize(12)
                  .fontColor('#FFFFFF')
              }

              // 底部控制按钮
              Row({ space: 20 }) {
                Button('倍速')
                  .onClick(() => {
                    this.showSpeedOptions();
                  })
                  
                Button('缩放')
                  .onClick(() => {
                    this.showScaleOptions();
                  })
                  
                Button('静音')
                  .onClick(() => {
                    this.toggleMute();
                  })
                  
                Button('全屏')
                  .onClick(() => {
                    this.toggleFullScreen();
                  })
              }
              .width('100%')
              .justifyContent(FlexAlign.SpaceAround)
              .margin({ top: 10 })
            }
            .width('100%')
            .padding(10)
            .backgroundColor('#66000000')
          }
        }
      }
      .width('100%')
      .height(240)
      .onClick(() => {
        this.showControls = !this.showControls;
      })

      // 视频列表或其他内容
      List({ space: 10 }) {
        ForEach(this.getVideoList(), (item: VideoItem) => {
          ListItem() {
            VideoListItem({ item: item })
              .onClick(() => {
                this.playVideo(item);
              })
          }
        })
      }
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F0F0F0')
  }

  private initializePlayer(): void {
    let surfaceId = this.xComponentController.getXComponentSurfaceId();
    this.avPlayer.createAVPlayer().then(() => {
      if (this.avPlayer.avPlayer) {
        this.avPlayer.avPlayer.surfaceId = surfaceId;
        this.setupPlayerCallbacks();
      }
    });
  }

  private setupPlayerCallbacks(): void {
    // 设置时间更新回调
    this.avPlayer.setTimeUpdateCallback((time: number, duration: number) => {
      this.currentTime = this.formatTime(time);
      this.totalTime = this.formatTime(duration);
      this.progress = duration > 0 ? (time / duration) * 100 : 0;
    });

    // 设置缓冲状态回调
    this.avPlayer.setBufferingCallback((isBuffering: boolean, progress: number) => {
      this.isBuffering = isBuffering;
      this.bufferProgress = progress;
    });
  }

  private togglePlayPause(): void {
    if (this.isPlaying) {
      this.avPlayer.pause();
    } else {
      this.avPlayer.play();
    }
    this.isPlaying = !this.isPlaying;
  }

  private onProgressChange(value: number): void {
    if (this.avPlayer.getPlaybackInfo().duration > 0) {
      const targetTime = (value / 100) * this.avPlayer.getPlaybackInfo().duration;
      this.avPlayer.seekTo(targetTime);
    }
  }

  private formatTime(milliseconds: number): string {
    const seconds = Math.floor(milliseconds / 1000);
    const minutes = Math.floor(seconds / 60);
    const hours = Math.floor(minutes / 60);
    
    const displayMinutes = minutes % 60;
    const displaySeconds = seconds % 60;
    
    if (hours > 0) {
      return `${hours}:${displayMinutes.toString().padStart(2, '0')}:${displaySeconds.toString().padStart(2, '0')}`;
    } else {
      return `${minutes}:${displaySeconds.toString().padStart(2, '0')}`;
    }
  }

  private getVideoList(): VideoItem[] {
    // 返回视频列表
    return [
      { id: '1', title: '示例视频1', url: 'https://example.com/video1.mp4', thumbnail: '' },
      { id: '2', title: '示例视频2', url: 'https://example.com/video2.mp4', thumbnail: '' }
    ];
  }

  private playVideo(item: VideoItem): void {
    this.avPlayer.setNetworkVideo(item.url);
    this.isPlaying = true;
  }
}

@Component
struct VideoListItem {
  private item: VideoItem;

  build() {
    Row() {
      Image(this.item.thumbnail)
        .width(60)
        .height(45)
        .backgroundColor('#DDDDDD')
        
      Column() {
        Text(this.item.title)
          .fontSize(16)
          .fontColor('#333333')
        Text('点击播放')
          .fontSize(12)
          .fontColor('#666666')
      }
      .layoutWeight(1)
      .margin({ left: 10 })
    }
    .width('100%')
    .padding(10)
    .backgroundColor('#FFFFFF')
    .borderRadius(8)
  }
}

interface VideoItem {
  id: string;
  title: string;
  url: string;
  thumbnail: string;
}

7. 性能优化与最佳实践

7.1 内存管理

typescript 复制代码
class OptimizedVideoPlayer extends AdvancedVideoPlayer {
  private memoryMonitor: MemoryMonitor = new MemoryMonitor();
  
  // 资源清理
  async cleanup(): Promise<void> {
    if (!this.avPlayer) return;
    
    const currentState = this.avPlayer.state;
    
    // 根据当前状态执行适当的清理
    if (['prepared', 'playing', 'paused', 'completed'].includes(currentState)) {
      await this.avPlayer.stop();
    }
    
    if (currentState !== 'idle' && currentState !== 'released') {
      await this.avPlayer.reset();
    }
    
    if (currentState !== 'released') {
      await this.avPlayer.release();
    }
    
    this.avPlayer = null;
  }
  
  // 监控内存使用
  private monitorMemoryUsage(): void {
    setInterval(() => {
      const memoryInfo = this.memoryMonitor.getMemoryInfo();
      if (memoryInfo.usage > memoryInfo.threshold * 0.8) {
        console.warn('内存使用过高,考虑清理资源');
        this.cleanupUnusedResources();
      }
    }, 5000);
  }
}

7.2 网络优化

typescript 复制代码
// 网络状态监控
private monitorNetworkStatus(): void {
  // 监听网络状态变化
  // 根据网络质量调整播放策略
}

// 自适应码率切换
private setupAdaptiveBitrate(): void {
  // 根据网络条件动态切换视频质量
}

8. 错误处理与调试

8.1 常见错误处理

typescript 复制代码
private handlePlaybackError(error: BusinessError): void {
  console.error(`播放错误: code=${error.code}, message=${error.message}`);
  
  switch (error.code) {
    case 5400101: // 媒体格式不支持
      this.showErrorMessage('视频格式不支持,请尝试其他格式');
      break;
      
    case 5400102: // 网络异常
      this.showErrorMessage('网络连接异常,请检查网络设置');
      break;
      
    case 5400103: // 解码失败
      this.showErrorMessage('视频解码失败');
      break;
      
    default:
      this.showErrorMessage('播放失败,请重试');
      break;
  }
  
  // 重置播放器状态
  this.resetPlayer();
}

private resetPlayer(): void {
  if (this.avPlayer && this.avPlayer.avPlayer) {
    this.avPlayer.avPlayer.reset();
  }
}

总结

本文详细介绍了在HarmonyOS中使用AVPlayer实现视频播放的完整流程,包括:

  1. AVPlayer实例创建与配置
  2. 状态机管理与事件监听
  3. 多种资源设置方式
  4. 与XComponent集成实现视频渲染
  5. 完整的播放控制功能
  6. 高级功能如缩放、循环播放等
  7. 性能优化和错误处理

通过以上实现,开发者可以构建功能完善、性能优异的视频播放应用。在实际开发中,建议根据具体需求选择合适的功能实现,并注意资源管理和错误处理,以提供更好的用户体验。

相关推荐
li理3 小时前
鸿蒙AVPlayer视频播放全解析:从基础实现到高级应用
harmonyos
HarmonyOS_SDK5 小时前
数字商品服务助力开发者降本增效,加速数字商品商业变现
harmonyos
后端小张7 小时前
【鸿蒙开发手册】重生之我要学习鸿蒙HarmonyOS开发
开发语言·学习·华为·架构·harmonyos·鸿蒙·鸿蒙系统
猫林老师8 小时前
HarmonyOS测试与上架:单元测试、UI测试与App Gallery Connect发布实战
ui·单元测试·harmonyos
SWUT胖虎8 小时前
ArkTS 中@Extend 和@Styles 装饰器的用法和区别
harmonyos·arkts·鸿蒙·鸿蒙系统
猫林老师10 小时前
鸿蒙元服务开发:免安装的卡片式服务(Atomic Service)
华为·wpf·harmonyos
shr007_20 小时前
flutter 鸿蒙
flutter·华为·harmonyos
鼓掌MVP1 天前
【案例实战】多维度视角:鸿蒙2048游戏开发的深度分析与感悟
华为·ai编程·harmonyos·arkts·游戏开发·ability
安卓开发者1 天前
鸿蒙Next Performance Analysis Kit:打造极致流畅的应用体验
华为·harmonyos