王士厅
@@ -101,8 +101,23 @@ export class AppInnerLink { @@ -101,8 +101,23 @@ export class AppInnerLink {
101 return 101 return
102 } 102 }
103 103
104 - if (params.type == "topic") { 104 + if (params.type == "topic" && params.subType == "h5") {
105 105
  106 + let taskAction: Action = {
  107 + type: 'JUMP_INNER_NEW_PAGE',
  108 + params: {
  109 + contentID: params.pageId,
  110 + url: params.url,
  111 + pageID: 'SPACIAL_TOPIC_PAGE',
  112 + backVisibility: true,
  113 + extra: {
  114 + relType: params.relType,
  115 + relId: params.relId,
  116 + pageId: params.pageId
  117 + } as ExtraDTO,
  118 + } as Params,
  119 + };
  120 + WDRouterRule.jumpWithAction(taskAction)
106 } 121 }
107 122
108 if (params.type == "channel") { 123 if (params.type == "channel") {
@@ -97,13 +97,13 @@ export struct SpacialTopicPageComponent { @@ -97,13 +97,13 @@ export struct SpacialTopicPageComponent {
97 this.contentDetailData.shareInfo = this.shareInfo 97 this.contentDetailData.shareInfo = this.shareInfo
98 98
99 console.log('contentDetailData111', JSON.stringify(this.contentDetailData)) 99 console.log('contentDetailData111', JSON.stringify(this.contentDetailData))
100 - if(this.topicInfo.shareOpen === 1){  
101 - if (!this.operationButtonList.includes('share')) {  
102 - this.operationButtonList.push('share');  
103 - }  
104 - } else {  
105 - this.operationButtonList = this.operationButtonList.filter(e =>e !== 'share')  
106 - } 100 + // if(this.topicInfo.shareOpen === 1){
  101 + // if (!this.operationButtonList.includes('share')) {
  102 + // this.operationButtonList.push('share');
  103 + // }
  104 + // } else {
  105 + // this.operationButtonList = this.operationButtonList.filter(e =>e !== 'share')
  106 + // }
107 107
108 // 转换评论数据 108 // 转换评论数据
109 this.publishCommentModel.targetId = String(this.contentDetailData?.newsId || '') 109 this.publishCommentModel.targetId = String(this.contentDetailData?.newsId || '')
@@ -14,18 +14,8 @@ import { TrackConstants } from 'wdTracking/Index'; @@ -14,18 +14,8 @@ import { TrackConstants } from 'wdTracking/Index';
14 14
15 import { SPHelper } from 'wdKit/Index'; 15 import { SPHelper } from 'wdKit/Index';
16 import { SpConstants } from 'wdConstant/Index'; 16 import { SpConstants } from 'wdConstant/Index';
  17 +import { photoPickerUtils} from '../../utils/PhotoPickerUtils';
17 18
18 -import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';  
19 -import { picker } from '@kit.CoreFileKit';  
20 -import { camera, cameraPicker } from '@kit.CameraKit';  
21 -import { BusinessError } from '@kit.BasicServicesKit';  
22 -  
23 -let mContext = getContext(this) as common.Context;  
24 -  
25 -const PERMISSIONS: Array<Permissions> = [  
26 - 'ohos.permission.READ_IMAGEVIDEO',  
27 - 'ohos.permission.WRITE_IMAGEVIDEO'  
28 -];  
29 @Entry 19 @Entry
30 @Component 20 @Component
31 struct EditUserInfoPage { 21 struct EditUserInfoPage {
@@ -93,11 +83,7 @@ struct EditUserInfoPage { @@ -93,11 +83,7 @@ struct EditUserInfoPage {
93 builder: CustomDialogUI({ 83 builder: CustomDialogUI({
94 itemData:['相册','拍照'], 84 itemData:['相册','拍照'],
95 confirmCallback:(index)=>{ 85 confirmCallback:(index)=>{
96 - if (index === 0) {  
97 - this.getPhotoPicker()  
98 - }else {  
99 - this.getCamera()  
100 - } 86 + this.pickerSelect(index)
101 } 87 }
102 }), 88 }),
103 alignment: DialogAlignment.Bottom, 89 alignment: DialogAlignment.Bottom,
@@ -105,42 +91,23 @@ struct EditUserInfoPage { @@ -105,42 +91,23 @@ struct EditUserInfoPage {
105 closeAnimation:{duration:0} 91 closeAnimation:{duration:0}
106 }) 92 })
107 93
108 - async getPhotoPicker(){  
109 - ///权限查询  
110 - const context = getContext(this) as common.UIAbilityContext;  
111 - const atManager = abilityAccessCtrl.createAtManager();  
112 - await atManager.requestPermissionsFromUser(context, PERMISSIONS);  
113 -  
114 - let PhotoSelectOptions = new picker.PhotoSelectOptions();  
115 - PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型  
116 - PhotoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目  
117 - let photoPicker = new picker.PhotoViewPicker(); // 使用图库选择器对象前,需要先创建PhotoViewPicker实例  
118 - photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {  
119 - if (PhotoSelectResult !== null && PhotoSelectResult !==  
120 - undefined) {  
121 - // 接口采用callback异步返回形式,返回PhotoSelectResult对象,故进行下一步操作前要先判断是否已经成功返回PhotoSelectResult对象了  
122 - this.headerImg = PhotoSelectResult['photoUris'][0] 94 + pickerSelect(index:number){
  95 + if (index === 0) {
  96 + photoPickerUtils.getPhotoPicker().then(value => {
  97 + if (value.length > 0) {
  98 + this.headerImg = value
123 } 99 }
124 }) 100 })
  101 + }else {
  102 + photoPickerUtils.getCamera().then(value => {
  103 + if (value.length > 0) {
  104 + this.headerImg = value
125 } 105 }
126 -  
127 - async getCamera(){  
128 - try {  
129 - let pickerProfile: cameraPicker.PickerProfile = {  
130 - cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK  
131 - };  
132 - let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(mContext,  
133 - [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO], pickerProfile);  
134 - if (pickerResult['resultCode'] === 0) {  
135 - this.headerImg = pickerResult['resultUri']  
136 - }  
137 - console.log("the pick pickerResult is:" + JSON.stringify(pickerResult));  
138 - } catch (error) {  
139 - let err = error as BusinessError;  
140 - console.error(`the pick call failed. error code: ${err.code}`); 106 + })
141 } 107 }
142 } 108 }
143 109
  110 +
144 aboutToAppear() { 111 aboutToAppear() {
145 let userType = SPHelper.default.getSync(SpConstants.USER_Type,"") as string 112 let userType = SPHelper.default.getSync(SpConstants.USER_Type,"") as string
146 if (userType && userType.length > 0) { 113 if (userType && userType.length > 0) {
@@ -96,6 +96,7 @@ export struct OperRowListView { @@ -96,6 +96,7 @@ export struct OperRowListView {
96 @State likesStyle: number | string = 1 // 赞样式 1红心(点赞) 2大拇指(祈福) 3蜡烛(默哀) 4置空 96 @State likesStyle: number | string = 1 // 赞样式 1红心(点赞) 2大拇指(祈福) 3蜡烛(默哀) 4置空
97 @State openLikes: boolean = false // 是否可以点赞 1:可以 0:不可以 97 @State openLikes: boolean = false // 是否可以点赞 1:可以 0:不可以
98 @Prop topicInfo?: TopicInfo = {} as TopicInfo 98 @Prop topicInfo?: TopicInfo = {} as TopicInfo
  99 + private shareOpen = 0;
99 100
100 async aboutToAppear() { 101 async aboutToAppear() {
101 console.info(TAG, 'this.needLike', this.needLike) 102 console.info(TAG, 'this.needLike', this.needLike)
@@ -137,6 +138,7 @@ export struct OperRowListView { @@ -137,6 +138,7 @@ export struct OperRowListView {
137 if (!this.contentDetailData) { 138 if (!this.contentDetailData) {
138 return 139 return
139 } 140 }
  141 + this.shareOpen = this.contentDetailData.shareInfo.shareOpen;
140 const user_id = await SPHelper.default.get(SpConstants.USER_ID, '') 142 const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
141 if (user_id) { 143 if (user_id) {
142 this.getInteractDataStatus() 144 this.getInteractDataStatus()
@@ -393,10 +395,11 @@ export struct OperRowListView { @@ -393,10 +395,11 @@ export struct OperRowListView {
393 */ 395 */
394 @Builder 396 @Builder
395 builderShare() { 397 builderShare() {
396 - if(this.contentDetailData?.shareInfo?.shareOpen == 1) { 398 +
  399 +
397 Column() { 400 Column() {
398 - Image(this.styleType == 1 ? $r('app.media.iv_live_comment_share') :  
399 - $r('app.media.iv_live_comment_share_white')) 401 + Image(this.styleType == 1 ? (this.shareOpen == 1?$r('app.media.iv_live_comment_share'):$r('app.media.more_icon_black')) :
  402 + (this.shareOpen == 1?$r('app.media.iv_live_comment_share_white'):$r('app.media.more_icon_white')))
400 .width(24) 403 .width(24)
401 .height(24) 404 .height(24)
402 .aspectRatio(1) 405 .aspectRatio(1)
@@ -411,7 +414,9 @@ export struct OperRowListView { @@ -411,7 +414,9 @@ export struct OperRowListView {
411 .borderRadius(18) 414 .borderRadius(18)
412 .backgroundColor(this.pageComponentType === 2 ? '#4D000000' : Color.Transparent) 415 .backgroundColor(this.pageComponentType === 2 ? '#4D000000' : Color.Transparent)
413 } 416 }
414 - } 417 + // if(this.contentDetailData?.shareInfo?.shareOpen == 1) {
  418 + //
  419 + // }
415 420
416 handleStyle() { 421 handleStyle() {
417 if (this.styleType == 1) { 422 if (this.styleType == 1) {
@@ -440,7 +445,7 @@ export struct OperRowListView { @@ -440,7 +445,7 @@ export struct OperRowListView {
440 appCustomTargetRelType: this.topicInfo?.relType, 445 appCustomTargetRelType: this.topicInfo?.relType,
441 appCustomShowReport: false, 446 appCustomShowReport: false,
442 appCustomShowLike: -1, 447 appCustomShowLike: -1,
443 - shareOpen: 1, 448 + shareOpen: this.shareOpen,
444 sharePosterOpen: this.topicInfo?.posterFlag, 449 sharePosterOpen: this.topicInfo?.posterFlag,
445 appCustomShowPoster: this.topicInfo?.posterFlag && this.topicInfo?.posterFlag > 0 ? 1 : -1, 450 appCustomShowPoster: this.topicInfo?.posterFlag && this.topicInfo?.posterFlag > 0 ? 1 : -1,
446 } 451 }
  1 +import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
  2 +import { picker } from '@kit.CoreFileKit';
  3 +import { camera, cameraPicker } from '@kit.CameraKit';
  4 +import { BusinessError } from '@kit.BasicServicesKit';
  5 +
  6 +let mContext = getContext(this) as common.Context;
  7 +
  8 +const PERMISSIONS: Array<Permissions> = [
  9 + 'ohos.permission.READ_IMAGEVIDEO',
  10 +];
  11 +
  12 +export class PhotoPickerUtils {
  13 +
  14 + async getPhotoPicker(){
  15 + this.pickerPermissions()
  16 +
  17 + let PhotoSelectOptions = new picker.PhotoSelectOptions();
  18 + PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型
  19 + PhotoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
  20 + let photoPicker = new picker.PhotoViewPicker(); // 使用图库选择器对象前,需要先创建PhotoViewPicker实例
  21 +
  22 + return new Promise<string>((success, fail) => {
  23 + photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {
  24 + if (PhotoSelectResult !== null && PhotoSelectResult !==
  25 + undefined) {
  26 + // 接口采用callback异步返回形式,返回PhotoSelectResult对象,故进行下一步操作前要先判断是否已经成功返回PhotoSelectResult对象了
  27 + success(PhotoSelectResult['photoUris'][0])
  28 + }
  29 + })
  30 + })
  31 + }
  32 +
  33 + async getCamera(){
  34 + this.pickerPermissions()
  35 +
  36 + let pickerProfile: cameraPicker.PickerProfile = {
  37 + cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
  38 + };
  39 + let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(mContext,
  40 + [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO], pickerProfile);
  41 +
  42 + return new Promise<string>((success, fail) => {
  43 + if (pickerResult['resultCode'] === 0) {
  44 + success(pickerResult['resultUri'])
  45 + }
  46 + })
  47 + }
  48 +
  49 + async pickerPermissions(){
  50 + ///权限查询
  51 + const context = getContext(this) as common.UIAbilityContext;
  52 + const atManager = abilityAccessCtrl.createAtManager();
  53 + await atManager.requestPermissionsFromUser(context, PERMISSIONS);
  54 + }
  55 +
  56 +}
  57 +
  58 +export const photoPickerUtils: PhotoPickerUtils = new PhotoPickerUtils();
@@ -45,11 +45,10 @@ export class AudioSuspensionModel { @@ -45,11 +45,10 @@ export class AudioSuspensionModel {
45 this.playerController.get().keepOnBackground = true 45 this.playerController.get().keepOnBackground = true
46 BackgroundAudioController.sharedController().avplayerController = this.playerController.get() 46 BackgroundAudioController.sharedController().avplayerController = this.playerController.get()
47 await BackgroundAudioController.sharedController().createSession() 47 await BackgroundAudioController.sharedController().createSession()
48 - BackgroundAudioController.sharedController().startContinuousTask()  
49 - let id = $r('app.media.newspaper_default').id  
50 - BackgroundAudioController.sharedController().setSessionMetaData(srcContentId ?? "", srcTitle, 'file://', srcSource ?? "")  
51 - BackgroundAudioController.sharedController().stopUseFeatures() 48 + // BackgroundAudioController.sharedController().startContinuousTask()
52 BackgroundAudioController.sharedController().listenPlayEvents() 49 BackgroundAudioController.sharedController().listenPlayEvents()
  50 + await BackgroundAudioController.sharedController().setSessionMetaData(srcContentId ?? "", srcTitle, $r("app.media.system_audio_icon_bk_center"), srcSource ?? "")
  51 + BackgroundAudioController.sharedController().stopUseFeatures()
53 52
54 if (this.url === url) { 53 if (this.url === url) {
55 this.isMinimize = AppStorage.link<boolean>('isMinimize') 54 this.isMinimize = AppStorage.link<boolean>('isMinimize')
@@ -2,10 +2,11 @@ import { Context, WantAgent, wantAgent } from '@kit.AbilityKit' @@ -2,10 +2,11 @@ import { Context, WantAgent, wantAgent } from '@kit.AbilityKit'
2 import { avSession as AVSessionManager } from '@kit.AVSessionKit' 2 import { avSession as AVSessionManager } from '@kit.AVSessionKit'
3 import { backgroundTaskManager } from '@kit.BackgroundTasksKit' 3 import { backgroundTaskManager } from '@kit.BackgroundTasksKit'
4 import { BusinessError } from '@kit.BasicServicesKit' 4 import { BusinessError } from '@kit.BasicServicesKit'
5 -import { Logger } from 'wdKit/Index'  
6 -import { PlayerConstants } from '../constants/PlayerConstants' 5 +import { DateTimeUtils, EmitterEventId, EmitterUtils, Logger } from 'wdKit/Index'
  6 +import { Events, PlayerConstants } from '../constants/PlayerConstants'
7 import { WDPlayerController } from './WDPlayerController' 7 import { WDPlayerController } from './WDPlayerController'
8 import { image } from '@kit.ImageKit' 8 import { image } from '@kit.ImageKit'
  9 +import { JSON } from '@kit.ArkTS'
9 10
10 const TAG = "BackgroundAudioController" 11 const TAG = "BackgroundAudioController"
11 12
@@ -13,6 +14,9 @@ export class BackgroundAudioController { @@ -13,6 +14,9 @@ export class BackgroundAudioController {
13 14
14 private static bgAudioController: BackgroundAudioController 15 private static bgAudioController: BackgroundAudioController
15 private constructor() { 16 private constructor() {
  17 + EmitterUtils.receiveEvent(EmitterEventId.APP_ENTER_BACKGROUD, () => {
  18 + this.startContinuousTask()
  19 + })
16 } 20 }
17 public static sharedController() { 21 public static sharedController() {
18 if (!BackgroundAudioController.bgAudioController) { 22 if (!BackgroundAudioController.bgAudioController) {
@@ -24,9 +28,17 @@ export class BackgroundAudioController { @@ -24,9 +28,17 @@ export class BackgroundAudioController {
24 public gotContextFunc?: () => Context 28 public gotContextFunc?: () => Context
25 public avplayerController?: WDPlayerController 29 public avplayerController?: WDPlayerController
26 private lastSession?: AVSessionManager.AVSession 30 private lastSession?: AVSessionManager.AVSession
  31 +
27 private applyedLongTaskPlay: boolean = false 32 private applyedLongTaskPlay: boolean = false
  33 +
28 private lastProgress: number = 0.0 34 private lastProgress: number = 0.0
29 private hasSetupProgress: boolean = false 35 private hasSetupProgress: boolean = false
  36 + private playing: boolean = false
  37 + private lastItemAssetId?: string
  38 + private lastItemTitle?: string
  39 + private lastItemMediaImage?: Resource
  40 + private lastItemArtist?: string
  41 + private lastItemTotalDuration: number = 0
30 42
31 // 开始创建并激活媒体会话 43 // 开始创建并激活媒体会话
32 // 创建session 44 // 创建session
@@ -56,23 +68,53 @@ export class BackgroundAudioController { @@ -56,23 +68,53 @@ export class BackgroundAudioController {
56 } 68 }
57 69
58 //设置播放元数据 70 //设置播放元数据
59 - setSessionMetaData(assetId: string, title: string, mediaImage: image.PixelMap | string, artist: string) {  
60 - Logger.debug(TAG, `SetAVMetadata assetId: ${assetId}}, title: ${title}, mediaImage: ${mediaImage}, artist: ${artist}`); 71 + async setSessionMetaData(assetId: string, title: string, mediaImage: Resource, artist: string) {
  72 + this.lastItemAssetId = assetId
  73 + this.lastItemTitle = title
  74 + this.lastItemMediaImage = mediaImage
  75 + this.lastItemArtist = artist
  76 + }
  77 +
  78 + async setSessionMetaDataWithDuration(assetId: string, title: string, mediaImage: Resource, artist: string, duration: number) {
  79 + Logger.debug(TAG, `SetAVMetadata assetId: ${assetId}}, title: ${title}, mediaImage: ${mediaImage}, artist: ${artist}, duration: ${duration}`);
  80 +
  81 + if (!this.gotContextFunc) { return }
  82 + let pixelMapImage:image.PixelMap | null = null
  83 + try {
  84 + const data:Uint8Array = await this.gotContextFunc().resourceManager.getMediaContent(mediaImage)
  85 + pixelMapImage = await image.createPixelMap(data.buffer as ArrayBuffer, {
  86 + editable: false,
  87 + alphaType: image.AlphaType.UNKNOWN,
  88 + srcPixelFormat: image.PixelMapFormat.RGB_888,
  89 + size: { width:300, height:300 }
  90 + })
  91 + } catch (e) {
  92 + Logger.error(TAG, `SetAVMetadata ` + JSON.stringify(e));
  93 + } finally {
  94 + // Logger.debug(TAG, `SetAVMetadata ` + JSON.stringify(pixelMapImage));
61 let metadata: AVSessionManager.AVMetadata = { 95 let metadata: AVSessionManager.AVMetadata = {
62 assetId: assetId.length > 0 ? assetId : "fake-asset-id", 96 assetId: assetId.length > 0 ? assetId : "fake-asset-id",
63 title: title.length > 0 ? title : " ", 97 title: title.length > 0 ? title : " ",
64 - mediaImage: mediaImage, 98 + mediaImage: pixelMapImage ?? ("file://" + mediaImage.id),
65 artist: artist.length > 0 ? artist : "人日日报", 99 artist: artist.length > 0 ? artist : "人日日报",
  100 + duration: duration
66 }; 101 };
67 - this.lastSession?.setAVMetadata(metadata).then(() => { 102 +
  103 + try {
  104 + await this.lastSession?.setAVMetadata(metadata)
68 Logger.debug(TAG, `SetAVMetadata successfully`); 105 Logger.debug(TAG, `SetAVMetadata successfully`);
69 - }).catch((err: BusinessError) => { 106 + } catch (err) {
70 Logger.error(TAG, `Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 107 Logger.error(TAG, `Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`);
71 - }); 108 + } finally {
  109 + pixelMapImage?.release()
  110 + }
  111 + }
  112 +
72 } 113 }
73 114
74 //设置播放状态 115 //设置播放状态
75 setSessionPlayStatus(playStatus: number) { 116 setSessionPlayStatus(playStatus: number) {
  117 + let needUpdateProgress = false
76 let playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY 118 let playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY
77 switch (playStatus){ 119 switch (playStatus){
78 case PlayerConstants.STATUS_PAUSE: { 120 case PlayerConstants.STATUS_PAUSE: {
@@ -80,6 +122,7 @@ export class BackgroundAudioController { @@ -80,6 +122,7 @@ export class BackgroundAudioController {
80 } break 122 } break
81 case PlayerConstants.STATUS_START: { 123 case PlayerConstants.STATUS_START: {
82 playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY 124 playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY
  125 + needUpdateProgress = true
83 } break 126 } break
84 case PlayerConstants.STATUS_STOP: { 127 case PlayerConstants.STATUS_STOP: {
85 playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_STOP 128 playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_STOP
@@ -103,13 +146,15 @@ export class BackgroundAudioController { @@ -103,13 +146,15 @@ export class BackgroundAudioController {
103 Logger.error(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 146 Logger.error(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`);
104 } else { 147 } else {
105 Logger.debug(TAG, `SetAVPlaybackState 设置播放状态成功 ` + playStatus); 148 Logger.debug(TAG, `SetAVPlaybackState 设置播放状态成功 ` + playStatus);
  149 + if (needUpdateProgress) {
  150 + this.hasSetupProgress = false
  151 + }
106 } 152 }
107 }); 153 });
108 } 154 }
109 155
110 - //设置进度,单位秒  
111 - setSessionPlayProgress(progressDuration: number, totalDuration: number) {  
112 - // Logger.debug(TAG, `set progress: ` + progressDuration + " duration: " + totalDuration); 156 + //设置进度,单位ms
  157 + async setSessionPlayProgress(progressDuration: number, totalDuration: number) {
113 if (totalDuration <= 0) { 158 if (totalDuration <= 0) {
114 return 159 return
115 } 160 }
@@ -117,25 +162,38 @@ export class BackgroundAudioController { @@ -117,25 +162,38 @@ export class BackgroundAudioController {
117 if (Math.abs(newProgress - this.lastProgress) < 0.01) { 162 if (Math.abs(newProgress - this.lastProgress) < 0.01) {
118 return 163 return
119 } 164 }
  165 + // Logger.debug(TAG, `set progress: ` + progressDuration + " duration: " + totalDuration);
120 this.lastProgress = newProgress 166 this.lastProgress = newProgress
121 167
  168 + if (this.lastItemAssetId) {
  169 + this.lastItemTotalDuration = totalDuration
  170 + await this.setSessionMetaDataWithDuration(
  171 + this.lastItemAssetId ?? "",
  172 + this.lastItemTitle ?? "",
  173 + this.lastItemMediaImage!,
  174 + this.lastItemArtist ?? "",
  175 + totalDuration
  176 + )
  177 + this.lastItemAssetId = undefined
  178 + }
  179 +
122 if (this.hasSetupProgress) { 180 if (this.hasSetupProgress) {
123 return 181 return
124 } 182 }
125 this.hasSetupProgress = true 183 this.hasSetupProgress = true
126 -  
127 - Logger.debug(TAG, `set progress: ` + progressDuration + " duration: " + totalDuration); 184 + Logger.debug(TAG, `set progress: ` + DateTimeUtils.secondToTime(progressDuration / 1000)
  185 + + " duration: " + DateTimeUtils.secondToTime(totalDuration / 1000));
128 186
129 // 设置状态: 播放状态,进度位置,播放倍速,缓存的时间 187 // 设置状态: 播放状态,进度位置,播放倍速,缓存的时间
130 let playbackState: AVSessionManager.AVPlaybackState = { 188 let playbackState: AVSessionManager.AVPlaybackState = {
131 state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY, // 播放状态 189 state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY, // 播放状态
132 position: { 190 position: {
133 - elapsedTime: progressDuration * 1000, // 已经播放的位置,以ms为单位 191 + elapsedTime: progressDuration, // 已经播放的位置,以ms为单位
134 updateTime: new Date().getTime(), // 应用更新当前位置时的时间戳,以ms为单位 192 updateTime: new Date().getTime(), // 应用更新当前位置时的时间戳,以ms为单位
135 }, 193 },
136 - duration: totalDuration * 1000,  
137 - speed: 1.0, // 可选,默认是1.0,播放的倍速,按照应用内支持的speed进行设置,系统不做校验  
138 - bufferedTime: totalDuration * 1000, // 可选,资源缓存的时间,以ms为单位 194 + // duration: totalDuration,
  195 + // speed: 1.0, // 可选,默认是1.0,播放的倍速,按照应用内支持的speed进行设置,系统不做校验
  196 + // bufferedTime: totalDuration, // 可选,资源缓存的时间,以ms为单位
139 }; 197 };
140 this.lastSession?.setAVPlaybackState(playbackState, (err) => { 198 this.lastSession?.setAVPlaybackState(playbackState, (err) => {
141 if (err) { 199 if (err) {
@@ -181,8 +239,12 @@ export class BackgroundAudioController { @@ -181,8 +239,12 @@ export class BackgroundAudioController {
181 // Logger.debug(TAG, `on playPrevious `); 239 // Logger.debug(TAG, `on playPrevious `);
182 // }); 240 // });
183 this.lastSession?.on('seek', (position: number) => { 241 this.lastSession?.on('seek', (position: number) => {
184 - Logger.debug(TAG, `on seek , the time is ${JSON.stringify(position)}`); 242 + Logger.debug(TAG, `on seek , the time is ${position}`);
  243 + if (this.lastItemTotalDuration == 0) {
  244 + return
  245 + }
185 246
  247 + this.hasSetupProgress = true
186 // 由于应用内seek可能会触发较长的缓冲等待,可以先把状态设置为 Buffering 248 // 由于应用内seek可能会触发较长的缓冲等待,可以先把状态设置为 Buffering
187 let playbackState: AVSessionManager.AVPlaybackState = { 249 let playbackState: AVSessionManager.AVPlaybackState = {
188 state: AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING, // 缓冲状态 250 state: AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING, // 缓冲状态
@@ -193,11 +255,13 @@ export class BackgroundAudioController { @@ -193,11 +255,13 @@ export class BackgroundAudioController {
193 } else { 255 } else {
194 Logger.debug(TAG, `SetAVPlaybackState seek buffering`); 256 Logger.debug(TAG, `SetAVPlaybackState seek buffering`);
195 } 257 }
196 - });  
197 258
198 // 应用响应seek命令,使用应用内播放器完成seek实现 259 // 应用响应seek命令,使用应用内播放器完成seek实现
199 - this.avplayerController?.setSeekTime(position * 0.001, SliderChangeMode.End) 260 + this.avplayerController?.setSeekMicroSecondsTime(position)
  261 + setTimeout(() => {
200 this.hasSetupProgress = false 262 this.hasSetupProgress = false
  263 + }, 1000)
  264 + });
201 }); 265 });
202 } 266 }
203 267
@@ -239,6 +303,7 @@ export class BackgroundAudioController { @@ -239,6 +303,7 @@ export class BackgroundAudioController {
239 // 通过wantAgent模块下getWantAgent方法获取WantAgent对象 303 // 通过wantAgent模块下getWantAgent方法获取WantAgent对象
240 wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => { 304 wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => {
241 if (!this.gotContextFunc) { return } 305 if (!this.gotContextFunc) { return }
  306 + this.lastSession?.setLaunchAbility(wantAgentObj)
242 backgroundTaskManager.startBackgroundRunning(this.gotContextFunc(), 307 backgroundTaskManager.startBackgroundRunning(this.gotContextFunc(),
243 backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, 308 backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,
244 wantAgentObj).then(() => { 309 wantAgentObj).then(() => {
@@ -336,6 +336,13 @@ export class WDPlayerController { @@ -336,6 +336,13 @@ export class WDPlayerController {
336 this.avPlayer?.seek(this.seekTime); 336 this.avPlayer?.seek(this.seekTime);
337 } 337 }
338 } 338 }
  339 + async setSeekMicroSecondsTime(value: number) {
  340 + // 防止seek报错
  341 + if (this.avPlayer && PlayerConstants.OPERATE_STATE.indexOf(this.avPlayer?.state) === -1) {
  342 + return;
  343 + }
  344 + this.avPlayer?.seek(value);
  345 + }
339 346
340 setBright() { 347 setBright() {
341 // globalThis.windowClass.setWindowBrightness(this.playerThis.bright) 348 // globalThis.windowClass.setWindowBrightness(this.playerThis.bright)
@@ -63,7 +63,7 @@ struct LaunchAdvertisingPage { @@ -63,7 +63,7 @@ struct LaunchAdvertisingPage {
63 //显示视频播放 63 //显示视频播放
64 Video({ 64 Video({
65 src: this.defaultModel.bootVideoUrl, 65 src: this.defaultModel.bootVideoUrl,
66 - previewUri: this.defaultModel.bootVideoScreenUrl, 66 + // previewUri: this.defaultModel.bootVideoScreenUrl,
67 controller: this.controller 67 controller: this.controller
68 }).controls(false) 68 }).controls(false)
69 .autoPlay(true) 69 .autoPlay(true)
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 "deliveryWithInstall": true, 13 "deliveryWithInstall": true,
14 "installationFree": false, 14 "installationFree": false,
15 "pages": "$profile:main_pages", 15 "pages": "$profile:main_pages",
  16 + "querySchemes": ["rmrbapp"],
16 "abilities": [ 17 "abilities": [
17 { 18 {
18 "name": "EntryAbility", 19 "name": "EntryAbility",
@@ -30,22 +31,47 @@ @@ -30,22 +31,47 @@
30 "skills": [ 31 "skills": [
31 { 32 {
32 "entities": [ 33 "entities": [
33 - "entity.system.home" 34 + "entity.system.home",
  35 + "entity.system.browsable"
34 ], 36 ],
35 "actions": [ 37 "actions": [
36 "action.system.home", 38 "action.system.home",
37 - "com.test.pushaction" 39 + "com.test.pushaction",
  40 + "ohos.want.action.viewData"
38 ], 41 ],
  42 +// "uris": [{
  43 +// // 之前的 推送配置
  44 +// "scheme": 'rmrbapp',
  45 +// "host": 'rmrb.app',
  46 +// 'port': '8080',
  47 +// "path": 'openwith'
  48 +// }]
39 }, 49 },
40 { 50 {
41 "uris": [ 51 "uris": [
42 - { 52 + { // 配置 - (播控中心用)
43 "scheme": 'rmrbapp', 53 "scheme": 'rmrbapp',
44 "host": 'rmrb.app', 54 "host": 'rmrb.app',
45 'port': '8080', 55 'port': '8080',
46 "path": 'openwith' 56 "path": 'openwith'
  57 + },
  58 + { // 普通配置 - 暂时无法跳转 - ??
  59 + "scheme": "rmrbapp",
  60 + "host": "rmrb.app",
  61 + "path": "openwith"
  62 + },
  63 + { // 分享用 - 正式环境地址
  64 + "scheme": "https",
  65 + "host": "www.peopleapp.com",
  66 + "pathStartWith": "column"
  67 + },
  68 + { // 分享用 - 测试环境地址
  69 + "scheme": "https",
  70 + "host": "pd-people-uat.pdnews.cn",
  71 + "pathStartWith": "column"
47 } 72 }
48 ], 73 ],
  74 + "domainVerify": true
49 } 75 }
50 ] 76 ]
51 } 77 }