xugenyuan

ref |> 音频播放接入系统播控中心

1 import window from '@ohos.window'; 1 import window from '@ohos.window';
2 import { Logger } from 'wdKit'; 2 import { Logger } from 'wdKit';
3 -import { WDPlayerController } from 'wdPlayer'; 3 +import { BackgroundAudioController, WDPlayerController } from 'wdPlayer';
4 import { BusinessError } from '@ohos.base'; 4 import { BusinessError } from '@ohos.base';
5 import { EmitterEventId, EmitterUtils } from 'wdKit/Index' 5 import { EmitterEventId, EmitterUtils } from 'wdKit/Index'
6 6
@@ -42,6 +42,14 @@ export class AudioSuspensionModel { @@ -42,6 +42,14 @@ export class AudioSuspensionModel {
42 public setPlayerUrl(url: string, srcTitle: string) { 42 public setPlayerUrl(url: string, srcTitle: string) {
43 /*console.log(TAG,'this.url', this.url) 43 /*console.log(TAG,'this.url', this.url)
44 console.log(TAG,'url', url)*/ 44 console.log(TAG,'url', url)*/
  45 + this.playerController.get().keepOnBackground = true
  46 + BackgroundAudioController.sharedController().avplayerController = this.playerController.get()
  47 + BackgroundAudioController.sharedController().createSession()
  48 + BackgroundAudioController.sharedController().startContinuousTask()
  49 + BackgroundAudioController.sharedController().setSessionMetaData("aaa", srcTitle, "")
  50 + BackgroundAudioController.sharedController().stopUseFeatures()
  51 + BackgroundAudioController.sharedController().listenPlayEvents()
  52 +
45 if (this.url === url) { 53 if (this.url === url) {
46 this.isMinimize = AppStorage.link<boolean>('isMinimize') 54 this.isMinimize = AppStorage.link<boolean>('isMinimize')
47 console.log(TAG, 'this.isMinimize', this.isMinimize?.get()) 55 console.log(TAG, 'this.isMinimize', this.isMinimize?.get())
@@ -16,4 +16,6 @@ export { WDAliPlayerController } from "./src/main/ets/controller/WDAliPlayerCont @@ -16,4 +16,6 @@ export { WDAliPlayerController } from "./src/main/ets/controller/WDAliPlayerCont
16 16
17 export { WDListPlayerData, WDAliListPlayerController } from "./src/main/ets/controller/WDAliListPlayerController" 17 export { WDListPlayerData, WDAliListPlayerController } from "./src/main/ets/controller/WDAliListPlayerController"
18 18
19 -export { AliPlayerRenderView } from "./src/main/ets/pages/AliPlayerRenderView"  
  19 +export { AliPlayerRenderView } from "./src/main/ets/pages/AliPlayerRenderView"
  20 +
  21 +export { BackgroundAudioController } from "./src/main/ets/controller/BackgroundAudioController"
  1 +import { Context, WantAgent, wantAgent } from '@kit.AbilityKit'
  2 +import { avSession as AVSessionManager } from '@kit.AVSessionKit'
  3 +import { backgroundTaskManager } from '@kit.BackgroundTasksKit'
  4 +import { BusinessError } from '@kit.BasicServicesKit'
  5 +import { Logger } from 'wdKit/Index'
  6 +import { PlayerConstants } from '../constants/PlayerConstants'
  7 +import { WDPlayerController } from './WDPlayerController'
  8 +
  9 +const TAG = "BackgroundAudioController"
  10 +
  11 +export class BackgroundAudioController {
  12 +
  13 + private static bgAudioController: BackgroundAudioController
  14 + private constructor() {
  15 + }
  16 + public static sharedController() {
  17 + if (!BackgroundAudioController.bgAudioController) {
  18 + BackgroundAudioController.bgAudioController = new BackgroundAudioController()
  19 + }
  20 + return BackgroundAudioController.bgAudioController
  21 + }
  22 +
  23 + public gotContextFunc?: () => Context
  24 + public avplayerController?: WDPlayerController
  25 + private lastSession?: AVSessionManager.AVSession
  26 +
  27 + // 开始创建并激活媒体会话
  28 + // 创建session
  29 + async createSession() {
  30 + if (!this.gotContextFunc) { return }
  31 + this.destorySession()
  32 + let type: AVSessionManager.AVSessionType = 'audio';
  33 + let session = await AVSessionManager.createAVSession(this.gotContextFunc(),'SESSION_NAME', type);
  34 +
  35 + // 激活接口要在元数据、控制命令注册完成之后再执行
  36 + await session.activate();
  37 + Logger.debug(TAG, `session create done : sessionId : ${session.sessionId}`);
  38 +
  39 + this.lastSession = session
  40 + }
  41 +
  42 + destorySession() {
  43 + if (this.lastSession) {
  44 + this.lastSession.deactivate();
  45 + this.lastSession.destroy();
  46 + }
  47 + }
  48 +
  49 + //设置播放元数据
  50 + setSessionMetaData(assetId: string, title: string, mediaImage: string, artist?: string) {
  51 + let metadata: AVSessionManager.AVMetadata = {
  52 + assetId: assetId,
  53 + title: title,
  54 + mediaImage: mediaImage,
  55 + artist: artist ?? "",
  56 + // duration: "",
  57 + };
  58 + this.lastSession?.setAVMetadata(metadata).then(() => {
  59 + Logger.debug(TAG, `SetAVMetadata successfully`);
  60 + }).catch((err: BusinessError) => {
  61 + Logger.error(TAG, `Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`);
  62 + });
  63 + }
  64 +
  65 + //设置播放状态
  66 + setSessionPlayStatus(playStatus: number) {
  67 + let pauseed = playStatus == PlayerConstants.STATUS_PAUSE
  68 + let playbackState: AVSessionManager.AVPlaybackState = {
  69 + state:pauseed ? AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE : AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY,
  70 + isFavorite:false
  71 + };
  72 + this.lastSession?.setAVPlaybackState(playbackState, (err: BusinessError) => {
  73 + if (err) {
  74 + Logger.error(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`);
  75 + } else {
  76 + Logger.debug(TAG, `SetAVPlaybackState 设置播放状态成功` + playStatus);
  77 + }
  78 + });
  79 + }
  80 +
  81 + //设置进度,单位秒
  82 + setSessionPlayProgress(progressDuration: number, totalDuration: number) {
  83 + Logger.debug(TAG, `set progress: ` + progressDuration + " duration: " + totalDuration);
  84 + if (totalDuration <= 0) {
  85 + return
  86 + }
  87 + // 设置状态: 播放状态,进度位置,播放倍速,缓存的时间
  88 + let playbackState: AVSessionManager.AVPlaybackState = {
  89 + state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY, // 播放状态
  90 + position: {
  91 + elapsedTime: progressDuration * 1000, // 已经播放的位置,以ms为单位
  92 + updateTime: new Date().getTime(), // 应用更新当前位置时的时间戳,以ms为单位
  93 + },
  94 + duration: totalDuration * 1000,
  95 + // speed: 1.0, // 可选,默认是1.0,播放的倍速,按照应用内支持的speed进行设置,系统不做校验
  96 + // bufferedTime: 14000, // 可选,资源缓存的时间,以ms为单位
  97 + };
  98 + this.lastSession?.setAVPlaybackState(playbackState, (err) => {
  99 + if (err) {
  100 + Logger.error(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`);
  101 + } else {
  102 + // Logger.debug(TAG, `SetAVPlaybackState successfully`);
  103 + }
  104 + });
  105 + }
  106 +
  107 + // 置灰或禁用不支持的按钮
  108 + stopUseFeatures() {
  109 + // 取消指定session下的相关监听
  110 + this.lastSession?.off('playFromAssetId');
  111 + this.lastSession?.off('setSpeed');
  112 + this.lastSession?.off('setLoopMode');
  113 + this.lastSession?.off('toggleFavorite');
  114 + this.lastSession?.off('skipToQueueItem');
  115 + this.lastSession?.off('handleKeyEvent');
  116 + this.lastSession?.off('commonCommand');
  117 + this.lastSession?.off('rewind');
  118 + this.lastSession?.off('fastForward');
  119 + }
  120 +
  121 + listenPlayEvents() {
  122 + this.lastSession?.on('play', () => {
  123 + Logger.debug(TAG, `on play `);
  124 + });
  125 + this.lastSession?.on('pause', () => {
  126 + Logger.debug(TAG, `on pause `);
  127 + });
  128 + this.lastSession?.on('stop', () => {
  129 + Logger.debug(TAG, `on stop `);
  130 + });
  131 + this.lastSession?.on('playNext', () => {
  132 + Logger.debug(TAG, `on playNext `);
  133 + });
  134 + this.lastSession?.on('playPrevious', () => {
  135 + Logger.debug(TAG, `on playPrevious `);
  136 + });
  137 +
  138 + this.lastSession?.on('seek', (position: number) => {
  139 + Logger.debug(TAG, `on seek , the time is ${JSON.stringify(position)}`);
  140 +
  141 + // 由于应用内seek可能会触发较长的缓冲等待,可以先把状态设置为 Buffering
  142 + let playbackState: AVSessionManager.AVPlaybackState = {
  143 + state: AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING, // 缓冲状态
  144 + };
  145 + this.lastSession?.setAVPlaybackState(playbackState, (err) => {
  146 + if (err) {
  147 + Logger.debug(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`);
  148 + } else {
  149 + Logger.debug(TAG, `SetAVPlaybackState seek buffering`);
  150 + }
  151 + });
  152 +
  153 + // 应用响应seek命令,使用应用内播放器完成seek实现
  154 +
  155 +
  156 + });
  157 + }
  158 +
  159 + // 开启后台长时任务
  160 + startContinuousTask() {
  161 + let params: Record<string, string> = {
  162 + "title": "开始后台任务",
  163 + "content": "内容?",
  164 + // "pushLink": pushLink,
  165 + // "taskid": message.taskId,
  166 + // "messageId": message.messageId,
  167 + // "gtTransmitMsgLocalNotify": "1",
  168 + }
  169 +
  170 + let wantAgentInfo: wantAgent.WantAgentInfo = {
  171 + // 点击通知后,将要执行的动作列表
  172 + // 添加需要被拉起应用的bundleName和abilityName
  173 + wants: [
  174 + {
  175 + deviceId: '',
  176 + bundleName: "com.peopledailychina.hosactivity",
  177 + abilityName: "EntryAbility",
  178 + action: 'com.test.pushaction',
  179 + entities: [],
  180 + parameters:params,
  181 + }
  182 + ],
  183 + // 指定点击通知栏消息后的动作是拉起ability
  184 + actionType: wantAgent.OperationType.START_ABILITY,
  185 + // 使用者自定义的一个私有值
  186 + requestCode: 0,
  187 + // 点击通知后,动作执行属性
  188 + wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
  189 + };
  190 +
  191 + // 通过wantAgent模块下getWantAgent方法获取WantAgent对象
  192 + wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => {
  193 + if (!this.gotContextFunc) { return }
  194 + backgroundTaskManager.startBackgroundRunning(this.gotContextFunc(),
  195 + backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,
  196 + wantAgentObj).then(() => {
  197 + Logger.debug(TAG, `Succeeded in operationing startBackgroundRunning.`);
  198 + }).catch((err: BusinessError) => {
  199 + Logger.error(TAG, `Failed to operation startBackgroundRunning. Code is ${err.code}, message is ${err.message}`);
  200 + });
  201 + });
  202 + }
  203 +
  204 + stopContinuousTask() {
  205 + if (!this.gotContextFunc) { return }
  206 + backgroundTaskManager.stopBackgroundRunning(this.gotContextFunc()).then(() => {
  207 + Logger.debug(TAG, `Succeeded in operationing stopBackgroundRunning.`);
  208 + }).catch((err: BusinessError) => {
  209 + Logger.error(TAG, `Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`);
  210 + });
  211 + }
  212 +
  213 +}
1 import media from '@ohos.multimedia.media'; 1 import media from '@ohos.multimedia.media';
2 import prompt from '@ohos.promptAction'; 2 import prompt from '@ohos.promptAction';
3 -import { Logger } from '../utils/Logger';  
4 import { PlayerConstants, AVPlayerStatus, Events } from '../constants/PlayerConstants'; 3 import { PlayerConstants, AVPlayerStatus, Events } from '../constants/PlayerConstants';
5 import { BusinessError } from '@ohos.base'; 4 import { BusinessError } from '@ohos.base';
6 import { TrackingPlay } from 'wdTracking/Index'; 5 import { TrackingPlay } from 'wdTracking/Index';
7 import { ParamType } from 'wdTracking/Index'; 6 import { ParamType } from 'wdTracking/Index';
8 -import { DateTimeUtils } from 'wdKit/Index'; 7 +import { DateTimeUtils, Logger } from 'wdKit/Index';
  8 +import { BackgroundAudioController } from './BackgroundAudioController';
9 9
10 interface obj { 10 interface obj {
11 loop: boolean 11 loop: boolean
12 } 12 }
13 13
  14 +const TAG = "WDPlayerController"
  15 +
14 @Observed 16 @Observed
15 export class WDPlayerController { 17 export class WDPlayerController {
16 private initPromise: Promise<void>; 18 private initPromise: Promise<void>;
@@ -41,7 +43,7 @@ export class WDPlayerController { @@ -41,7 +43,7 @@ export class WDPlayerController {
41 public xComponentController?: XComponentController 43 public xComponentController?: XComponentController
42 public videoWidth: number = 0 44 public videoWidth: number = 0
43 public videoHeight: number = 0 45 public videoHeight: number = 0
44 - 46 + public keepOnBackground = false
45 47
46 48
47 49
@@ -61,17 +63,17 @@ export class WDPlayerController { @@ -61,17 +63,17 @@ export class WDPlayerController {
61 Logger.error("开始创建") 63 Logger.error("开始创建")
62 media.createAVPlayer().then((avPlayer) => { 64 media.createAVPlayer().then((avPlayer) => {
63 if (avPlayer) { 65 if (avPlayer) {
64 - Logger.error("创建完成1") 66 + Logger.error(TAG, "创建完成1")
65 this.avPlayer = avPlayer; 67 this.avPlayer = avPlayer;
66 this.bindState(); 68 this.bindState();
67 resolve(); 69 resolve();
68 } else { 70 } else {
69 - Logger.error("创建完成0")  
70 - Logger.error('[PlayVideoModel] createAvPlayer fail!'); 71 + Logger.error(TAG, "创建完成0")
  72 + Logger.error(TAG, '[PlayVideoModel] createAvPlayer fail!');
71 reject(); 73 reject();
72 } 74 }
73 }).catch((error: BusinessError) => { 75 }).catch((error: BusinessError) => {
74 - console.error(`AVPlayer catchCallback, error message:${error.message}`); 76 + Logger.error(TAG, `AVPlayer catchCallback, error message:${error.message}`);
75 }); 77 });
76 ; 78 ;
77 }); 79 });
@@ -143,10 +145,10 @@ export class WDPlayerController { @@ -143,10 +145,10 @@ export class WDPlayerController {
143 this.avPlayer.release(); 145 this.avPlayer.release();
144 this.status = PlayerConstants.STATUS_STOP; 146 this.status = PlayerConstants.STATUS_STOP;
145 this.watchStatus(); 147 this.watchStatus();
146 - Logger.info('[PlayVideoModel] state released called') 148 + Logger.info(TAG, '[PlayVideoModel] state released called')
147 break; 149 break;
148 default: 150 default:
149 - Logger.info('[PlayVideoModel] unKnown state: ' + state); 151 + Logger.info(TAG, '[PlayVideoModel] unKnown state: ' + state);
150 break; 152 break;
151 } 153 }
152 }); 154 });
@@ -155,7 +157,7 @@ export class WDPlayerController { @@ -155,7 +157,7 @@ export class WDPlayerController {
155 }); 157 });
156 this.avPlayer?.on(Events.ERROR, (error) => { 158 this.avPlayer?.on(Events.ERROR, (error) => {
157 this.playError(error.message); 159 this.playError(error.message);
158 - console.log('播放错误',JSON.stringify(error)) 160 + Logger.error(TAG, '播放错误' + JSON.stringify(error))
159 TrackingPlay.videoPlayError(error.message, this.pageName, this.pageName, this.pageParam) 161 TrackingPlay.videoPlayError(error.message, this.pageName, this.pageName, this.pageParam)
160 }) 162 })
161 this.avPlayer?.on('seekDone', (time: number) => { 163 this.avPlayer?.on('seekDone', (time: number) => {
@@ -186,7 +188,7 @@ export class WDPlayerController { @@ -186,7 +188,7 @@ export class WDPlayerController {
186 this.url = url; 188 this.url = url;
187 //加载时长prepareTime 189 //加载时长prepareTime
188 this.creatStartTime = DateTimeUtils.getTimeStamp() 190 this.creatStartTime = DateTimeUtils.getTimeStamp()
189 - console.log('开始创建',JSON.stringify(this.creatStartTime)) 191 + Logger.debug(TAG, '开始创建' + JSON.stringify(this.creatStartTime))
190 this.prepareTime = 0 192 this.prepareTime = 0
191 if(pageName){ 193 if(pageName){
192 this.pageName = pageName 194 this.pageName = pageName
@@ -195,7 +197,7 @@ export class WDPlayerController { @@ -195,7 +197,7 @@ export class WDPlayerController {
195 this.pageParam = pageParam 197 this.pageParam = pageParam
196 } 198 }
197 if (this.avPlayer == null) { 199 if (this.avPlayer == null) {
198 - console.log("等待") 200 + Logger.debug(TAG, "等待")
199 this.initPromise = this.createAVPlayer(); 201 this.initPromise = this.createAVPlayer();
200 await this.initPromise; 202 await this.initPromise;
201 } else { 203 } else {
@@ -209,13 +211,13 @@ export class WDPlayerController { @@ -209,13 +211,13 @@ export class WDPlayerController {
209 if (this.avPlayer == null) { 211 if (this.avPlayer == null) {
210 return 212 return
211 } 213 }
212 - console.log("开始播放", this.url) 214 + Logger.debug(TAG, "开始播放", this.url)
213 this.avPlayer.url = this.url; 215 this.avPlayer.url = this.url;
214 //加载时长prepareTime 216 //加载时长prepareTime
215 this.creatEndTime = DateTimeUtils.getTimeStamp() 217 this.creatEndTime = DateTimeUtils.getTimeStamp()
216 this.prepareTime = 0 218 this.prepareTime = 0
217 this.prepareTime = Math.floor((this.creatEndTime - this.creatStartTime)/1000) 219 this.prepareTime = Math.floor((this.creatEndTime - this.creatStartTime)/1000)
218 - console.log('开始播放2',JSON.stringify(this.prepareTime)) 220 + Logger.debug(TAG, '开始播放2',JSON.stringify(this.prepareTime))
219 } 221 }
220 222
221 async release() { 223 async release() {
@@ -237,6 +239,7 @@ export class WDPlayerController { @@ -237,6 +239,7 @@ export class WDPlayerController {
237 // if (this.avPlayer == null) { 239 // if (this.avPlayer == null) {
238 // return 240 // return
239 // } 241 // }
  242 + Logger.debug(TAG, "start pause")
240 this.avPlayer?.pause(); 243 this.avPlayer?.pause();
241 } 244 }
242 245
@@ -253,7 +256,7 @@ export class WDPlayerController { @@ -253,7 +256,7 @@ export class WDPlayerController {
253 async startRenderFrame(cb: Function) { 256 async startRenderFrame(cb: Function) {
254 this.avPlayer?.on('startRenderFrame', () => { 257 this.avPlayer?.on('startRenderFrame', () => {
255 cb && cb(); 258 cb && cb();
256 - console.info('startRenderFrame success') 259 + Logger.debug(TAG, 'startRenderFrame success')
257 }) 260 })
258 } 261 }
259 262
@@ -299,6 +302,7 @@ export class WDPlayerController { @@ -299,6 +302,7 @@ export class WDPlayerController {
299 // return 302 // return
300 // } 303 // }
301 if (this.status === PlayerConstants.STATUS_START) { 304 if (this.status === PlayerConstants.STATUS_START) {
  305 + Logger.debug(TAG, "start pause 1111")
302 this.avPlayer?.pause(); 306 this.avPlayer?.pause();
303 } else { 307 } else {
304 this.avPlayer?.play(); 308 this.avPlayer?.play();
@@ -349,6 +353,11 @@ export class WDPlayerController { @@ -349,6 +353,11 @@ export class WDPlayerController {
349 this.currentPlayTime=Math.floor(time / 1000); 353 this.currentPlayTime=Math.floor(time / 1000);
350 let nowSeconds = Math.floor(time / 1000); 354 let nowSeconds = Math.floor(time / 1000);
351 let totalSeconds = Math.floor(this.duration / 1000); 355 let totalSeconds = Math.floor(this.duration / 1000);
  356 +
  357 + if (this.keepOnBackground) {
  358 + BackgroundAudioController.sharedController().setSessionPlayProgress(time, this.duration)
  359 + }
  360 +
352 if (this.onTimeUpdate) { 361 if (this.onTimeUpdate) {
353 this.onTimeUpdate(time, this.duration); 362 this.onTimeUpdate(time, this.duration);
354 } 363 }
@@ -397,7 +406,7 @@ export class WDPlayerController { @@ -397,7 +406,7 @@ export class WDPlayerController {
397 if (this.onVolumeUpdate) { 406 if (this.onVolumeUpdate) {
398 this.onVolumeUpdate(this.volume); 407 this.onVolumeUpdate(this.volume);
399 } 408 }
400 - console.log("volume : " + this.volume) 409 + Logger.debug(TAG, "volume : " + this.volume)
401 } 410 }
402 411
403 onBrightActionUpdate(event: GestureEvent) { 412 onBrightActionUpdate(event: GestureEvent) {
@@ -421,22 +430,27 @@ export class WDPlayerController { @@ -421,22 +430,27 @@ export class WDPlayerController {
421 } 430 }
422 431
423 watchStatus() { 432 watchStatus() {
424 - console.log('watchStatus', this.status) 433 +
  434 + if (this.keepOnBackground) {
  435 + BackgroundAudioController.sharedController().setSessionPlayStatus(this.status)
  436 + }
  437 +
  438 + Logger.debug(TAG, 'watchStatus ' + this.status)
425 if(this.status == PlayerConstants.STATUS_START){ 439 if(this.status == PlayerConstants.STATUS_START){
426 - console.log('播放视频')  
427 - console.log('播放视频prepareTime',JSON.stringify(this.prepareTime))  
428 - console.log('播放视频pageName',JSON.stringify(this.pageName))  
429 - console.log('播放视频pageParam',JSON.stringify(this.pageParam)) 440 + Logger.debug(TAG, '播放视频')
  441 + Logger.debug(TAG, '播放视频prepareTime' + JSON.stringify(this.prepareTime))
  442 + Logger.debug(TAG, '播放视频pageName' + JSON.stringify(this.pageName))
  443 + Logger.debug(TAG, '播放视频pageParam' + JSON.stringify(this.pageParam))
430 // 播放埋点 444 // 播放埋点
431 TrackingPlay.videoPositivePlay(Number(this.prepareTime),this.pageName, this.pageName, this.pageParam) 445 TrackingPlay.videoPositivePlay(Number(this.prepareTime),this.pageName, this.pageName, this.pageParam)
432 } 446 }
433 if(this.status == PlayerConstants.STATUS_COMPLETION){ 447 if(this.status == PlayerConstants.STATUS_COMPLETION){
434 let initDuration = Math.floor(Number(this.duration)/1000) 448 let initDuration = Math.floor(Number(this.duration)/1000)
435 - console.log('播放结束')  
436 - console.log('播放结束currentPlayTime',JSON.stringify(this.currentPlayTime))  
437 - console.log('播放结束initDuration',JSON.stringify(initDuration))  
438 - console.log('播放结束pageName',JSON.stringify(this.pageName))  
439 - console.log('播放结束pageParam',JSON.stringify(this.pageParam)) 449 + Logger.debug(TAG, '播放结束')
  450 + Logger.debug(TAG, '播放结束currentPlayTime' + JSON.stringify(this.currentPlayTime))
  451 + Logger.debug(TAG, '播放结束initDuration' + JSON.stringify(initDuration))
  452 + Logger.debug(TAG, '播放结束pageName' + JSON.stringify(this.pageName))
  453 + Logger.debug(TAG, '播放结束pageParam' + JSON.stringify(this.pageParam))
440 // 播放结束埋点 454 // 播放结束埋点
441 TrackingPlay.videoPlayEnd(this.currentPlayTime, initDuration, this.currentPlayTime, this.pageName, this.pageName, this.pageParam) 455 TrackingPlay.videoPlayEnd(this.currentPlayTime, initDuration, this.currentPlayTime, this.pageName, this.pageName, this.pageParam)
442 } 456 }
@@ -88,7 +88,8 @@ struct Index { @@ -88,7 +88,8 @@ struct Index {
88 88
89 onPageHide() { 89 onPageHide() {
90 // this.status = PlayerConstants.STATUS_PAUSE; 90 // this.status = PlayerConstants.STATUS_PAUSE;
91 - this.AudioSuspension.playerController.get()?.pause(); 91 + console.info('onPageHide');
  92 + // this.AudioSuspension.playerController.get()?.pause();
92 } 93 }
93 94
94 build() { 95 build() {
@@ -22,6 +22,7 @@ import { webview } from '@kit.ArkWeb' @@ -22,6 +22,7 @@ import { webview } from '@kit.ArkWeb'
22 import { NewspaperWidgetCommon } from '../dailynewspaperwidget/common/NewspaperWidgetCommon' 22 import { NewspaperWidgetCommon } from '../dailynewspaperwidget/common/NewspaperWidgetCommon'
23 import { LiveRoomManager } from 'wdDetailPlayLive/Index' 23 import { LiveRoomManager } from 'wdDetailPlayLive/Index'
24 import { initGlobalPlayerSettings } from 'wdPlayer/src/main/ets/utils/GlobalSetting' 24 import { initGlobalPlayerSettings } from 'wdPlayer/src/main/ets/utils/GlobalSetting'
  25 +import { BackgroundAudioController } from 'wdPlayer/Index'
25 26
26 const TAG = "[StartupManager]" 27 const TAG = "[StartupManager]"
27 28
@@ -115,6 +116,8 @@ export class StartupManager { @@ -115,6 +116,8 @@ export class StartupManager {
115 this.initAuthLogin() 116 this.initAuthLogin()
116 117
117 this.initLiveChatRoom() 118 this.initLiveChatRoom()
  119 +
  120 + this.initBackgroundAudioTask()
118 Logger.debug(TAG, "App 必要初始化完成") 121 Logger.debug(TAG, "App 必要初始化完成")
119 } 122 }
120 123
@@ -210,6 +213,12 @@ export class StartupManager { @@ -210,6 +213,12 @@ export class StartupManager {
210 } 213 }
211 } 214 }
212 215
  216 + private initBackgroundAudioTask() {
  217 + BackgroundAudioController.sharedController().gotContextFunc = () => {
  218 + return StartupManager.sharedInstance().context!
  219 + }
  220 + }
  221 +
213 private initThirdPlatformSDK() { 222 private initThirdPlatformSDK() {
214 223
215 } 224 }
@@ -42,7 +42,8 @@ @@ -42,7 +42,8 @@
42 } 42 }
43 ] 43 ]
44 } 44 }
45 - ] 45 + ],
  46 + "backgroundModes": ["audioPlayback"]
46 } 47 }
47 ], 48 ],
48 "metadata": [ 49 "metadata": [
@@ -103,6 +104,16 @@ @@ -103,6 +104,16 @@
103 } 104 }
104 }, 105 },
105 { 106 {
  107 + "name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
  108 + "reason": "$string:permission_background_audio",
  109 + "usedScene": {
  110 + "abilities": [
  111 + "FormAbility"
  112 + ],
  113 + "when": "always"
  114 + }
  115 + },
  116 + {
106 "name": "ohos.permission.INTERNET" 117 "name": "ohos.permission.INTERNET"
107 }, 118 },
108 ], 119 ],
@@ -29,6 +29,10 @@ @@ -29,6 +29,10 @@
29 "value": "开启之后即可用于收录声音进行拍摄视频、语音搜索、语音评论功能," 29 "value": "开启之后即可用于收录声音进行拍摄视频、语音搜索、语音评论功能,"
30 }, 30 },
31 { 31 {
  32 + "name": "permission_background_audio",
  33 + "value": "开启之后即可用于后台音频播放"
  34 + },
  35 + {
32 "name": "dialog_text_title", 36 "name": "dialog_text_title",
33 "value": "个人隐私保护指引" 37 "value": "个人隐私保护指引"
34 }, 38 },