HarmonyOS鸿蒙Next中音视频播放问题

HarmonyOS鸿蒙Next中音视频播放问题 使用AVPlayer播放音频,在音频播放期间打开华为视频app播放视频。AVPlayer会收到audioInterrupt事件,但是在App内的Webview里面播放视频,就收不到audioInterrupt事件。AVPlayer的打断模式是INDEPENDENT_MODE

请问如果我需要在Webview播放视频的时候也收InterruptEvent事件,需要如何处理?

HarmonyOS NEXT Developer Beta6 SDK, based on OpenHarmony SDK Ohos_sdk_public 5.0.0.61 (API Version 12 Beta6)


更多关于HarmonyOS鸿蒙Next中音视频播放问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

参考音频打断策略,看能否解决您的问题:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/audio-playback-concurrency-V5

可参考如下文档托管网页中的媒体播放,看能否解决问题:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/app-takeovers-web-media-V5# 完整示例

如果是网页版本,可以试试都设置成独立焦点模式,应该是能收到的

在prepared/playing/paused/completed状态下设置avPlayer.audioInterruptMode = audio.InterruptMode.INDEPENDENT_MODE,实现独立焦点模式,播放web组件的视频时,可以接受到打断事件,正常打断,

本地测试使用的真机版本为5.0Beta1MR3,您可以尝试使用该版本测试,

import media from '[@ohos](/user/ohos).multimedia.media';
import fs from '[@ohos](/user/ohos).file.fs';
import common from '[@ohos](/user/ohos).app.ability.common';
import { BusinessError } from '[@ohos](/user/ohos).base';
import { webview } from '[@kit](/user/kit).ArkWeb';
import { audio } from '[@kit](/user/kit).AudioKit';

[@Entry](/user/Entry)
[@Component](/user/Component)
struct Index {
    @State message: string = 'Hello World';
    private avPlayer: media.AVPlayer | null = null;
    private count: number = 0;
    private isSeek: boolean = true; // 用于区分模式是否支持seek操作
    private fileSize: number = -1;
    private fd: number = 0;
    private webviewController: WebviewController = new webview.WebviewController();

    async aboutToAppear(): Promise<void> {
        this.avPlayer = await media.createAVPlayer();
        console.log('666660' + this.avPlayer.state)
        this.setAVPlayerCallback(this.avPlayer);
        if (this.avPlayer != null) {
            this.avPlayerUrlDemo();
        }
    }

    async avPlayerFdSrcDemo() {
        let context = getContext(this) as common.UIAbilityContext;
        let fileDescriptor = await context.resourceManager.getRawFd('123.mp3');
        let avFileDescriptor: media.AVFileDescriptor =
            { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length };
        this.isSeek = false; // 支持seek操作
        if (this.avPlayer != null) {
            this.avPlayer.fdSrc = avFileDescriptor;
            console.log('666661' + this.avPlayer.state)
            console.log('666662' + this.avPlayer.state)
        }
    }

    async avPlayerLiveDemo() {
        this.avPlayer = await media.createAVPlayer();
        this.setAVPlayerCallback(this.avPlayer);
        this.isSeek = false; // 不支持seek操作
        this.avPlayer.url = 'https://www.cambridgeenglish.org/images/153149-movers-sample-listening-test-vol2.mp3'
    }

    async avPlayerUrlDemo() {
        const resourceManager = getContext(this).resourceManager
        const imageArray = await resourceManager.getMediaContent($r(""app.media.dx""));
        let fdPath = 'fd://';
        let path: string = ""/01.mp3"";
        console.log("yuv_path is": + path);
        let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
        fs.write(file.fd, imageArray.buffer).then(async (writeLen) => {
            console.info("write data to file succeed and size is": + writeLen);
            fs.closeSync(file);
            let file1 = await fs.open(path);
            fdPath = fdPath + '' + file1.fd;
            if (this.avPlayer != null) {
                this.avPlayer.url = fdPath;
                console.log('666661' + this.avPlayer.state)
            }
        }).catch((err: BusinessError) => {
            console.info("write data to file failed with error message": + err.message, error code: + err.code);
        });
    }

    setAVPlayerCallback(avPlayer: media.AVPlayer) {
        avPlayer.on('seekDone', (seekDoneTime: number) => {
            console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
        })

        avPlayer.on('error', (err: BusinessError) => {
            console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
            avPlayer.reset(); // 调用reset重置资源,触发idle状态
        })

        avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
            switch (state) {
                case 'idle': // 成功调用reset接口后触发该状态机上报
                    console.info('AVPlayer state idle called.');
                    break;
                case 'initialized': // avplayer 设置播放源后触发该状态上报
                    console.info('666AVPlayer state initialized called.666666666666666');
                    avPlayer.prepare();
                    break;
                case 'prepared': // prepare调用成功后上报该状态机
                    console.info('AVPlayer state prepared called.');
                    avPlayer.audioInterruptMode = audio.InterruptMode.INDEPENDENT_MODE;
                    break;
                case 'playing': // play成功调用后触发该状态机上报
                    console.info('AVPlayer state playing called.');
                    break;
                case 'paused': // pause成功调用后触发该状态机上报
                    console.info('AVPlayer state paused called.');
                    break;
                case 'completed': // 播放结束后触发该状态机上报
                    console.info('AVPlayer state completed called.');
                    avPlayer.stop(); //调用播放结束接口
                    break;
                case 'stopped': // stop接口成功调用后触发该状态机上报
                    console.info('AVPlayer state stopped called.');
                    break;
                case 'released':
                    console.info('AVPlayer state released called.');
                    break;
                default:
                    console.info('AVPlayer state unknown called.');
                    break;
            }
        })
    }

    build() {
        Row() {
            Column() {
                Text(this.message)
                    .fontSize(50)
                    .fontWeight(FontWeight.Bold)
                Button('play')
                    .margin(10)
                    .onClick(async (event: ClickEvent) => {
                        if (this.avPlayer != null) {
                            console.log('6666677' + this.avPlayer.state)
                            this.avPlayer.play();
                        }
                    })
                Button('reset').onClick(async (event: ClickEvent) => {
                    if (this.avPlayer != null) {
                        await this.avPlayer.reset();
                        let context = getContext(this) as common.UIAbilityContext;
                        let fileDescriptor = await context.resourceManager.getRawFd('稻香.mp3');
                        let avFileDescriptor1: media.AVFileDescriptor =
                            { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length };
                        this.isSeek = false; // 支持seek操作
                        this.avPlayer.fdSrc = avFileDescriptor1;
                    }
                })
                Web({
                    controller: this.webviewController,
                    src: "http://www.w3school.com.cn/example/html5/mov_bbb.mp4"
                }).javaScriptAccess(true).domStorageAccess(true).fileAccess(true).imageAccess(true).mixedMode(MixedMode.All).databaseAccess(true)
            }
    .width('100%')
        }
    .height('100%')
    }
}

更多关于HarmonyOS鸿蒙Next中音视频播放问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,音视频播放问题可能涉及以下几个方面:

  1. 媒体框架:HarmonyOS提供了统一的媒体框架,支持多种音视频格式的播放。开发者可以通过MediaPlayer类来实现音视频的播放控制,包括播放、暂停、停止等操作。

  2. 硬件加速:鸿蒙系统支持硬件加速,能够利用设备的GPU进行音视频解码,提升播放性能。开发者可以通过配置MediaPlayer的硬件加速选项来启用或禁用此功能。

  3. 音频管理:鸿蒙系统提供了音频管理服务,支持多路音频流的混音和管理。开发者可以通过AudioManager类来控制音频流的焦点、音量等参数。

  4. 视频渲染:鸿蒙系统支持多种视频渲染方式,包括SurfaceView和TextureView。开发者可以根据需求选择合适的渲染方式,并通过MediaPlayersetDisplay方法设置渲染目标。

  5. 网络播放:鸿蒙系统支持通过网络流媒体协议(如HTTP、RTSP等)进行音视频播放。开发者可以通过MediaPlayersetDataSource方法设置网络流媒体URL。

  6. 错误处理:在音视频播放过程中,可能会遇到各种错误,如网络连接问题、格式不支持等。鸿蒙系统提供了MediaPlayer.OnErrorListener接口,开发者可以通过实现该接口来处理播放错误。

  7. 权限管理:在鸿蒙系统中,音视频播放可能需要访问设备的多媒体资源或网络资源,因此需要申请相应的权限。开发者需要在应用的配置文件中声明所需的权限。

  8. 系统资源管理:鸿蒙系统提供了系统资源管理服务,能够监控和管理应用对系统资源的使用情况。开发者可以通过ResourceManager类来获取系统资源的使用情况,并根据需要进行优化。

以上是HarmonyOS鸿蒙Next中音视频播放问题的主要方面,开发者可以根据具体需求进行相应的开发和调试。

在HarmonyOS鸿蒙Next中,音视频播放主要依赖于MediaPlayerAudioManager等API。开发者需确保正确初始化MediaPlayer,设置数据源,并调用prepareAsync()异步准备播放。常见问题包括:1) 未正确设置权限(如INTERNET权限);2) 数据源格式不兼容;3) 未处理播放状态回调(如onPreparedonError)。建议使用SurfaceViewTextureView显示视频,并通过AudioManager管理音频焦点,确保播放流畅。

回到顶部