在HarmonyOS NEXT开发中VideoController无法继承?

在HarmonyOS NEXT开发中VideoController无法继承?继承VideoController后,再调用VideoController中的方法不再生效;现象就是点击暂停,暂停不下来,debug和日志可以看到方法已经被调用

阅读 1.2k
avatarAI BotBETA

在 HarmonyOS NEXT 开发中遇到 VideoController 继承失效的问题,可能涉及以下原因和解决方案:


1. 类封闭性限制

  • 现象:直接继承 VideoController 后方法调用无效
  • 原因VideoController 可能被设计为 final 类或未开放继承权限
  • 验证方式

    // 尝试继承时若IDE报错"cannot inherit from final VideoController"
    public class CustomVideoController extends VideoController { ... } // 编译错误则证明类被封闭
  • 解决方案
    改用 组合模式 替代继承:

    public class CustomController {
        private VideoController mController;
    
        public CustomController(VideoController controller) {
            this.mController = controller;
        }
    
        // 通过委托调用原有方法
        public void customPause() {
            mController.pause();
            // 添加自定义逻辑
        }
    }

2. 生命周期未正确绑定

  • 现象:方法被调用但无实际效果
  • 关键检查点

    // 确保在组件生命周期中正确绑定
    @Override
    public void onPageShow() {
        super.onPageShow();
        mVideoController.bind(mVideoComponent); // 必须绑定到组件
    }
  • 典型错误:在 onPageHide() 后未释放资源,导致后续调用失效

3. 事件监听未覆盖

  • HarmonyOS 推荐模式:通过监听器实现控制逻辑而非直接继承
  • 正确写法

    mVideoComponent.setVideoStateListener(new VideoStateListener() {
        @Override
        public void onPlayStatusChanged(boolean isPlaying) {
            // 处理播放状态变更
        }
    
        @Override
        public void onControlRequest(String cmd) {
            if ("CUSTOM_PAUSE".equals(cmd)) {
                doCustomPauseAction();
            }
        }
    });

4. 异步操作未等待

  • 常见于:在播放器未就绪时调用方法
  • 健壮性处理

    mVideoController.prepare(new AVPlayer.AVPlayerCallback() {
        @Override
        public void onPrepared() {
            // 确保在此回调后执行操作
            mVideoController.pause();
        }
    });

5. 调试建议

  1. 添加 调用栈日志

    public void pause() {
        Log.info("CustomCtrl", "Pause called, isActive=" + isBound());
        super.pause(); // 如果继承可行
        // 或 mController.pause();
    }
  2. 检查 权限声明

    // module.json5
    "abilities": [{
      "permissions": [
        "ohos.permission.INTERNET",
        "ohos.permission.MEDIA_CONTROL" // 视频控制所需权限
      ]
    }]

如问题仍未解决,建议提供以下信息进一步分析:

  • 继承 VideoController 的具体实现代码片段
  • 日志中是否出现 IllegalStateExceptionUnsupportedOperationException
  • 使用的 SDK 版本号(可通过 ohos.sysversion.SystemVersion.get() 获取)
1 个回答

解决方案如下:

// xxx.ets 
@Entry 
@Component 
struct VideoCreateComponent { 
  @State videoSrc: Resource = $rawfile('video1.mp4') 
  @State previewUri: Resource = $r('app.media.APEX') 
  @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X 
  @State isAutoPlay: boolean = false 
  @State showControls: boolean = true 
  controller: myVideoCol = new myVideoCol(); 
 
  build() { 
    Column() { 
      Video({ 
        src: this.videoSrc, 
        previewUri: this.previewUri, 
        currentProgressRate: this.curRate, 
        controller: this.controller 
      }) 
        .width('100%') 
        .height(600) 
        .autoPlay(this.isAutoPlay) 
        .controls(this.showControls) 
        .onStart(() => { 
          console.info('onStart') 
        }) 
        .onPause(() => { 
          console.info('onPause') 
        }) 
        .onUpdate((e?: TimeObject) => { 
          if (e != undefined) { 
            console.info('onUpdate is ' + e.time) 
          } 
        }) 
 
      Row() { 
        Button('start').onClick(() => { 
          this.controller.myStart() // 开始播放 
        }).margin(5) 
        Button('pause').onClick(() => { 
          this.controller.pause() // 暂停播放 
        }).margin(5) 
        Button('stop').onClick(() => { 
          this.controller.myStop() // 结束播放 
        }).margin(5) 
        Button('setTime').onClick(() => { 
          this.controller.mySeekTo(10) // 精准跳转到视频的10s位置 
          // this.controller.setCurrentTime(10, SeekMode.Accurate) // 精准跳转到视频的10s位置 
        }).margin(5) 
      } 
 
    } 
  } 
} 
 
interface DurationObject { 
  duration: number; 
} 
 
interface TimeObject { 
  time: number; 
} 
 
class myVideoCol extends VideoController { 
  myStart(): void { 
    console.log("myVideoCol === myStart") 
    super.start() 
  } 
 
  pause(): void { 
    console.log("myVideoCol === myPause") 
    super.pause() 
  } 
 
  myStop(): void { 
    console.log("myVideoCol === myStop") 
    super.stop() 
  } 
 
  mySeekTo(time: number): void { 
    console.log("myVideoCol === mySeekTo") 
    super.setCurrentTime(time) 
  } 
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题