HarmonyOS鸿蒙Next中视频播放被打断后如何实现自动恢复播放

HarmonyOS鸿蒙Next中视频播放被打断后如何实现自动恢复播放 【问题描述】:视频播放被打断后如何实现自动恢复播放

【问题现象】:我在开发一款短视频类型的应用,现在遇到了一个问题,在我的应用视频播放过程中,下拉状态栏播放其他应用的音乐,我应用的视频播放会暂停。

我想要实现的方式有两种:

  1. 视频播放过程中下拉状态栏播放其他应用的音乐,我的应用中视频还是可以继续播放

2.视频播放过程中下拉状态栏播放其他应用的音乐,我的应用视频暂停播放,但是我在状态栏点击停止播放音乐按钮,我的应用视频可以自动恢复播放

以上两种解决方案哪一种都可以,但是要怎么实现呢?

【版本信息】:不涉及

【复现代码】:不涉及

【尝试解决方案】:不涉及


更多关于HarmonyOS鸿蒙Next中视频播放被打断后如何实现自动恢复播放的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

开发者您好,先播放视频在播放其他应用的音频,视频应用会被打断,这是目前系统默认的焦点策略:系统默认焦点策略表。不过开发者可以配置下你们播放视频应用的音频流类型(开发者尝试可以配置成游戏类型,系统打断策略是同时播放),配置音频流类型可以参考以下步骤:

设置音频渲染:只允许在initialized状态下,第一次调用prepare()之前设置,以便音频渲染器信息在之后生效。若媒体源包含视频,则usage默认值为STREAM_USAGE_MOVIE,否则usage默认值为STREAM_USAGE_MUSIC。rendererFlags默认值为0。

为了确保音频行为符合使用预期,建议根据具体业务场景和实际需求,主动配置audio.AudioRendererInfo,为音频选择恰当的流类型usage

import { audio } from '@kit.AudioKit';

avPlayer.audioRendererInfo = {
    usage: audio.StreamUsage.STREAM_USAGE_MOVIE,
    rendererFlags: 0
}

更多关于HarmonyOS鸿蒙Next中视频播放被打断后如何实现自动恢复播放的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


可以问问小艺参考一下!我也不懂,哈哈,

在HarmonyOS Next中,视频播放被打断后实现自动恢复播放,核心是监听系统中断事件并管理播放状态。主要使用AVSession和AVPlayer。当发生来电等中断时,系统会发送interrupt事件。你需要在AVSession的on('interrupt')回调中,根据interruptEvent的hint类型(如2/INTERRUPT_HINT_PAUSE)暂停播放并保存当前播放位置。当中断结束(hint为1/INTERRUPT_HINT_RESUME)时,在回调中调用AVPlayer的play()方法,并从保存的位置恢复播放。

在HarmonyOS Next中,处理音频焦点冲突以实现视频播放的自动恢复或共存,核心在于正确使用AudioManager进行音频焦点管理。以下是针对你两种需求的实现方案:

方案一:视频与背景音乐共存(共享音频焦点)

此方案允许你的视频在后台音乐播放时继续播放,两者声音混合。

  1. 请求音频焦点时指定行为: 在初始化视频播放器并请求音频焦点时,使用AudioFocusRequest.audioFocusRequest构建请求,并设置willPauseWhenDuckedfalse,同时建议使用AudioFocusType.AUDIO_FOCUS_TYPE_GAIN_TRANSIENT_MAY_DUCK

    import audio from '@ohos.multimedia.audio';
    
    // 创建音频焦点请求
    let focusRequest: audio.AudioFocusRequest = {
        focusType: audio.AudioFocusType.AUDIO_FOCUS_TYPE_GAIN_TRANSIENT_MAY_DUCK, // 焦点类型:临时获取,允许闪避
        willPauseWhenDucked: false // 当发生闪避时(如其他应用播放),不暂停本应用音频
    };
    
    // 请求音频焦点
    audioManager.requestAudioFocus(focusRequest).then(() => {
        // 焦点获取成功,开始播放视频
        videoPlayer.play();
    }).catch((err) => {
        console.error('请求音频焦点失败: ' + JSON.stringify(err));
    });
    
    • AUDIO_FOCUS_TYPE_GAIN_TRANSIENT_MAY_DUCK表示你的应用临时获取焦点,并允许其他应用同时播放时降低自身音量(而非暂停)。
    • willPauseWhenDucked: false确保在发生“闪避”(即其他应用播放导致系统建议降低音量)时,你的视频播放流不会暂停。
  2. 处理焦点变化: 你需要监听音频焦点的变化,以响应其他应用的行为。当其他应用(如音乐APP)请求焦点时,系统会通知你。

    // 设置音频焦点变化监听器
    audioManager.on('audioFocusChange', (focusChangeInfo: audio.AudioFocusChangeInfo) => {
        switch (focusChangeInfo.focusChange) {
            case audio.AudioFocusChangeType.AUDIO_FOCUS_TYPE_GAIN:
                // 重新获得焦点,恢复播放或提高音量
                if (!videoPlayer.isPlaying) {
                    videoPlayer.play();
                }
                // 可以调整音量至正常水平
                break;
            case audio.AudioFocusChangeType.AUDIO_FOCUS_TYPE_LOSS_TRANSIENT_CAN_DUCK:
                // 临时失去焦点,允许闪避。系统可能会降低你的音量,但根据willPauseWhenDucked:false,播放应继续。
                // 你可以选择主动调低音量以获得更好体验
                videoPlayer.setVolume(0.2); // 例如,将音量设置为20%
                break;
            case audio.AudioFocusChangeType.AUDIO_FOCUS_TYPE_LOSS_TRANSIENT:
                // 临时失去焦点(通常需要暂停),但你的焦点请求类型是MAY_DUCK,此情况可能不触发。
                // 如果触发,可考虑暂停播放。
                videoPlayer.pause();
                break;
            case audio.AudioFocusChangeType.AUDIO_FOCUS_TYPE_LOSS:
                // 永久失去焦点,应停止播放并释放资源
                videoPlayer.stop();
                audioManager.abandonAudioFocus(focusRequest);
                break;
        }
    });
    

方案一总结:通过请求MAY_DUCK类型的焦点并设置willPauseWhenDucked: false,你的视频播放会在后台音乐启动时尝试降低音量(或保持原音量)继续播放,而不是暂停。当后台音乐停止,系统会重新授予你焦点(AUDIO_FOCUS_TYPE_GAIN),此时你可以将音量恢复。

方案二:视频暂停,并在后台音乐停止后自动恢复

此方案更符合常见行为:视频在后台音乐播放时暂停,音乐停止后自动恢复。

  1. 请求音频焦点: 使用AUDIO_FOCUS_TYPE_GAIN_TRANSIENT类型请求焦点,这表示你的应用需要独占焦点,其他应用获取焦点时你会临时失去它。

    let focusRequest: audio.AudioFocusRequest = {
        focusType: audio.AudioFocusType.AUDIO_FOCUS_TYPE_GAIN_TRANSIENT, // 临时独占焦点
        willPauseWhenDucked: true // 默认值,失去焦点时暂停
    };
    audioManager.requestAudioFocus(focusRequest).then(() => {
        videoPlayer.play();
    });
    
  2. 处理焦点变化: 焦点变化监听是自动恢复的关键。

    audioManager.on('audioFocusChange', (focusChangeInfo: audio.AudioFocusChangeInfo) => {
        switch (focusChangeInfo.focusChange) {
            case audio.AudioFocusChangeType.AUDIO_FOCUS_TYPE_GAIN:
                // 重新获得焦点(例如用户停止了后台音乐)
                if (!videoPlayer.isPlaying) {
                    videoPlayer.play(); // 自动恢复播放
                }
                break;
            case audio.AudioFocusChangeType.AUDIO_FOCUS_TYPE_LOSS_TRANSIENT:
                // 临时失去焦点(如下拉状态栏播放音乐)
                if (videoPlayer.isPlaying) {
                    videoPlayer.pause(); // 暂停视频播放
                    // 可以记录播放位置,以便恢复
                }
                break;
            case audio.AudioFocusChangeType.AUDIO_FOCUS_TYPE_LOSS:
                // 永久失去焦点,停止并释放
                videoPlayer.stop();
                audioManager.abandonAudioFocus(focusRequest);
                break;
            // AUDIO_FOCUS_TYPE_LOSS_TRANSIENT_CAN_DUCK 在这种焦点类型下通常不会收到
        }
    });
    

方案二总结:通过AUDIO_FOCUS_TYPE_GAIN_TRANSIENT请求焦点,当其他应用(如音乐播放器)获取焦点时,你的应用会收到AUDIO_FOCUS_TYPE_LOSS_TRANSIENT事件,在此处暂停视频。当该应用释放焦点(用户停止音乐)时,你的应用会收到AUDIO_FOCUS_TYPE_GAIN事件,在此处恢复播放。

实现建议

  • 选择方案二更为通用和符合用户预期,即视频播放时,若有其他音频(如电话、音乐)介入,则视频暂停,待其结束后自动恢复。
  • 在应用生命周期中管理焦点:在应用挂起(如进入后台)时,应主动调用audioManager.abandonAudioFocus(focusRequest)释放焦点,并在恢复时重新请求。
  • 测试不同场景:请在实际设备上测试与系统音乐播放器、通话等应用的交互,确保行为符合预期。

通过上述AudioManager的音频焦点管理机制,你可以精确控制应用在多媒体冲突时的播放行为。

回到顶部