王士厅
... ... @@ -101,8 +101,23 @@ export class AppInnerLink {
return
}
if (params.type == "topic") {
if (params.type == "topic" && params.subType == "h5") {
let taskAction: Action = {
type: 'JUMP_INNER_NEW_PAGE',
params: {
contentID: params.pageId,
url: params.url,
pageID: 'SPACIAL_TOPIC_PAGE',
backVisibility: true,
extra: {
relType: params.relType,
relId: params.relId,
pageId: params.pageId
} as ExtraDTO,
} as Params,
};
WDRouterRule.jumpWithAction(taskAction)
}
if (params.type == "channel") {
... ...
... ... @@ -97,13 +97,13 @@ export struct SpacialTopicPageComponent {
this.contentDetailData.shareInfo = this.shareInfo
console.log('contentDetailData111', JSON.stringify(this.contentDetailData))
if(this.topicInfo.shareOpen === 1){
if (!this.operationButtonList.includes('share')) {
this.operationButtonList.push('share');
}
} else {
this.operationButtonList = this.operationButtonList.filter(e =>e !== 'share')
}
// if(this.topicInfo.shareOpen === 1){
// if (!this.operationButtonList.includes('share')) {
// this.operationButtonList.push('share');
// }
// } else {
// this.operationButtonList = this.operationButtonList.filter(e =>e !== 'share')
// }
// 转换评论数据
this.publishCommentModel.targetId = String(this.contentDetailData?.newsId || '')
... ...
... ... @@ -14,18 +14,8 @@ import { TrackConstants } from 'wdTracking/Index';
import { SPHelper } from 'wdKit/Index';
import { SpConstants } from 'wdConstant/Index';
import { photoPickerUtils} from '../../utils/PhotoPickerUtils';
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { picker } from '@kit.CoreFileKit';
import { camera, cameraPicker } from '@kit.CameraKit';
import { BusinessError } from '@kit.BasicServicesKit';
let mContext = getContext(this) as common.Context;
const PERMISSIONS: Array<Permissions> = [
'ohos.permission.READ_IMAGEVIDEO',
'ohos.permission.WRITE_IMAGEVIDEO'
];
@Entry
@Component
struct EditUserInfoPage {
... ... @@ -93,11 +83,7 @@ struct EditUserInfoPage {
builder: CustomDialogUI({
itemData:['相册','拍照'],
confirmCallback:(index)=>{
if (index === 0) {
this.getPhotoPicker()
}else {
this.getCamera()
}
this.pickerSelect(index)
}
}),
alignment: DialogAlignment.Bottom,
... ... @@ -105,42 +91,23 @@ struct EditUserInfoPage {
closeAnimation:{duration:0}
})
async getPhotoPicker(){
///权限查询
const context = getContext(this) as common.UIAbilityContext;
const atManager = abilityAccessCtrl.createAtManager();
await atManager.requestPermissionsFromUser(context, PERMISSIONS);
let PhotoSelectOptions = new picker.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型
PhotoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
let photoPicker = new picker.PhotoViewPicker(); // 使用图库选择器对象前,需要先创建PhotoViewPicker实例
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {
if (PhotoSelectResult !== null && PhotoSelectResult !==
undefined) {
// 接口采用callback异步返回形式,返回PhotoSelectResult对象,故进行下一步操作前要先判断是否已经成功返回PhotoSelectResult对象了
this.headerImg = PhotoSelectResult['photoUris'][0]
pickerSelect(index:number){
if (index === 0) {
photoPickerUtils.getPhotoPicker().then(value => {
if (value.length > 0) {
this.headerImg = value
}
})
}else {
photoPickerUtils.getCamera().then(value => {
if (value.length > 0) {
this.headerImg = value
}
async getCamera(){
try {
let pickerProfile: cameraPicker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
};
let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(mContext,
[cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO], pickerProfile);
if (pickerResult['resultCode'] === 0) {
this.headerImg = pickerResult['resultUri']
}
console.log("the pick pickerResult is:" + JSON.stringify(pickerResult));
} catch (error) {
let err = error as BusinessError;
console.error(`the pick call failed. error code: ${err.code}`);
})
}
}
aboutToAppear() {
let userType = SPHelper.default.getSync(SpConstants.USER_Type,"") as string
if (userType && userType.length > 0) {
... ...
... ... @@ -96,6 +96,7 @@ export struct OperRowListView {
@State likesStyle: number | string = 1 // 赞样式 1红心(点赞) 2大拇指(祈福) 3蜡烛(默哀) 4置空
@State openLikes: boolean = false // 是否可以点赞 1:可以 0:不可以
@Prop topicInfo?: TopicInfo = {} as TopicInfo
private shareOpen = 0;
async aboutToAppear() {
console.info(TAG, 'this.needLike', this.needLike)
... ... @@ -137,6 +138,7 @@ export struct OperRowListView {
if (!this.contentDetailData) {
return
}
this.shareOpen = this.contentDetailData.shareInfo.shareOpen;
const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
if (user_id) {
this.getInteractDataStatus()
... ... @@ -393,10 +395,11 @@ export struct OperRowListView {
*/
@Builder
builderShare() {
if(this.contentDetailData?.shareInfo?.shareOpen == 1) {
Column() {
Image(this.styleType == 1 ? $r('app.media.iv_live_comment_share') :
$r('app.media.iv_live_comment_share_white'))
Image(this.styleType == 1 ? (this.shareOpen == 1?$r('app.media.iv_live_comment_share'):$r('app.media.more_icon_black')) :
(this.shareOpen == 1?$r('app.media.iv_live_comment_share_white'):$r('app.media.more_icon_white')))
.width(24)
.height(24)
.aspectRatio(1)
... ... @@ -411,7 +414,9 @@ export struct OperRowListView {
.borderRadius(18)
.backgroundColor(this.pageComponentType === 2 ? '#4D000000' : Color.Transparent)
}
}
// if(this.contentDetailData?.shareInfo?.shareOpen == 1) {
//
// }
handleStyle() {
if (this.styleType == 1) {
... ... @@ -440,7 +445,7 @@ export struct OperRowListView {
appCustomTargetRelType: this.topicInfo?.relType,
appCustomShowReport: false,
appCustomShowLike: -1,
shareOpen: 1,
shareOpen: this.shareOpen,
sharePosterOpen: this.topicInfo?.posterFlag,
appCustomShowPoster: this.topicInfo?.posterFlag && this.topicInfo?.posterFlag > 0 ? 1 : -1,
}
... ...
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { picker } from '@kit.CoreFileKit';
import { camera, cameraPicker } from '@kit.CameraKit';
import { BusinessError } from '@kit.BasicServicesKit';
let mContext = getContext(this) as common.Context;
const PERMISSIONS: Array<Permissions> = [
'ohos.permission.READ_IMAGEVIDEO',
];
export class PhotoPickerUtils {
async getPhotoPicker(){
this.pickerPermissions()
let PhotoSelectOptions = new picker.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型
PhotoSelectOptions.maxSelectNumber = 1; // 选择媒体文件的最大数目
let photoPicker = new picker.PhotoViewPicker(); // 使用图库选择器对象前,需要先创建PhotoViewPicker实例
return new Promise<string>((success, fail) => {
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {
if (PhotoSelectResult !== null && PhotoSelectResult !==
undefined) {
// 接口采用callback异步返回形式,返回PhotoSelectResult对象,故进行下一步操作前要先判断是否已经成功返回PhotoSelectResult对象了
success(PhotoSelectResult['photoUris'][0])
}
})
})
}
async getCamera(){
this.pickerPermissions()
let pickerProfile: cameraPicker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
};
let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(mContext,
[cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO], pickerProfile);
return new Promise<string>((success, fail) => {
if (pickerResult['resultCode'] === 0) {
success(pickerResult['resultUri'])
}
})
}
async pickerPermissions(){
///权限查询
const context = getContext(this) as common.UIAbilityContext;
const atManager = abilityAccessCtrl.createAtManager();
await atManager.requestPermissionsFromUser(context, PERMISSIONS);
}
}
export const photoPickerUtils: PhotoPickerUtils = new PhotoPickerUtils();
\ No newline at end of file
... ...
... ... @@ -45,11 +45,10 @@ export class AudioSuspensionModel {
this.playerController.get().keepOnBackground = true
BackgroundAudioController.sharedController().avplayerController = this.playerController.get()
await BackgroundAudioController.sharedController().createSession()
BackgroundAudioController.sharedController().startContinuousTask()
let id = $r('app.media.newspaper_default').id
BackgroundAudioController.sharedController().setSessionMetaData(srcContentId ?? "", srcTitle, 'file://', srcSource ?? "")
BackgroundAudioController.sharedController().stopUseFeatures()
// BackgroundAudioController.sharedController().startContinuousTask()
BackgroundAudioController.sharedController().listenPlayEvents()
await BackgroundAudioController.sharedController().setSessionMetaData(srcContentId ?? "", srcTitle, $r("app.media.system_audio_icon_bk_center"), srcSource ?? "")
BackgroundAudioController.sharedController().stopUseFeatures()
if (this.url === url) {
this.isMinimize = AppStorage.link<boolean>('isMinimize')
... ...
... ... @@ -2,10 +2,11 @@ import { Context, WantAgent, wantAgent } from '@kit.AbilityKit'
import { avSession as AVSessionManager } from '@kit.AVSessionKit'
import { backgroundTaskManager } from '@kit.BackgroundTasksKit'
import { BusinessError } from '@kit.BasicServicesKit'
import { Logger } from 'wdKit/Index'
import { PlayerConstants } from '../constants/PlayerConstants'
import { DateTimeUtils, EmitterEventId, EmitterUtils, Logger } from 'wdKit/Index'
import { Events, PlayerConstants } from '../constants/PlayerConstants'
import { WDPlayerController } from './WDPlayerController'
import { image } from '@kit.ImageKit'
import { JSON } from '@kit.ArkTS'
const TAG = "BackgroundAudioController"
... ... @@ -13,6 +14,9 @@ export class BackgroundAudioController {
private static bgAudioController: BackgroundAudioController
private constructor() {
EmitterUtils.receiveEvent(EmitterEventId.APP_ENTER_BACKGROUD, () => {
this.startContinuousTask()
})
}
public static sharedController() {
if (!BackgroundAudioController.bgAudioController) {
... ... @@ -24,9 +28,17 @@ export class BackgroundAudioController {
public gotContextFunc?: () => Context
public avplayerController?: WDPlayerController
private lastSession?: AVSessionManager.AVSession
private applyedLongTaskPlay: boolean = false
private lastProgress: number = 0.0
private hasSetupProgress: boolean = false
private playing: boolean = false
private lastItemAssetId?: string
private lastItemTitle?: string
private lastItemMediaImage?: Resource
private lastItemArtist?: string
private lastItemTotalDuration: number = 0
// 开始创建并激活媒体会话
// 创建session
... ... @@ -56,23 +68,53 @@ export class BackgroundAudioController {
}
//设置播放元数据
setSessionMetaData(assetId: string, title: string, mediaImage: image.PixelMap | string, artist: string) {
Logger.debug(TAG, `SetAVMetadata assetId: ${assetId}}, title: ${title}, mediaImage: ${mediaImage}, artist: ${artist}`);
async setSessionMetaData(assetId: string, title: string, mediaImage: Resource, artist: string) {
this.lastItemAssetId = assetId
this.lastItemTitle = title
this.lastItemMediaImage = mediaImage
this.lastItemArtist = artist
}
async setSessionMetaDataWithDuration(assetId: string, title: string, mediaImage: Resource, artist: string, duration: number) {
Logger.debug(TAG, `SetAVMetadata assetId: ${assetId}}, title: ${title}, mediaImage: ${mediaImage}, artist: ${artist}, duration: ${duration}`);
if (!this.gotContextFunc) { return }
let pixelMapImage:image.PixelMap | null = null
try {
const data:Uint8Array = await this.gotContextFunc().resourceManager.getMediaContent(mediaImage)
pixelMapImage = await image.createPixelMap(data.buffer as ArrayBuffer, {
editable: false,
alphaType: image.AlphaType.UNKNOWN,
srcPixelFormat: image.PixelMapFormat.RGB_888,
size: { width:300, height:300 }
})
} catch (e) {
Logger.error(TAG, `SetAVMetadata ` + JSON.stringify(e));
} finally {
// Logger.debug(TAG, `SetAVMetadata ` + JSON.stringify(pixelMapImage));
let metadata: AVSessionManager.AVMetadata = {
assetId: assetId.length > 0 ? assetId : "fake-asset-id",
title: title.length > 0 ? title : " ",
mediaImage: mediaImage,
mediaImage: pixelMapImage ?? ("file://" + mediaImage.id),
artist: artist.length > 0 ? artist : "人日日报",
duration: duration
};
this.lastSession?.setAVMetadata(metadata).then(() => {
try {
await this.lastSession?.setAVMetadata(metadata)
Logger.debug(TAG, `SetAVMetadata successfully`);
}).catch((err: BusinessError) => {
} catch (err) {
Logger.error(TAG, `Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`);
});
} finally {
pixelMapImage?.release()
}
}
}
//设置播放状态
setSessionPlayStatus(playStatus: number) {
let needUpdateProgress = false
let playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY
switch (playStatus){
case PlayerConstants.STATUS_PAUSE: {
... ... @@ -80,6 +122,7 @@ export class BackgroundAudioController {
} break
case PlayerConstants.STATUS_START: {
playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY
needUpdateProgress = true
} break
case PlayerConstants.STATUS_STOP: {
playbackStatus = AVSessionManager.PlaybackState.PLAYBACK_STATE_STOP
... ... @@ -103,13 +146,15 @@ export class BackgroundAudioController {
Logger.error(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`);
} else {
Logger.debug(TAG, `SetAVPlaybackState 设置播放状态成功 ` + playStatus);
if (needUpdateProgress) {
this.hasSetupProgress = false
}
}
});
}
//设置进度,单位秒
setSessionPlayProgress(progressDuration: number, totalDuration: number) {
// Logger.debug(TAG, `set progress: ` + progressDuration + " duration: " + totalDuration);
//设置进度,单位ms
async setSessionPlayProgress(progressDuration: number, totalDuration: number) {
if (totalDuration <= 0) {
return
}
... ... @@ -117,25 +162,38 @@ export class BackgroundAudioController {
if (Math.abs(newProgress - this.lastProgress) < 0.01) {
return
}
// Logger.debug(TAG, `set progress: ` + progressDuration + " duration: " + totalDuration);
this.lastProgress = newProgress
if (this.lastItemAssetId) {
this.lastItemTotalDuration = totalDuration
await this.setSessionMetaDataWithDuration(
this.lastItemAssetId ?? "",
this.lastItemTitle ?? "",
this.lastItemMediaImage!,
this.lastItemArtist ?? "",
totalDuration
)
this.lastItemAssetId = undefined
}
if (this.hasSetupProgress) {
return
}
this.hasSetupProgress = true
Logger.debug(TAG, `set progress: ` + progressDuration + " duration: " + totalDuration);
Logger.debug(TAG, `set progress: ` + DateTimeUtils.secondToTime(progressDuration / 1000)
+ " duration: " + DateTimeUtils.secondToTime(totalDuration / 1000));
// 设置状态: 播放状态,进度位置,播放倍速,缓存的时间
let playbackState: AVSessionManager.AVPlaybackState = {
state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY, // 播放状态
position: {
elapsedTime: progressDuration * 1000, // 已经播放的位置,以ms为单位
elapsedTime: progressDuration, // 已经播放的位置,以ms为单位
updateTime: new Date().getTime(), // 应用更新当前位置时的时间戳,以ms为单位
},
duration: totalDuration * 1000,
speed: 1.0, // 可选,默认是1.0,播放的倍速,按照应用内支持的speed进行设置,系统不做校验
bufferedTime: totalDuration * 1000, // 可选,资源缓存的时间,以ms为单位
// duration: totalDuration,
// speed: 1.0, // 可选,默认是1.0,播放的倍速,按照应用内支持的speed进行设置,系统不做校验
// bufferedTime: totalDuration, // 可选,资源缓存的时间,以ms为单位
};
this.lastSession?.setAVPlaybackState(playbackState, (err) => {
if (err) {
... ... @@ -181,8 +239,12 @@ export class BackgroundAudioController {
// Logger.debug(TAG, `on playPrevious `);
// });
this.lastSession?.on('seek', (position: number) => {
Logger.debug(TAG, `on seek , the time is ${JSON.stringify(position)}`);
Logger.debug(TAG, `on seek , the time is ${position}`);
if (this.lastItemTotalDuration == 0) {
return
}
this.hasSetupProgress = true
// 由于应用内seek可能会触发较长的缓冲等待,可以先把状态设置为 Buffering
let playbackState: AVSessionManager.AVPlaybackState = {
state: AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING, // 缓冲状态
... ... @@ -193,11 +255,13 @@ export class BackgroundAudioController {
} else {
Logger.debug(TAG, `SetAVPlaybackState seek buffering`);
}
});
// 应用响应seek命令,使用应用内播放器完成seek实现
this.avplayerController?.setSeekTime(position * 0.001, SliderChangeMode.End)
this.avplayerController?.setSeekMicroSecondsTime(position)
setTimeout(() => {
this.hasSetupProgress = false
}, 1000)
});
});
}
... ... @@ -239,6 +303,7 @@ export class BackgroundAudioController {
// 通过wantAgent模块下getWantAgent方法获取WantAgent对象
wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => {
if (!this.gotContextFunc) { return }
this.lastSession?.setLaunchAbility(wantAgentObj)
backgroundTaskManager.startBackgroundRunning(this.gotContextFunc(),
backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,
wantAgentObj).then(() => {
... ...
... ... @@ -336,6 +336,13 @@ export class WDPlayerController {
this.avPlayer?.seek(this.seekTime);
}
}
async setSeekMicroSecondsTime(value: number) {
// 防止seek报错
if (this.avPlayer && PlayerConstants.OPERATE_STATE.indexOf(this.avPlayer?.state) === -1) {
return;
}
this.avPlayer?.seek(value);
}
setBright() {
// globalThis.windowClass.setWindowBrightness(this.playerThis.bright)
... ...
... ... @@ -63,7 +63,7 @@ struct LaunchAdvertisingPage {
//显示视频播放
Video({
src: this.defaultModel.bootVideoUrl,
previewUri: this.defaultModel.bootVideoScreenUrl,
// previewUri: this.defaultModel.bootVideoScreenUrl,
controller: this.controller
}).controls(false)
.autoPlay(true)
... ...
... ... @@ -13,6 +13,7 @@
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"querySchemes": ["rmrbapp"],
"abilities": [
{
"name": "EntryAbility",
... ... @@ -30,22 +31,47 @@
"skills": [
{
"entities": [
"entity.system.home"
"entity.system.home",
"entity.system.browsable"
],
"actions": [
"action.system.home",
"com.test.pushaction"
"com.test.pushaction",
"ohos.want.action.viewData"
],
// "uris": [{
// // 之前的 推送配置
// "scheme": 'rmrbapp',
// "host": 'rmrb.app',
// 'port': '8080',
// "path": 'openwith'
// }]
},
{
"uris": [
{
{ // 配置 - (播控中心用)
"scheme": 'rmrbapp',
"host": 'rmrb.app',
'port': '8080',
"path": 'openwith'
},
{ // 普通配置 - 暂时无法跳转 - ??
"scheme": "rmrbapp",
"host": "rmrb.app",
"path": "openwith"
},
{ // 分享用 - 正式环境地址
"scheme": "https",
"host": "www.peopleapp.com",
"pathStartWith": "column"
},
{ // 分享用 - 测试环境地址
"scheme": "https",
"host": "pd-people-uat.pdnews.cn",
"pathStartWith": "column"
}
],
"domainVerify": true
}
]
}
... ...