/
githubmirror
/
taro
Обзор
Документация
Войти
/
githubmirror
/
taro
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
packages/taro-platform-harmony-cpp/src/runtime/components/video.ets
119 строк
5 KB
ZakaryCode
feat(harmony): 修复 audio-session 触发机制
09 май 2025, 06:42
09 май 2025, 06:42
3847f76
Код
Авторство
О чём код?
import { audio } from '@kit.AudioKit' import { AREA_CHANGE_EVENT_NAME, Current, createTaroEvent, eventHandler, getComponentEventCallback, VISIBLE_CHANGE_EVENT_NAME } from '@tarojs/runtime' import commonStyleModify from './style' import { shouldBindEvent, getNodeThresholds } from './utils/helper' import type { TaroAny, TaroEvent, TaroVideoElement } from '@tarojs/runtime' export interface VideoUpdateEvent { time: number } function emitEvent (node: TaroVideoElement, type: string, detail?: TaroAny) { const event: TaroEvent = createTaroEvent(type, { detail }, node) event.stopPropagation() eventHandler(event, type, node) } function handleUpdate (node: TaroVideoElement, e: VideoUpdateEvent) { node._nodeInfo._currentTime = e.time emitEvent(node, 'timeUpdate', { currentTime: e.time}) } @ComponentV2 export default struct TaroVideo { @Builder customBuilder() {} @BuilderParam createLazyChildren: (node: TaroVideoElement) => void = this.customBuilder @Param @Require node: TaroVideoElement controller: VideoController = new VideoController() @Local attrSrc: string = '' @Local attrPoster: string = '' @Local attrAutoplay: boolean = false @Local attrControls: boolean = false @Local attrLoop: boolean = false @Local attrMuted: boolean = false @Local attrObjectFit: string = '' @Computed get computedObjectFit () { switch (this.attrObjectFit) { case 'contain': return ImageFit.Contain case 'cover': return ImageFit.Cover case 'fill': return ImageFit.Fill default: return ImageFit.Contain } } aboutToAppear(): void { if (this.node) { this.node._instance = this this.node.controller = this.controller this.attrSrc = this.node._attrs.src ?? this.attrSrc this.attrPoster = this.node._attrs.poster ?? this.attrPoster this.attrAutoplay = this.node._attrs.autoplay ?? this.attrAutoplay this.attrControls = this.node._attrs.controls ?? this.attrControls this.attrLoop = this.node._attrs.loop ?? this.attrLoop this.attrMuted = this.node._attrs.muted ?? this.attrMuted this.attrObjectFit = this.node._attrs.objectFit ?? this.attrObjectFit } } refreshAudioSession() { if (Current.audioSessionManager) { const manager: audio.AudioSessionManager = Current.audioSessionManager if (manager.isAudioSessionActivated()) { manager.deactivateAudioSession().then(() => { let strategy: audio.AudioSessionStrategy = { concurrencyMode: audio.AudioConcurrencyMode.CONCURRENCY_PAUSE_OTHERS } manager.activateAudioSession(strategy) }) } } } aboutToDisappear(): void { setTimeout(() => { this.refreshAudioSession() }, 200) } build () { Video({ src: this.attrSrc, previewUri: this.attrPoster, controller: this.node.controller }) .attributeModifier(commonStyleModify.setNode(this.node)) .muted(this.attrMuted || false) .autoPlay(this.attrAutoplay || false) .controls(this.attrControls || false) .objectFit(this.computedObjectFit) .loop(this.attrLoop || false) .onStart(shouldBindEvent(() => { emitEvent(this.node, 'play') }, this.node, ['play'])) .onPause(() => { shouldBindEvent(() => { emitEvent(this.node, 'pause') }, this.node, ['pause'])?.() this.refreshAudioSession() }) .onStop(() => { this.refreshAudioSession() }) .onFinish(() => { shouldBindEvent(() => { emitEvent(this.node, 'ended') }, this.node, ['ended'])?.() this.refreshAudioSession() }) .onError(shouldBindEvent(() => { emitEvent(this.node, 'error') }, this.node, ['error'])) .onUpdate((e) => { handleUpdate(this.node, e) }) .onPrepared(shouldBindEvent((e: TaroAny) => { emitEvent(this.node, 'loadedMetaData', { duration: e.duration }) }, this.node, ['loadedmetadata'])) .onSeeking(shouldBindEvent((e: TaroAny) => { emitEvent(this.node, 'seeking', { duration: e.time }) }, this.node, ['seeking'])) .onSeeked(shouldBindEvent(() => { emitEvent(this.node, 'seeked') }, this.node, ['seeked'])) .onFullscreenChange(shouldBindEvent((e: TaroAny) => { emitEvent(this.node, 'fullScreenChange', { fullScreen: e.fullscreen}) }, this.node, ['fullscreenchange'])) .onAreaChange(getComponentEventCallback(this.node, AREA_CHANGE_EVENT_NAME, (res: TaroAny) => { this.node._nodeInfo.areaInfo = res[1] })) .onVisibleAreaChange(getNodeThresholds(this.node) || [0.0, 1.0], getComponentEventCallback(this.node, VISIBLE_CHANGE_EVENT_NAME)) } }