HarmonyOS鸿蒙Next中录制屏幕时,调用stopRecording不会触发stateChange

HarmonyOS鸿蒙Next中录制屏幕时,调用stopRecording不会触发stateChange

import { IRecordMode } from ‘…/common/Model’ import { RecordProgress } from ‘./RecordProgress’

@Preview @Component export struct ScreenRecordSmallView { @Link mode: IRecordMode @Link lastTime: number @Link hasStart: boolean @Require startRecord?: Function @Require stopRecord?: Function

build() { Row() { RecordProgress({ startRecord: this.startRecord, stopRecord: this.stopRecord, hasStart: this.hasStart, lastTime: this.lastTime, showBig: false }) Divider() .vertical(true) .color(’#1FFFFFFF’) .margin({ left: 12, right: 12 }) .strokeWidth(1) Image($r(‘app.media.open_camera’)) .size({ width: 46, height: 24 }) .objectFit(ImageFit.Contain) .onClick(() => { this.mode = ‘video’ }) } .height(48) .padding(12) .backgroundColor(’#7A3DFF’) .borderRadius(9) } }

@Preview @Component export struct RecordProgress { @Prop hasStart: boolean @Prop lastTime: number @State value: number = 0 @Prop showBig: boolean = false @Require startRecord?: Function @Require stopRecord?: Function

formatSecondsToMMSS(seconds: number): string { const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; const minutesString = minutes < 10 ? 0${minutes} : ${minutes}; const secondsString = remainingSeconds < 10 ? 0${remainingSeconds} : ${remainingSeconds}; return ${minutesString}:${secondsString}; }

build() { Row() { Column() { if (this.showBig) { Text(this.hasStart ? this.formatSecondsToMMSS(this.lastTime) : $r(‘app.string.sr_start’)) .fontColor(Color.White) .fontSize(12) .margin({ left: 0, bottom: 8 }) } Stack() { Progress({ type: ProgressType.Ring, value: this.value, }) .size({ width: 24, height: 24 }) .style({ strokeWidth: 2 }) .backgroundColor(Color.White)

      if (this.hasStart) {
        Rect({ width: 12, height: 12 })
          .radius(3)
          .fill('#EB5D5D')
          .id('stop_record')
      } else {
        Circle({ width: 17, height: 17 })
          .fill('#EB5D5D')
          .id('start_record')
      }
    }
    .onClick(() => {
      if (!this.hasStart) {
        this.startRecord?()
      } else {
        this.stopRecord?()
      }
    })
  }

  if (!this.showBig) {
    Text(this.hasStart ? this.formatSecondsToMMSS(this.lastTime) : $r('app.string.sr_start'))
      .fontColor(Color.White)
      .fontSize(12)
      .margin({
        left: 8,
        bottom: 0
      })
  }
}

} }

import { BusinessError } from ‘@kit.BasicServicesKit’; import { camera } from ‘@kit.CameraKit’; import { abilityAccessCtrl, common, PermissionRequestResult, Permissions } from ‘@kit.AbilityKit’; import { IRecordMode } from ‘…/common/Model’; import { RecordProgress } from ‘./RecordProgress’; import { StyleConstants, toast } from ‘@lunar/tools’;

@Component @Preview export struct ScreenRecordStreamView { private xComponentController: XComponentController = new XComponentController(); private context = getContext(this) as common.UIAbilityContext; @Prop @Watch(‘handleReloadCountChange’) reloadCount: number = 0 @Link mode: IRecordMode @Link lastTime: number @Link hasStart: boolean @Require startRecord?: Function @Require stopRecord?: Function @State contentWidth: Length = $r(‘app.float.float_window_width’); @State contentHeight: Length = $r(‘app.float.float_window_height’); @State captureSession?: camera.Session = undefined

async getCameraImage() { // 1、使用系统相机框架camera模块获取物理摄像头信息。 let cameraManager = camera.getCameraManager(this.context); let camerasInfo: Array<camera.CameraDevice> = cameraManager.getSupportedCameras(); let cameraDevice: camera.CameraDevice = camerasInfo[0]; // 2、创建并启动物理摄像头输入流通道 // 设置为前置摄像头 camera.CameraPosition.CAMERA_POSITION_FRONT let cameraInput = cameraManager.createCameraInput(camera.CameraPosition.CAMERA_POSITION_FRONT, camera.CameraType.CAMERA_TYPE_DEFAULT); await cameraInput.open(); // 3、拿到物理摄像头信息查询摄像头支持预览流支持的输出格式,结合XComponent提供的surfaceId创建预览输出通道 let outputCapability = cameraManager.getSupportedOutputCapability(cameraDevice, camera.SceneMode.NORMAL_PHOTO); let previewProfile = outputCapability.previewProfiles[0]; const realW = previewProfile.size.width const realH = previewProfile.size.height const ratio = realW / realH this.xComponentController.setXComponentSurfaceRect({ surfaceWidth: realW, surfaceHeight: realH }); this.contentHeight = px2vp(realW / ratio) let surfaceId = this.xComponentController.getXComponentSurfaceId(); let previewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId); // 4、创建相机会话,在会话中添加摄像头输入流和预览输出流,然后启动会话,预览画面就会在XComponent组件上送显。 this.captureSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO); this.captureSession.beginConfig(); this.captureSession.addInput(cameraInput); this.captureSession.addOutput(previewOutput); this.captureSession.commitConfig() this.captureSession.start(); }

handleReloadCountChange() { if (!this.context) { return } this.xComponentController.setXComponentSurfaceRotation({ lock: true }) let permissions: Array<Permissions> = [‘ohos.permission.CAMERA’, ‘ohos.permission.MICROPHONE’] let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); atManager.requestPermissionsFromUser(this.context, permissions).then((data: PermissionRequestResult) => { let grantStatus: Array<number> = data.authResults; let length: number = grantStatus.length; // 只有录音权限,则跳转到纯录音模式 if (grantStatus[0] !== 0 && grantStatus[1] === 0) { this.mode = ‘audio’ toast(‘当前仅打开了录音权限~’) return } else { for (let i = 0; i < length; i++) { if (grantStatus[i] != 0) { toast(‘请去设置打开相机以及麦克风权限~’) return; } } this.getCameraImage() } }).catch((err: BusinessError) => { }) }

aboutToDisappear(): void { this.captureSession?.release() }

build() { Row() { Stack() { XComponent({ id: ‘xComponentId1’, type: ‘surface’, controller: this.xComponentController }) .id(‘preview_container’) .onLoad(() => { this.handleReloadCountChange() }) Column() { Image($r(‘app.media.icon_microphone’)) .size({ width: 34, height: 34 }) .padding(6) .objectFit(ImageFit.Contain) .onClick(() => { this.mode = ‘audio’ this.captureSession?.release() toast(‘切换到纯录音模式’) }) RecordProgress({ startRecord: this.startRecord, stopRecord: this.stopRecord, hasStart: this.hasStart, lastTime: this.lastTime, showBig: true }) } .padding({ bottom: 6 }) .height(StyleConstants.FULL_HEIGHT) .justifyContent(FlexAlign.SpaceBetween) } .size({ width: this.contentWidth, height: this.contentHeight }) } } }


更多关于HarmonyOS鸿蒙Next中录制屏幕时,调用stopRecording不会触发stateChange的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

media.createAVScreenCaptureRecorder改为同步操作

更多关于HarmonyOS鸿蒙Next中录制屏幕时,调用stopRecording不会触发stateChange的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,录制屏幕时调用stopRecording方法不会触发stateChange事件。这是因为stateChange事件主要用于监听录制状态的变化,例如从“准备中”到“录制中”或“暂停中”等。而stopRecording方法直接终止录制,不会经历状态变化的中间过程,因此不会触发stateChange事件。如果需要监听录制结束的事件,可以使用onRecordingComplete回调来捕获录制完成的通知。

在HarmonyOS鸿蒙Next中,调用stopRecording方法停止屏幕录制时,stateChange事件可能未被触发的原因通常与事件监听器的注册或状态更新机制有关。建议检查以下几点:

  1. 事件监听器注册:确保已正确注册stateChange事件监听器,并在适当的生命周期方法中进行了绑定。
  2. 状态更新时机:stopRecording可能不会立即触发状态更新,尝试在调用stopRecording后短暂延迟再检查状态。
  3. API调用顺序:确保stopRecording是在startRecording成功调用后执行的,避免时序问题。

如果问题仍未解决,建议查阅官方文档或联系技术支持以获取更详细的帮助。

回到顶部