zhenghy

Merge branch 'main' of http://192.168.1.42/developOne/harmonyPool

# Conflicts:
#	sight_harmony/features/wdDetailPlayShortVideo/src/main/ets/view/PlayerRightView.ets
Showing 51 changed files with 334 additions and 1606 deletions
@mpaas:registry=https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/meta
\ No newline at end of file
... ... @@ -38,4 +38,7 @@ export class SpConstants{
//启动页数据存储key
static APP_LAUNCH_PAGE_DATA_MODEL = 'app_launch_page_data_model'
//频道信息流页面左右挂角
static APP_PAGE_CORNER_ADV = 'app_page_corner_adv_'
}
\ No newline at end of file
... ...
import { expect } from '@ohos/hypium';
export { Logger } from './src/main/ets/utils/Logger'
export { ResourcesUtils } from './src/main/ets/utils/ResourcesUtils'
... ... @@ -51,7 +49,3 @@ export { NetworkUtil } from './src/main/ets/utils/NetworkUtil'
export { NetworkManager } from './src/main/ets/network/NetworkManager'
export { NetworkType } from './src/main/ets/network/NetworkType'
export { MpaasUtils } from './src/main/ets/mpaas/MpaasUtils'
export { MpaasUpgradeCheck, UpgradeTipContent } from './src/main/ets/mpaas/MpaasUpgradeCheck'
\ No newline at end of file
... ...
... ... @@ -6,6 +6,5 @@
"description": "Please describe the basic information.",
"main": "Index.ets",
"version": "1.0.0",
"dependencies": {
}
"dependencies": {}
}
... ...
import { MPUpgradeService } from '@mpaas/upgrade'
import { upgradeRes } from '@mpaas/upgrade/src/main/ets/t4/a'
import { AppUtils } from '../utils/AppUtils'
import { SPHelper } from '../utils/SPHelper'
export interface UpgradeTipContent {
content: string
newVersion: string
downloadUrl: string
forceUpgrade: boolean
}
export class MpaasUpgradeCheck {
/// 默认提示框
checkNewVersionAndShow() {
try {
MPUpgradeService.checkNewVersionAndShow()
} catch (error) {
console.log("mpaas upgrade fail", JSON.stringify(error))
}
}
checkNewVersion(): Promise<UpgradeTipContent | null> {
return new Promise((resolve, fail) => {
MPUpgradeService.checkNewVersion().then((response)=>{
let str = JSON.stringify(response)
console.log("mpaas upgrade check", str)
/*
{
"android64FileSize": 0,
"downloadURL": "https://appgallery.huawei.com/#/app",
"fileSize": 0,
"fullMd5": "no md5",
"guideMemo": "欢迎使用新版本",
"isWifi": 0,
"netType": "ALL",
"newestVersion": "1.0.1",
"resultStatus": 204,
"silentType": 0,
"upgradeVersion": "1.0.1"
}*/
let res = response as upgradeRes
// AliUpgradeNewVersion = 201, /*当前使用的已是最新版本*/
// AliUpgradeOneTime = 202, /*客户端已有新版本,单次提醒*/
// AliUpgradeForceUpdate = 203, /*客户端已有新版本,强制升级(已废弃)*/
// AliUpgradeEveryTime = 204, /*客户端已有新版本,多次提醒*/
// AliUpgradeRejectLogin = 205, /*限制登录(已废弃)*/
// AliUpgradeForceUpdateWithLogin = 206 /*客户端已有新版本,强制升级*/
const currentAppVersoin = AppUtils.getAppVersionName()
if (res.resultStatus == 201) {
resolve(null)
return
}
// 单次升级控制
if (res.resultStatus == 202) {
const oldOnceValue = SPHelper.default.getSync("upgradeOnceKey", false) as boolean
if (true == oldOnceValue) {
resolve(null)
return
}
SPHelper.default.save("upgradeOnceKey", true)
} else {
SPHelper.default.save("upgradeOnceKey", false)
}
if (res.resultStatus == 202 || res.resultStatus == 204 || res.resultStatus == 206) {
let content: UpgradeTipContent = {
content: res.guideMemo,
newVersion: res.upgradeVersion,
downloadUrl: res.downloadURL,
forceUpgrade: res.resultStatus == 206
}
resolve(content)
return
}
resolve(null)
}).catch((error: Error) => {
console.log("mpaas upgrade fail", `name: ${error.name}, message: ${error.message}, \nstack: ${error.stack}`)
fail("检测升级失败")
})
})
}
}
\ No newline at end of file
import { MPFramework } from '@mpaas/framework'
import { common } from '@kit.AbilityKit';
/*
对接mpaas注意:
* 1、后台创建mpaas.config,需要包名。放到rawfile目录
* 2、网关加密hs_1222.png图片,放到rawfile目录
* 3. 配置和加密图片,需要包名和签名对应,否则无法使用
* */
export class MpaasUtils {
// 启动时onCreate()方法调用
static initApp(context: common.UIAbilityContext) {
MPFramework.create(context);
}
// 获取mPaaS utdid
static async mpaasUtdid() {
let utdid = await MPFramework.instance.udid
return utdid
}
// 登录和退出登录调用,用来管理白名单用
static setupUserId(userId?: string) {
MPFramework.instance.userId = userId
}
}
\ No newline at end of file
... ... @@ -53,16 +53,5 @@ export class AppUtils {
}
return '';
}
static getFingerprint(): string {
try {
let bundleInfo =
bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO);
let finger = bundleInfo.signatureInfo.fingerprint;
} catch (e) {
Logger.warn(TAG, 'get app signatureinfo error:' + e?.message);
}
return '';
}
}
... ...
export { ResponseDTO } from "./src/main/ets/bean/ResponseDTO"
export { ResposeError } from "./src/main/ets/bean/ResposeError"
export { HttpRequest as WDHttp } from "./src/main/ets/http/HttpRequest"
export { HttpUrlUtils } from "./src/main/ets/http/HttpUrlUtils"
... ...
/**
* 接口返回错误数据封装
*/
export class ResposeError {
code: number = -1;
message: string = '';
static buildError(message: string, code?: number): ResposeError {
let error = new ResposeError()
error.message = message
if (code) {
error.code = code
}
return error;
}
}
\ No newline at end of file
... ...
... ... @@ -6,6 +6,7 @@ import axios, {
InternalAxiosRequestConfig
} from '@ohos/axios';
import { Logger } from 'wdKit/Index';
import { ResposeError } from '../bean/ResposeError';
// import type ResponseDTO from '../models/ResponseDTO';
... ... @@ -99,17 +100,16 @@ instance.interceptors.response.use(// 响应拦截器response类型就是Axios.r
},
(error: AxiosError) => {
// 异常响应
// console.log('全局响应失败拦截')
// console.log(error.request)
// console.log(error.response)
// 429-流量超标;403-临时token;406-token过期,强制下线
// 这里用来处理http常见错误,进行全局提示
let errorBean = new ResposeError()
if (error != null && error.response != null) {
let message = buildErrorMsg(error.response.status);
// 错误消息可以使用全局弹框展示出来
console.log(`httpStatus:${error.response?.status}-${message},请检查网络或联系管理员!`)
errorBean = buildError(error.response.status)
}
return Promise.reject(error);
return Promise.reject(errorBean);
}
);
... ... @@ -161,3 +161,9 @@ function buildErrorMsg(httpStatus: number): string {
}
return message;
}
function buildError(httpStatus: number): ResposeError {
let message = buildErrorMsg(httpStatus);
let error: ResposeError = ResposeError.buildError(message, httpStatus)
return error;
}
... ...
... ... @@ -4,6 +4,7 @@ import HashMap from '@ohos.util.HashMap';
import { ResponseDTO } from '../bean/ResponseDTO';
import { HttpUrlUtils, WDHttp } from '../../../../Index';
import { RefreshTokenRes } from '../bean/RefreshTokenRes';
import { ResposeError } from '../bean/ResposeError';
const TAG: string = 'HttpBizUtil'
... ... @@ -20,14 +21,12 @@ export class HttpBizUtil {
* @returns 返回值
*/
static get<T = ResponseDTO<string>>(url: string, headers?: HashMap<string, string>): Promise<T> {
return new Promise<T>((success, debug) => {
return new Promise<T>((success, error) => {
WDHttp.get<T>(url, headers).then((originalRes: T) => {
try {
let resDTO = originalRes as ResponseDTO
Logger.debug(TAG, 'get: ' + resDTO.code)
Logger.debug(TAG, 'get: ' + resDTO.message)
success(originalRes)
}).catch((res: ResposeError) => {
// 403:临时token;406:强制下线、封禁、清空登录信息还要跳转登录页面
if (resDTO.code == 403 || resDTO.code == 406) {
if (res.code == 403 || res.code == 406) {
HttpBizUtil.refreshToken().then((token: string) => {
if (headers) {
headers.replace('RMRB-X-TOKEN', token)
... ... @@ -39,18 +38,14 @@ export class HttpBizUtil {
Logger.debug(TAG, 'get again: ' + againResDTO)
success(againResDTO)
}).catch((res: object) => {
debug(res)
error(ResposeError.buildError(JSON.stringify(res)))
})
});
} else {
success(originalRes)
}
} catch (e) {
debug(originalRes)
// 非403、406,直接抛出去
Logger.debug(TAG, 'get else: ' + JSON.stringify(res))
error(res)
}
}).catch((res: object) => {
debug(res)
})
})
}
... ... @@ -63,34 +58,31 @@ export class HttpBizUtil {
* @returns 返回值
*/
static post<T = ResponseDTO<string>>(url: string, data?: object, headers?: HashMap<string, string>): Promise<T> {
return new Promise<T>((success, debug) => {
return new Promise<T>((success, error) => {
WDHttp.post<T>(url, data, headers).then((originalRes: T) => {
try {
let resDTO = originalRes as ResponseDTO
Logger.debug(TAG, 'post: ' + resDTO.code)
Logger.debug(TAG, 'post: ' + resDTO.message)
success(originalRes)
}).catch((res: ResposeError) => {
// 403:临时token;406:强制下线、封禁、清空登录信息还要跳转登录页面
if (resDTO.code == 403 || resDTO.code == 406) {
Logger.debug(TAG, 'post catch error: ' + JSON.stringify(res))
if (res.code == 403 || res.code == 406) {
HttpBizUtil.refreshToken().then((token: string) => {
if (headers) {
headers.replace('RMRB-X-TOKEN', token)
headers.replace('cookie', 'RMRB-X-TOKEN=' + token)
}
Logger.debug(TAG, 'post again send: ' + token)
// refreshToken为空场景不处理,直接请求接口。
WDHttp.post<T>(url, headers).then((againResDTO: T) => {
WDHttp.post<T>(url, data, headers).then((againResDTO: T) => {
Logger.debug(TAG, 'post again success: ' + JSON.stringify(againResDTO))
success(againResDTO)
}).catch((res: object) => {
debug(res)
error(ResposeError.buildError(JSON.stringify(res)))
})
});
} else {
success(originalRes)
// 非403、406,直接抛出去
error(res)
}
} catch (e) {
success(originalRes)
}
}).catch((res: object) => {
debug(res)
})
})
}
... ... @@ -104,9 +96,9 @@ export class HttpBizUtil {
params.set('refreshToken', HttpUrlUtils.getRefreshToken())
params.set('deviceId', HttpUrlUtils.getDeviceId())
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
Logger.debug(TAG, 'refreshToken getRefreshToken: ' + HttpUrlUtils.getRefreshToken())
// // 请求刷新token接口
return new Promise<string>((success, debug) => {
// Logger.debug(TAG, 'refreshToken getRefreshToken: ' + HttpUrlUtils.getRefreshToken())
// 请求刷新token接口
return new Promise<string>((success, error) => {
WDHttp.post<ResponseDTO<RefreshTokenRes>>(url, params, headers).then((resDTO: ResponseDTO<RefreshTokenRes>) => {
let newToken = ''
if (resDTO) {
... ... @@ -126,6 +118,7 @@ export class HttpBizUtil {
Logger.debug(TAG, 'refreshToken refreshToken: ' + resDTO.data.refreshToken)
}
}
Logger.debug(TAG, 'refreshToken last jwtToken: ' + newToken)
success(newToken)
});
})
... ...
... ... @@ -2,7 +2,7 @@ import { Action, ContentDTO, Params, PhotoListBean, commentInfo } from 'wdBean';
import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO';
import { Logger } from 'wdKit';
import { StringUtils } from 'wdKit/src/main/ets/utils/StringUtils';
import { WDRouterRule } from '../router/WDRouterRule';
import { WDRouterRule, WDRouterPage } from '../../../../Index';
import { ContentConstants } from 'wdConstant';
import { common, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
... ... @@ -398,4 +398,14 @@ export class ProcessUtils {
public static jumpChannelTab(channelId: string, pageId: string) {
HomeChannelUtils.jumpChannelTab(channelId, pageId)
}
/**
* 跳转人民号主页
*@params creatorId 创作者id
*/
public static gotoPeopleShipHomePage(creatorId: string) {
let params = {'creatorId': creatorId} as Record<string, string>;
WDRouterRule.jumpWithPage(WDRouterPage.peopleShipHomePage, params)
}
}
... ...
... ... @@ -145,6 +145,10 @@ function handleJsCallAppInnerLinkMethod(data: Message) {
content.objectType = ContentConstants.TYPE_FOURTEEN
ProcessUtils.processPage(content)
break;
case 'owner_page':
let creatorId = urlParams.get('creatorId') || ''
ProcessUtils.gotoPeopleShipHomePage(creatorId)
break;
default:
break;
}
... ...
... ... @@ -68,14 +68,9 @@ export interface CompAdvBean {
displayPriority: number;
/**
* 展示的次数
*/
showCount: number;
/**
* 页面id
*/
pageId: String ;
pageId: String;
/**
* 开屏广告-显示时长
... ... @@ -97,6 +92,4 @@ export interface CompAdvBean {
displayRound: number;
}
... ...
import { AccountManagerUtils, Logger, DateTimeUtils } from 'wdKit';
import { AccountManagerUtils, Logger, DateTimeUtils, SPHelper } from 'wdKit';
import { MultiPictureDetailViewModel } from '../viewmodel/MultiPictureDetailViewModel';
import { ContentDetailDTO,batchLikeAndCollectResult,batchLikeAndCollectParams,postBatchAttentionStatusParams,
import { ContentDetailDTO,postBatchAttentionStatusParams,
PhotoListBean,
ContentDTO,
RmhInfoDTO, } from 'wdBean';
import media from '@ohos.multimedia.media';
import { OperRowListView } from './view/OperRowListView';
import { WDPlayerController } from 'wdPlayer/Index';
import {
batchLikeAndCollectParams,
batchLikeAndCollectResult,
ContentDetailRequest,
contentListParams,
postExecuteCollectRecordParams,
postExecuteLikeParams,
postInteractAccentionOperateParams
} from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest';
import { ContentConstants } from '../constants/ContentConstants';
import { ProcessUtils } from 'wdRouter';
import { ProcessUtils, WDRouterPage, WDRouterRule } from 'wdRouter';
import { StringUtils } from 'wdKit/src/main/ets/utils/StringUtils';
import display from '@ohos.display';
import { BusinessError } from '@ohos.base';
import { CommonConstants } from 'wdConstant/Index';
import { CommonConstants, SpConstants } from 'wdConstant/Index';
import { CardMediaInfo } from '../components/cardCommon/CardMediaInfo'
import router from '@ohos.router';
const TAG = 'DynamicDetailComponent'
... ... @@ -24,20 +33,13 @@ export struct DynamicDetailComponent {
private contentId: string = ''
private relType: string = ''
//出参 fixme 模拟数据用json转换
@State contentDetailData: ContentDetailDTO = {
publishTime: "2023年03月14日 08:16",
rmhInfo:{rmhHeadUrl:"",rmhName:"人民号名称",rmhDesc:"人民号描述单行展示"},
newsContent:"优先展示这个内容",
newsSummary:"其次展示这个内容",
newsTitle:"上面两个都没有再展示这个内容",
newsType:15
} as ContentDetailDTO
@State contentDetailData: ContentDetailDTO = {} as ContentDetailDTO
//变量
scroller: Scroller = new Scroller();
/**
* 默认未关注 点击去关注
*/
private followStatus: String = '0';
@State followStatus: String = '0';
@State newsStatusOfUser: batchLikeAndCollectResult | undefined = undefined // 点赞、收藏状态
//跳转
... ... @@ -130,7 +132,7 @@ export struct DynamicDetailComponent {
.backgroundColor($r('app.color.color_ED2800'))
.fontColor($r('app.color.color_fff'))
.onClick(() => {
// this.handleAccention(this.item, 1)
this.handleAccention()
})
} else {
Text('已关注')
... ... @@ -143,7 +145,7 @@ export struct DynamicDetailComponent {
.borderColor($r('app.color.color_CCCCCC'))
.fontColor($r('app.color.color_CCCCCC'))
.onClick(() => {
// this.handleAccention(this.item, 0)
this.handleAccention()
})
}
}
... ... @@ -224,6 +226,9 @@ export struct DynamicDetailComponent {
item.height = callback?.height || 0;
})
}
.onClick((event: ClickEvent) => {
ProcessUtils.gotoMultiPictureListPage(this.contentDetailData.photoList)
})
}
} else if (this.contentDetailData.photoList.length === 4) {
GridCol({
... ... @@ -233,6 +238,9 @@ export struct DynamicDetailComponent {
.aspectRatio(1)
.borderRadius(this.caclImageRadius(index))
}
.onClick((event: ClickEvent) => {
ProcessUtils.gotoMultiPictureListPage(this.contentDetailData.photoList)
})
} else {
GridCol({
span: { sm: 4, lg: 3 }
... ... @@ -241,6 +249,9 @@ export struct DynamicDetailComponent {
.aspectRatio(1)
.borderRadius(this.caclImageRadius(index))
}
.onClick((event: ClickEvent) => {
ProcessUtils.gotoMultiPictureListPage(this.contentDetailData.photoList)
})
}
})
}
... ... @@ -414,7 +425,7 @@ export struct DynamicDetailComponent {
console.error(TAG, JSON.stringify(this.contentDetailData))
let data = await MultiPictureDetailViewModel.getInteractDataStatus(params)
console.error(TAG, '查询用户对作品点赞、收藏状态', JSON.stringify(data))
this.newsStatusOfUser = data[0];
// this.newsStatusOfUser = data[0];
Logger.info(TAG, `newsStatusOfUser:${JSON.stringify(this.newsStatusOfUser)}`)
} catch (exception) {
console.error(TAG, JSON.stringify(exception))
... ... @@ -486,6 +497,33 @@ export struct DynamicDetailComponent {
return 3; //普通图
}
}
/**
* 关注号主
*/
async handleAccention() {
// 未登录,跳转登录
const user_id = await SPHelper.default.get(SpConstants.USER_ID, '')
if (!user_id) {
WDRouterRule.jumpWithPage(WDRouterPage.loginPage)
return
}
const params2: postInteractAccentionOperateParams = {
attentionUserType: this.contentDetailData?.rmhInfo?.userType || '', //被关注用户类型(1 普通用户 2 视频号 3 矩阵号)
attentionUserId: this.contentDetailData?.rmhInfo?.userId || '', // 被关注用户号主id
attentionCreatorId: this.contentDetailData?.rmhInfo?.rmhId || '', // 被关注用户号主id
status: this.followStatus == '0'? 1:0,
}
ContentDetailRequest.postInteractAccentionOperate(params2).then(res => {
console.log('关注号主==', JSON.stringify(res.data))
if (this.followStatus == '1') {
this.followStatus = '0'
} else {
this.followStatus = '1'
}
})
}
}
interface radiusType {
... ...
... ... @@ -12,6 +12,7 @@ import {
} from 'wdBean';
import DetailViewModel from '../viewmodel/DetailViewModel';
import { ImageAndTextWebComponent } from './ImageAndTextWebComponent';
import { OperRowListView } from './view/OperRowListView';
import router from '@ohos.router';
import { RecommendList } from '../components/view/RecommendList'
import { CommonConstants } from 'wdConstant';
... ... @@ -91,7 +92,8 @@ export struct ImageAndTextPageComponent {
}
//底部交互区
Row() {
OperRowListView({contentDetailData: this.contentDetailData[0]})
/* Row() {
Image($r('app.media.icon_arrow_left'))
.width(24)
.height(24)
... ... @@ -126,7 +128,7 @@ export struct ImageAndTextPageComponent {
.height(56)
.padding({ left: 15, right: 15, bottom: 50, top: 20 })
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor(Color.White)
.backgroundColor(Color.White)*/
}
}
... ...
... ... @@ -6,7 +6,8 @@ import {
H5ReceiveDetailBean,
ResponseBean
} from 'wdBean';
import { Logger } from 'wdKit';
import { Logger, SPHelper } from 'wdKit';
import { SpConstants } from 'wdConstant';
import { WdWebLocalComponent } from 'wdWebComponent';
import { NativeCallH5Type } from 'wdWebComponent/src/main/ets/pages/NativeCallH5Type';
import { BridgeWebViewControl } from 'wdJsBridge/Index';
... ... @@ -22,7 +23,7 @@ export struct ImageAndTextWebComponent {
private webPrepared = false;
private dataPrepared = false;
onDetailDataUpdated() {
async onDetailDataUpdated() {
if (this.action) {
let contentId: string = ''
let contentType: string = ''
... ... @@ -30,6 +31,8 @@ export struct ImageAndTextWebComponent {
let channelId: string = ''
let compId: string = ''
let sourcePage: string = '5'
let creatorId = await SPHelper.default.get(SpConstants.USER_CREATOR_ID, '') || ''
let isLogin = await SPHelper.default.get(SpConstants.USER_STATUS, '') || '0'
if (this.action.params) {
if (this.action.params.contentID) {
contentId = this.action.params?.contentID
... ... @@ -56,8 +59,8 @@ export struct ImageAndTextWebComponent {
// TODO 对接user信息、登录情况
let h5ReceiveDataExtraBean: H5ReceiveDataExtraBean = {
creatorId: '',
isLogin: '0',
creatorId: creatorId,
isLogin: isLogin,
networkStatus: 1,
loadImageOnlyWifiSwitch: '2',
... ...
... ... @@ -44,7 +44,8 @@ export struct CommentText {
textContent: this.longMessage,
fontSize: this.fontSize,
fontWeight: this.fontWeight,
constraintWidth: (this.screenWidth - padding)
constraintWidth: (this.screenWidth - padding),
wordBreak:WordBreak.BREAK_ALL
})
console.log(`文本宽度为:${this.textWidth}`)
... ... @@ -71,7 +72,8 @@ export struct CommentText {
textContent: string,
fontSize: this.fontSize,
fontWeight: this.fontWeight,
constraintWidth: (this.screenWidth - padding)
constraintWidth: (this.screenWidth - padding),
wordBreak:WordBreak.BREAK_ALL
})
//计算有误差20
... ... @@ -130,6 +132,7 @@ export struct CommentText {
.fontWeight(this.fontWeight)
.fontColor(this.fontColor)
.maxLines(this.lines)
.wordBreak(WordBreak.BREAK_ALL)
// .backgroundColor(Color.Red)
... ...
... ... @@ -15,6 +15,7 @@ export struct ChildCommentComponent {
@State isExpandParent: boolean = false;
@State isOverLines: boolean = false
@State isOverLinesParent: boolean = false
testText:string = "1,因为读书的人\n是低着头向上看的人\n身处一隅,却能放眼世界\n2,因为读书的人\n总是比不读书的人\n活得有趣一点\n3,因为读书的人\n即使平凡,绝不平庸"
build() {
Column() {
... ... @@ -71,7 +72,7 @@ export struct ChildCommentComponent {
})
}
}
.margin({ bottom: '10lpx' })
.margin({ bottom: '5lpx' })
.width('100%')
.height('108lpx')
.padding({ left: '31lpx', right: '31lpx' })
... ... @@ -93,6 +94,7 @@ export struct ChildCommentComponent {
})
}
}.maxLines(5)
.wordBreak(WordBreak.BREAK_ALL)
.textStyle()
}
}.padding({ left: '31lpx', right: '31lpx' })
... ... @@ -138,6 +140,7 @@ export struct ChildCommentComponent {
})
}
}.maxLines(5)
.wordBreak(WordBreak.BREAK_ALL)
.textAlign(TextAlign.Start)
.width('100%')
}
... ... @@ -243,11 +246,13 @@ export struct ChildCommentComponent {
let measureTruncateWidth: number = measure.measureText({
textContent: truncateContent,
fontSize: px2fp(fontSize),
wordBreak:WordBreak.BREAK_ALL
})
if(type === 1){
measureTruncateWidth = measureTruncateWidth + measure.measureText({
textContent: `@${this.data.parentCommentUserName}:`,
fontSize: px2fp(fontSize),
wordBreak:WordBreak.BREAK_ALL
})
}
let clipStr: string = ''
... ... @@ -255,6 +260,7 @@ export struct ChildCommentComponent {
if (measure.measureText({
textContent: clipStr,
fontSize: px2fp(fontSize),
wordBreak:WordBreak.BREAK_ALL
}) >= textWidth * maxLines - measureTruncateWidth) {
if (type === 0) {
this.isOverLines = true
... ...
... ... @@ -2,8 +2,7 @@ import { Action, ContentDTO, Params } from 'wdBean';
import { CommonConstants, ConfigConstants, ScreenType } from 'wdConstant';
import { Logger } from 'wdKit';
import { CompUtils } from '../../utils/CompUtils';
import { WDRouterRule } from 'wdRouter';
import { ProcessUtils } from 'wdRouter';
import { ProcessUtils, WDRouterRule } from 'wdRouter';
const TAG: string = 'CardView';
... ... @@ -24,8 +23,7 @@ export struct CarouselLayout01CardView {
Image(this.item.coverUrl)
.width(CommonConstants.FULL_PARENT)
.height(CommonConstants.FULL_PARENT)
.objectFit(ImageFit.Cover)
// .borderRadius($r("app.float.border_radius_6"))
.objectFit(ImageFit.Cover)// .borderRadius($r("app.float.border_radius_6"))
.alignRules({
top: { anchor: '__container__', align: VerticalAlign.Top },
left: { anchor: '__container__', align: HorizontalAlign.Start }
... ... @@ -435,11 +433,10 @@ export struct PaperSingleColumn999CardView {
.fontSize(12)
.fontColor(Color.Gray)
.margin({ left: 22 })
Image($r('app.media.icon_share'))
Image($r('app.media.icon_forward'))
.width(16)
.height(16)
.margin({ left: 10, right: 22, top: 10, bottom: 10 })
.backgroundColor(Color.Brown)
}.width(CommonConstants.FULL_PARENT)
.justifyContent(FlexAlign.SpaceBetween)
}
... ... @@ -447,7 +444,7 @@ export struct PaperSingleColumn999CardView {
.backgroundColor(Color.White)
.margin({ bottom: 5, left: 12, right: 12 })
.borderRadius(4)
.onClick(()=>{
.onClick(() => {
ProcessUtils.processPage(this.item)
})
}
... ...
import { CommonConstants, ViewType } from 'wdConstant';
import { Logger } from 'wdKit';
import PageViewModel from '../../viewmodel/PageViewModel';
import { EmptyComponent } from '../view/EmptyComponent';
import { EmptyComponent, WDViewDefaultType } from '../view/EmptyComponent';
import { ErrorComponent } from '../view/ErrorComponent';
import PageModel from '../../viewmodel/PageModel';
import { listTouchEvent } from '../../utils/PullDownRefresh';
... ... @@ -31,14 +31,18 @@ export struct PageComponent {
build() {
Column() {
if (this.pageModel.viewType == ViewType.LOADING) {
// LoadingComponent()
this.LoadingLayout()
} else if (this.pageModel.viewType == ViewType.ERROR) {
ErrorComponent()
} else if (this.pageModel.viewType == ViewType.EMPTY) {
EmptyComponent()
} else {
} else if (this.pageModel.viewType == ViewType.LOADED) {
this.ListLayout()
} else if (this.pageModel.viewType == ViewType.EMPTY) {
//缺省页
EmptyComponent({
emptyType: this.pageModel.emptyType,
emptyButton: true,
retry: () => {
this.getData()
}
})
}
}
.width(CommonConstants.FULL_PARENT)
... ... @@ -65,7 +69,6 @@ export struct PageComponent {
this.pageModel.pullDownRefreshText, this.pageModel.pullDownRefreshHeight)
})
}
LazyForEach(this.pageModel.compList, (compDTO: CompDTO, compIndex: number) => {
ListItem() {
Column() {
... ... @@ -124,9 +127,10 @@ export struct PageComponent {
if (this.pageAdvModel.isShowAds) {
if (this.pageAdvModel.pageCornerAdv.matInfo != null) {
// 页面右边挂角
// 广告中心的挂角广告
this.drawPageCornerAdvView(1, 1 == this.pageAdvModel.isRightAdv)
} else if (this.pageAdvModel.pageCornerContentInfo.advert != null) {
// 展现中心的挂角广告业务
this.drawPageCornerAdvView(2, 1 == this.pageAdvModel.isRightAdv)
}
}
... ...
... ... @@ -6,7 +6,6 @@ import { StringUtils } from 'wdKit/Index'
import { CardMediaInfo } from '../cardCommon/CardMediaInfo'
import { ExtraDTO } from 'wdBean/src/main/ets/bean/component/extra/ExtraDTO'
import { WDRouterPage, WDRouterRule } from 'wdRouter/Index'
import { LiveModel } from '../../viewmodel/LiveModel'
@Component
export struct LiveHorizontalReservationComponent {
... ... @@ -20,7 +19,7 @@ export struct LiveHorizontalReservationComponent {
.width(3)
.height(16)
.margin({ right: 4 })
Text(StringUtils.isNotEmpty(this?.compDTO?.objectTitle) ? this?.compDTO?.objectTitle : "直播预")
Text(StringUtils.isNotEmpty(this?.compDTO?.objectTitle) ? this?.compDTO?.objectTitle : "直播预")
.fontSize($r("app.float.font_size_17"))
.fontColor($r("app.color.color_222222"))
.fontWeight(600)
... ... @@ -82,6 +81,7 @@ export struct LiveHorizontalReservationComponent {
})
})
}.listDirection(Axis.Horizontal)
.scrollBar(BarState.Off)
.width(CommonConstants.FULL_WIDTH)
.height(this.compDTO.operDataList.length == 2 ? 180 : 136)
} else if (this.compDTO.operDataList.length) {
... ...
... ... @@ -12,6 +12,7 @@ import {
import router from '@ohos.router';
import inputMethod from '@ohos.inputMethod';
import { MultiPictureDetailViewModel } from '../../viewmodel/MultiPictureDetailViewModel';
import { LikeComponent } from './LikeComponent';
import { HttpUrlUtils } from 'wdNetwork/Index';
import { WDRouterPage, WDRouterRule } from 'wdRouter/Index';
import { PageRepository } from '../../repository/PageRepository';
... ... @@ -29,9 +30,11 @@ const TAG = 'OperRowListView';
@Preview
@Component
export struct OperRowListView {
private contentDetailData: ContentDetailDTO = {} as ContentDetailDTO
// private contentDetailData: ContentDetailDTO = {} as ContentDetailDTO
@Prop contentDetailData: ContentDetailDTO
@State interactData: InteractDataDTO = {} as InteractDataDTO
@State newsStatusOfUser: batchLikeAndCollectResult | undefined = undefined // 点赞、收藏状态
@State likeBean: Record<string, string> = {}
@State operationList: OperationItem[] = [
{
... ... @@ -60,6 +63,20 @@ export struct OperRowListView {
this.getInteractDataStatus()
}
this.queryContentInteractCount()
// 点赞需要数据
// this.data['userName'] = '人民日报网友2kD2xW'
// this.data['contentType'] = '8' //必须
// this.data['title'] = '开创两校交流先河!克罗地亚教育代表团访问同济大学'
// this.data['userHeaderUrl'] = ""
// this.data['channelId'] = "2059" //必须
// this.data['status'] = "1" //必须
this.likeBean['contentId'] = this.contentDetailData.newsId + ''
this.likeBean['userName'] = this.contentDetailData.editorName + ''
this.likeBean['contentType'] = this.contentDetailData.newsType + ''
this.likeBean['title'] = this.contentDetailData.newsTitle + ''
this.likeBean['userHeaderUrl'] = ''
this.likeBean['channelId'] = this.contentDetailData.reLInfo?.channelId + ''
this.likeBean['status'] = ''
}
build() {
... ... @@ -83,7 +100,7 @@ export struct OperRowListView {
.onClick(() => {
router.back();
})
TextInput({placeholder:'说两句...'})
TextInput({placeholder:'说两句11...'})
.placeholderColor('#999999')
.placeholderFont(
{
... ... @@ -112,10 +129,9 @@ export struct OperRowListView {
.width('54.5%')
}
.width('100%')
.height(56)
.height(126)
.backgroundColor(Color.Black)
}
/**
* 组件项
*
... ... @@ -125,7 +141,11 @@ export struct OperRowListView {
buildOperationItem(item: OperationItem, index: number) {
Column() {
if (item.text === '点赞') {
RelativeContainer() {
LikeComponent({
data: this.likeBean
})
/* RelativeContainer() {
Row() {
Image(this.newsStatusOfUser?.likeStatus == '1' ? item.icon_check : item.icon)
.width(24)
... ... @@ -134,6 +154,7 @@ export struct OperRowListView {
.interpolation(ImageInterpolation.High)
.onClick(() => {
this.toggleLikeStatus()
console.log('点赞_111', JSON.stringify(this.contentDetailData))
})
}
.alignRules({
... ... @@ -168,7 +189,7 @@ export struct OperRowListView {
.id(`e_row3_${index}`)
}
}
.id(`e_icon_${index}`)
.id(`e_icon_${index}`)*/
} else if (item.text === '收藏') {
RelativeContainer() {
Row() {
... ...
import { PageInfoDTO } from 'wdBean/Index';
import { AdvRuleBean, CompAdvBean } from 'wdBean/src/main/ets/bean/adv/AdvsRuleBean';
import { DateTimeUtils, SPHelper } from 'wdKit/Index';
import { ArrayList } from '@kit.ArkTS';
import { SpConstants } from 'wdConstant/Index';
/**
* @Description: 处理页面的广告业务
... ... @@ -18,16 +21,11 @@ export default class PageAdModel {
// 1:右边;2:左边 -> 默认右边
pageCornerContentInfo: AdvRuleBean = {} as AdvRuleBean
// 展现中心业务信息
/**
* 解析广告资源
* @param pageInfo
*/
analysisAdvSource(pageInfo: PageInfoDTO): void {
async analysisAdvSource(pageInfo: PageInfoDTO) {
if (pageInfo.hasAdInfo === 1 && pageInfo.cornersAdv != null) {
// 优先展示展现中心广告
... ... @@ -55,12 +53,26 @@ export default class PageAdModel {
} else if (pageInfo.cornersAdv2 != null && pageInfo.cornersAdv2.length > 0) {
// 广告中心-挂角广告信息
let cornersAdv2 = pageInfo.cornersAdv2
// 获取
let showCompAdvBean = cornersAdv2[0]
if (cornersAdv2.length == 0) {
return
}
// 加工处理广告中心的广告数据
let pageCoreAdvArray = this.treatPageInfoAdsData(cornersAdv2);
let advLength = pageCoreAdvArray.length;
let pageId = pageInfo.id.toString();
let a = 0;
if (advLength > 1) {
a = await this.calPageAdvIndex(pageId,advLength)
}
// 获取投放
let showCompAdvBean = pageCoreAdvArray.convertToArray()[a]
if (showCompAdvBean.matInfo == null) {
return
}
this.saveReleaseAdvIndex(pageId, a)
//
let slotInfo = showCompAdvBean.slotInfo;
let postion = slotInfo.position
... ... @@ -76,4 +88,84 @@ export default class PageAdModel {
}
}
/**
* 计算投放广告的序列号
* @param pageId
* @param advLength
* @returns
*/
private async calPageAdvIndex(pageId: string , advLength: number): Promise<number>{
let index = await this.obtainReleaseAdvIndex(pageId);
let a = await index + 1;
if (a >= advLength) {
a = 0;
}
return a;
}
/**
* 获取已投放挂角广告的编号
* @param pageId
* @returns
*/
private async obtainReleaseAdvIndex(pageId: string): Promise<number> {
let index: number = await SPHelper.default.get(SpConstants.APP_PAGE_CORNER_ADV + pageId, -1) as number;
return index;
}
/**
* 存储已经投放广告的编号
* @param pageId
* @param index
*/
private async saveReleaseAdvIndex(pageId: string, index: number) {
await SPHelper.default.save(SpConstants.APP_PAGE_CORNER_ADV + pageId, index)
}
/**
* 删除数据
* @param pageId
*/
private async clearHistoryAdvIndex(pageId: string){
SPHelper.default.deleteSync(SpConstants.APP_PAGE_CORNER_ADV + pageId)
}
private checkPageCornerAdv(pageId: string): Promise<boolean> {
let haveData = SPHelper.default.has(SpConstants.APP_PAGE_CORNER_ADV + pageId)
return haveData
}
/**
* 对广告中心的广告 数据按不同维度加工 筛选出符合的数据
* @param cornersAdv2 页面的广告数据
* @param pageId 所在页面pageid
*/
private treatPageInfoAdsData(cornersAdv2: CompAdvBean[]): ArrayList<CompAdvBean> {
// 按时间维度过滤出广告数据
let compAdsArray: ArrayList<CompAdvBean> = new ArrayList();
let serverTimeLong: number = DateTimeUtils.getTimeStamp();
for (let advBean of cornersAdv2) {
let startLong = advBean.startTime;
let endLong = advBean.endTime;
if (serverTimeLong >= startLong && serverTimeLong <= endLong) {
//符合开始时间和结束时间要求
compAdsArray.add(advBean)
}
}
//按展现优先级维度 数值越小,等级越高
if (compAdsArray.length > 1) {
//B、按展现优先级维度 数值越小,等级越高
compAdsArray.sort((a: CompAdvBean, b: CompAdvBean) => a.displayPriority - b.displayPriority)
}
return compAdsArray;
}
}
\ No newline at end of file
... ...
import { PageDTO, CompDTO, PageInfoDTO, ContentDTO } from 'wdBean';
import { CompStyle, ViewType } from 'wdConstant/Index';
import { CollectionUtils, DateTimeUtils, Logger } from 'wdKit';
import { CollectionUtils, DateTimeUtils, Logger, NetworkUtil } from 'wdKit';
import { closeRefresh } from '../utils/PullDownRefresh';
import PageModel from './PageModel';
import PageViewModel from './PageViewModel';
import { promptAction } from '@kit.ArkUI';
import { AdvRuleBean } from 'wdBean/src/main/ets/bean/adv/AdvsRuleBean';
import PageAdModel from './PageAdvModel';
import { WDViewDefaultType } from '../components/view/EmptyComponent';
const TAG = 'PageHelper';
... ... @@ -14,14 +15,12 @@ const TAG = 'PageHelper';
* 处理返回后的数据
*/
export class PageHelper {
/**
* 刷新数据
*/
async refreshUI(pageModel: PageModel,pageAdvModel:PageAdModel) {
async refreshUI(pageModel: PageModel, pageAdvModel: PageAdModel) {
pageModel.loadStrategy = 2
this.getPageInfo(pageModel,pageAdvModel)
this.getPageInfo(pageModel, pageAdvModel)
}
/**
... ... @@ -36,28 +35,36 @@ export class PageHelper {
/**
* 进页面请求数据
*/
async getInitData(pageModel: PageModel,pageAdvModel:PageAdModel) {
async getInitData(pageModel: PageModel, pageAdvModel: PageAdModel) {
pageModel.loadStrategy = 1
this.getPageInfo(pageModel,pageAdvModel)
let netStatus = NetworkUtil.isNetConnected()
if (netStatus) {
this.getPageInfo(pageModel, pageAdvModel)
} else {
pageModel.viewType = ViewType.EMPTY;
pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_NoNetwork;
}
}
async getPageInfo(pageModel: PageModel,pageAdvModel:PageAdModel) {
getPageInfo(pageModel: PageModel, pageAdvModel: PageAdModel) {
pageModel.currentPage = 1;
let pageInfo = await PageViewModel.getPageInfo(pageModel.pageId);
PageViewModel.getPageInfo(pageModel.pageId).then(pageInfo => {
if (pageInfo == null) {
pageModel.viewType = ViewType.EMPTY;
pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_NoListContent;
return;
}
pageModel.pageInfo = pageInfo;
//解析广告资源
pageAdvModel.analysisAdvSource(pageInfo)
pageAdvModel.analysisAdvSource(pageInfo);
this.parseGroup(pageModel)
}).catch(() => {
pageModel.viewType = ViewType.EMPTY;
pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_ContentFailed;
})
}
async parseGroup(pageModel: PageModel) {
let pageInfo: PageInfoDTO = pageModel.pageInfo
pageModel.groupList = []
... ... @@ -84,6 +91,8 @@ export class PageHelper {
// 没数据,展示空页面
Logger.debug(TAG, 'aboutToAppear, data response page ' + pageModel.pageId + ', comp list is empty.');
pageModel.viewType = ViewType.EMPTY;
pageModel.emptyType = WDViewDefaultType.WDViewDefaultType_NoListContent;
}
}
... ...
... ... @@ -5,6 +5,7 @@ import { RefreshConstants as Const } from '../utils/RefreshConstants';
import { PageUIReqBean } from '../components/page/bean/PageUIReqBean';
import { GroupInfoDTO, PageInfoDTO } from 'wdBean/src/main/ets/bean/navigation/PageInfoDTO';
import { AdvRuleBean, CompAdvBean } from 'wdBean/src/main/ets/bean/adv/AdvsRuleBean';
import { WDViewDefaultType } from '../components/view/EmptyComponent';
/**
* 页面下拉刷新、上拉加载数据bean。
... ... @@ -38,6 +39,7 @@ export default class PageModel {
isVisiblePullUpLoad: boolean = false;
offsetY: number = 0;
viewType: number = ViewType.LOADING;
emptyType: WDViewDefaultType = WDViewDefaultType.WDViewDefaultType_Default
hasMore: boolean = true;
startIndex = 0;
endIndex = 0;
... ... @@ -51,12 +53,6 @@ export default class PageModel {
// keyGenerator相关字符串,用于刷新list布局
timestamp: String = '1';
// //左右挂角广告对象
// pageCornerAdv:CompAdvBean = {} as CompAdvBean // 挂角广告
// isShowAds : boolean = false;
// isRightAdv : number = 1;// 1:右边;2:左边 -> 默认右边
// pageCornerContentInfo:AdvRuleBean = {} as AdvRuleBean // 展现中心业务信息
/**
* 简单复制业务数据
... ...
... ... @@ -26,7 +26,7 @@ export struct TabChatComponent {
} else if (this.pageModel.viewType == ViewType.ERROR) {
ErrorComponent()
} else if (this.pageModel.viewType == ViewType.EMPTY) {
EmptyComponent({ emptyType: WDViewDefaultType.WDViewDefaultType_NoContent1 })
EmptyComponent({ emptyType: WDViewDefaultType.WDViewDefaultType_NoComment1 })
} else {
this.ListLayout()
}
... ...
... ... @@ -107,7 +107,6 @@ export struct TabLiveItemComponent {
.listDirection(Axis.Horizontal)
.margin({
top: 8,
right: 16
})
}
//音频
... ... @@ -147,14 +146,12 @@ export struct TabLiveItemComponent {
}
.margin({
top: 8,
right: 16
})
.aspectRatio(Number.parseFloat(this.item.pictureResolutions[0]?.split('*')[0]) / Number.parseFloat(this.item.pictureResolutions[0]?.split('*')[1]))
.onClick(() => {
this.gotoVideoPlayPage()
})
}
}
.margin({
left: 8,
... ...
... ... @@ -75,7 +75,7 @@ export struct PlayUIComponent {
if (this.liveDetailsBean.liveInfo?.liveState != 'wait') {
Text(this.liveDetailsBean.newsTitle)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.textOverflow({ overflow: TextOverflow.MARQUEE })
.fontSize('16fp')
.fontWeight(500)
.fontColor(Color.White)
... ... @@ -269,8 +269,7 @@ export struct PlayUIComponent {
.blockSize({
width: 18,
height: 12
})
// .blockStyle({
})// .blockStyle({
// type: SliderBlockType.IMAGE,
// image: $r('app.media.ic_player_block')
// })
... ...
... ... @@ -14,7 +14,7 @@ import { SpConstants } from 'wdConstant/Index'
const TAG = 'PlayerRightView';
//视频点播页右侧操作栏:点赞/收藏/评论/分享 竖着排列
@Component
export struct PlayerRightView {
private playerController?: WDPlayerController;
... ...
... ... @@ -11,7 +11,3 @@ export { PlayerConstants } from "./src/main/ets/constants/PlayerConstants"
export { SpeedBean } from "./src/main/ets/bean/SpeedBean"
export { DateFormatUtil } from "./src/main/ets/utils/DateFormatUtil"
export { WDAliPlayerController } from "./src/main/ets/controller/WDAliPlayerController"
export { WDListPlayerData, WDAliListPlayerController } from "./src/main/ets/controller/WDAliListPlayerController"
\ No newline at end of file
... ...
... ... @@ -7,7 +7,6 @@
"main": "Index.ets",
"version": "1.0.0",
"dependencies": {
"wdKit": "file:../../commons/wdKit",
"premierlibrary": "file:./libs/premierlibrary.har"
"wdKit": "file:../../commons/wdKit"
}
}
... ...
... ... @@ -5,8 +5,6 @@ export class PlayerConstants {
static readonly STATUS_START: number = 1;
static readonly STATUS_PAUSE: number = 2;
static readonly STATUS_STOP: number = 3;
static readonly STATUS_ERROR: number = 4;
static readonly STATUS_COMPLETION: number = 5;
static readonly OPERATE_STATE: Array<string> = ['prepared','playing', 'paused', 'completed'];
... ...
import { AliPlayerFactory, AliPlayer, InfoBean, UrlSource, ErrorInfo, InfoCode } from 'premierlibrary';
import {
idle,
initalized,
prepared,
started,
paused,
stopped,
completion,
error} from 'premierlibrary/src/main/ets/com/aliyun/player/IPlayer';
import { AliListPlayer } from 'premierlibrary/src/main/ets/com/aliyun/player/AliListPlayer'
import { initGlobalPlayerSettings, setupPlayerConfig } from '../utils/GlobalSetting';
import prompt from '@ohos.promptAction';
import { Logger } from '../utils/Logger';
import { PlayerConstants, AVPlayerStatus, Events } from '../constants/PlayerConstants';
export interface WDListPlayerData {
uid: string
url: string
surfaceId?: string
}
/*
* 此播放器为阿里播放器鸿蒙版本封装,可播放单个视频、列表多个视频
* 列表上下滑场景用:WDAliListPlayerController
*
* 阿里文档链接:https://help.aliyun.com/zh/apsara-video-sdk/developer-reference/integrated-hongmeng-harmonyos-next-framework-player-sdk
*/
@Observed
export class WDAliListPlayerController {
private initPromise: Promise<void>;
private avPlayer?: AliListPlayer;
// 内部播放器状态
private avPlayerStatus: number = idle
private duration: number = 0;
private status: number = PlayerConstants.STATUS_IDLE;
private loop: boolean = false;
private url: string = '';
private surfaceId: string = '';
private playSpeed: number = 1;
private seekTime: number = 0;
private positionY: number = 0;
private startTime: number = 0
public errorCode?: number
public errorMesage?: string
public onVideoSizeChange?: (width: number, height: number) => void;
public onBufferUpdate?: (buffered: number, duration: number) => void;
public onTimeUpdate?: (position: number, duration: number) => void;
public onVolumeUpdate?: (volume: number) => void;
// 播放完成,决定是否继续播放回调
public continue?: () => void;
// 准备完成,决定是否播放回调。如果不实现,则自动播放
public onCanplay?: () => void;
public onStatusChange?: (status: number) => void;
public onFirstFrameDisplay?: () => void
//// ------------ 以下为列表播放器属性
private playSources: WDListPlayerData[] = []
private currentPlayRecord?: WDListPlayerData
constructor() {
Logger.info("初始化")
initGlobalPlayerSettings()
this.initPromise = this.createAVPlayer();
}
/**
* 创建 videoPlayer对象
*/
private createAVPlayer(): Promise<void> {
return new Promise((resolve, reject) => {
Logger.debug("开始创建")
let traceId = ''
this.avPlayer = AliPlayerFactory.createAliListPlayer(getContext(), traceId)
if (this.avPlayer) {
Logger.debug("创建完成1")
setupPlayerConfig(this.avPlayer!)
this.bindState();
resolve();
} else {
Logger.error("创建完成0")
Logger.error('[WDPlayerController] createAvPlayer fail!');
reject();
}
});
}
public destory() {
Logger.debug("播放器销毁")
this.avPlayer?.stop()
this.avPlayer?.release()
this.playSources = []
this.currentPlayRecord = undefined
}
/**
* AliPlayer 绑定事件.
*/
private bindState() {
this.avPlayer?.setOnPreparedListener({
// 当调用play()方法后,会调用
onPrepared: () => {
this.duration = this.avPlayer?.getDuration();
Logger.debug("已准备好", `${this.duration}`)
}
}
);
this.avPlayer?.setOnRenderingStartListener({
onRenderingStart: () => {
Logger.debug("首帧开始显示")
if (this.onFirstFrameDisplay) {
this.onFirstFrameDisplay()
}
}
});
this.avPlayer?.setOnCompletionListener({
onCompletion: () => {
Logger.debug("播放完成")
}
});
this.avPlayer?.setOnInfoListener({
onInfo: (bean: InfoBean) => {
if (bean.getCode() === InfoCode.CurrentPosition) {
let position : number = bean.getExtraValue()
Logger.debug(`播放进度条:${position}/ ${this.duration}`)
this.initProgress(position);
} else if (bean.getCode() === InfoCode.BufferedPosition) {
let buffer : number = bean.getExtraValue()
if (this.onBufferUpdate) {
this.onBufferUpdate(buffer, this.duration)
}
} else if (bean.getCode() === InfoCode.SwitchToSoftwareVideoDecoder) {
Logger.debug(`DOWNGRADE TO SOFTWARE DECODE`)
// this.mSwitchedToSoftListener?.onSwitched();
}
}
});
this.avPlayer?.setOnStateChangedListener({
onStateChanged: (status: number) => {
this.avPlayerStatus = status
Logger.debug("status update:" + `${this.getStatusStringWith(status)}`)
switch (status) {
case initalized: {
//this.avPlayer?.prepare();
} break
case prepared: {
if (this.startTime) {
this.setSeekTime(this.startTime, SliderChangeMode.Begin);
}
this.duration = this.avPlayer?.getDuration();
if (this.onVideoSizeChange) {
this.onVideoSizeChange(this.avPlayer?.getVideoWidth(), this.avPlayer?.getVideoHeight());
}
if (this.onCanplay) {
this.onCanplay()
} else {
this.play()
}
} break
case started: {
this.setBright();
this.status = PlayerConstants.STATUS_START;
this.watchStatus();
} break
case paused: {
this.status = PlayerConstants.STATUS_PAUSE;
this.watchStatus();
} break
case stopped: {
this.status = PlayerConstants.STATUS_STOP;
this.watchStatus();
} break
case completion: {
this.status = PlayerConstants.STATUS_COMPLETION;
this.watchStatus();
if (this.continue) {
this.continue();
} else {
//TODO:
//this.duration = 0;
//this.url = this.avPlayer.url || '';
//this.avPlayer.reset();
}
} break
case error: {
// 这里拿不到错误信息
// this.status = PlayerConstants.STATUS_ERROR;
// this.watchStatus();
}
}
}
});
this.avPlayer?.setOnErrorListener({
onError:(errorInfo) => {
Logger.error("播放错误", JSON.stringify(errorInfo))
this.errorCode = errorInfo.getCode()
this.errorMesage = errorInfo.getMsg()
this.status = PlayerConstants.STATUS_ERROR;
this.watchStatus();
}
});
this.avPlayer?.setOnLoadingStatusListener({
onLoadingBegin: () => {
// Logger.error("开始加载。。。")
},
onLoadingProgress: (percent: number, netSpeed: number) => {
// this.loadingProgress = percent;
// this.loadingSpeed = netSpeed;
},
onLoadingEnd: () => {
// Logger.error("结束加载")
// this.showLoadingScene = false;
// this.loadingProgress = 0;
// this.loadingSpeed = 0;
}
});
this.avPlayer?.setOnSeekCompleteListener({
onSeekComplete: () => {
this.initProgress(this.avPlayer?.getCurrentPosition());
}
})
}
private getStatusStringWith(status: number) : string {
switch (status) {
case idle: return 'idle'
case initalized: return 'initalized'
case prepared: return 'prepared'
case started: return 'started'
case paused: return 'paused'
case stopped: return 'stopped'
case completion: return 'completion'
case error: return 'error'
}
return 'unknow'
}
public setXComponentController(controller: XComponentController) {
this.setSurfaceId(controller.getXComponentSurfaceId())
}
public setSurfaceId(surfaceId: string) {
this.surfaceId = surfaceId
}
public async addSources(sources: WDListPlayerData[]) {
if (this.avPlayer == null) {
Logger.info("等待播放器初始化")
await this.initPromise;
}
if (this.avPlayer == null) {
return
}
/// 追加数据源
this.playSources.splice(this.playSources.length, 0, ...sources)
sources.map(data => {
this.avPlayer?.addUrl(data.url, data.uid)
})
}
public moveTo(uid: string, surfaceId: string) {
let uidDatas = this.playSources.filter(data => data.uid === uid)
if (uidDatas.length == 0) {
Logger.info("请先addSources()添加数据源url" + uid)
return
}
this.currentPlayRecord = uidDatas[0]
this.avPlayer?.setSurfaceId(surfaceId)
// this.setAliPlayerURL(this.currentPlayRecord.url)
let result = this.avPlayer?.moveTo(uid)
Logger.info("moveTo" + uid + ` result:${result}`)
this.avPlayer?.prepare()
}
private setAliPlayerURL(url: string) {
let urlSource : UrlSource = new UrlSource()
urlSource.setUri(url)
this.avPlayer?.setUrlDataSource(urlSource)
}
private release() {
if (this.avPlayer == null) {
return
}
this.avPlayer.release()
this.avPlayer = undefined
}
public pause() {
Logger.debug("暂停", this.url)
this.avPlayer?.pause();
}
public play() {
Logger.debug("播放", this.url)
this.avPlayer?.start();
}
public stop() {
Logger.debug("停止", this.url)
this.avPlayer?.stop();
}
public setLoop(loop: boolean) {
this.loop = loop;
this.avPlayer?.setLoop(loop);
}
public setMute(mute: boolean) {
this.avPlayer?.setMute(mute)
}
public setSpeed(playSpeed: number) {
this.playSpeed = playSpeed;
this.avPlayer?.setSpeed(this.playSpeed);
}
public switchPlayOrPause() {
if (this.avPlayerStatus == started) {
this.avPlayer?.pause();
} else if (this.avPlayerStatus == completion) {
this.avPlayer?.seekTo(0, 0)
this.avPlayer?.start()
} else {
this.avPlayer?.start();
}
}
public setSeekTime(value: number, mode: SliderChangeMode) {
// if (this.avPlayer == null) {
// await this.initPromise;
// }
// if (this.avPlayer == null) {
// return
// }
// if (mode == SliderChangeMode.Begin) {
// this.seekTime = value * 1000;
// this.avPlayer?.seek(this.seekTime, media.SeekMode.SEEK_PREV_SYNC);
// }
if (mode === SliderChangeMode.Moving) {
// this.progressThis.progressVal = value;
// this.progressThis.currentTime = DateFormatUtil.secondToTime(Math.floor(value * this.duration /
// 100 / 1000));
}
if (mode === SliderChangeMode.End) {
this.seekTime = Math.floor(value * this.duration / 100);
this.avPlayer?.seekTo(this.seekTime, 0);
}
}
public setBright() {
// globalThis.windowClass.setWindowBrightness(this.playerThis.bright)
}
public getStatus() {
return this.status;
}
public getPlayer() {
return this.avPlayer != undefined
}
initProgress(time: number) {
if (this.onTimeUpdate) {
this.onTimeUpdate(time, this.duration);
}
}
resetProgress() {
this.seekTime = 0;
this.duration = 0;
}
onVolumeActionStart(event: GestureEvent) {
this.positionY = event.offsetY;
}
onBrightActionStart(event: GestureEvent) {
this.positionY = event.offsetY;
}
volume: number = 1
onVolumeActionUpdate(event: GestureEvent) {
if (!this.avPlayer) {
return
}
if (this.avPlayerStatus != prepared &&
this.avPlayerStatus != started &&
this.avPlayerStatus != paused &&
this.avPlayerStatus != completion) {
return;
}
let changeVolume = (event.offsetY - this.positionY) / 300;
let currentVolume = this.volume - changeVolume;
if (currentVolume > 1) {
currentVolume = 1;
}
if (currentVolume <= 0) {
currentVolume = 0;
}
this.volume = currentVolume;
this.avPlayer?.setVolume(this.volume);
this.positionY = event.offsetY;
if (this.onVolumeUpdate) {
this.onVolumeUpdate(this.volume);
}
console.log("volume : " + this.volume)
}
onBrightActionUpdate(event: GestureEvent) {
// if (!this.playerThis.volumeShow) {
// this.playerThis.brightShow = true;
// let changeBright = (this.positionY - event.offsetY) / globalThis.screenHeight;
// let currentBright = this.playerThis.bright + changeBright;
// let brightMinFlag = currentBright <= 0;
// let brightMaxFlag = currentBright > 1;
// this.playerThis.bright = brightMinFlag ? 0 :
// (brightMaxFlag ? 1 : currentBright);
// this.setBright();
// this.positionY = event.offsetY;
// }
}
onActionEnd() {
setTimeout(() => {
this.positionY = 0;
}, 200);
}
watchStatus() {
console.log('watchStatus', this.status)
if (this.onStatusChange) {
this.onStatusChange(this.status)
}
// if (this.status === PlayConstants.STATUS_START) {
// globalThis.windowClass.setWindowKeepScreenOn(true);
// } else {
// globalThis.windowClass.setWindowKeepScreenOn(false);
// }
}
playError(msg?: string) {
prompt.showToast({
duration: 3000,
message: msg ? msg : "请检查地址输入正确且网络正常"
});
}
setStartTime(time?: number) {
this.startTime = time ?? 0;
}
}
\ No newline at end of file
import { AliPlayerFactory, AliPlayer, InfoBean, UrlSource, ErrorInfo, InfoCode } from 'premierlibrary';
import {
idle,
initalized,
prepared,
started,
paused,
stopped,
completion,
error} from 'premierlibrary/src/main/ets/com/aliyun/player/IPlayer';
import { initGlobalPlayerSettings, setupPlayerConfig } from '../utils/GlobalSetting';
import prompt from '@ohos.promptAction';
import { Logger } from '../utils/Logger';
import { PlayerConstants, AVPlayerStatus, Events } from '../constants/PlayerConstants';
/*
* 此播放器为阿里播放器鸿蒙版本封装,可播放单个视频、或直播
* 列表上下滑场景用:WDListPlayerController
*
* 阿里文档链接:https://help.aliyun.com/zh/apsara-video-sdk/developer-reference/integrated-hongmeng-harmonyos-next-framework-player-sdk
*/
@Observed
export class WDAliPlayerController {
private initPromise: Promise<void>;
private avPlayer?: AliPlayer;
// 内部播放器状态
private avPlayerStatus: number = idle
private duration: number = 0;
private status: number = PlayerConstants.STATUS_IDLE;
private loop: boolean = false;
private url: string = '';
private surfaceId: string = '';
private playSpeed: number = 1;
private seekTime: number = 0;
private positionY: number = 0;
private startTime: number = 0
public errorCode?: number
public errorMesage?: string
public onVideoSizeChange?: (width: number, height: number) => void;
public onBufferUpdate?: (buffered: number, duration: number) => void;
public onTimeUpdate?: (position: number, duration: number) => void;
public onVolumeUpdate?: (volume: number) => void;
// 播放完成,决定是否继续播放回调
public continue?: () => void;
// 准备完成,决定是否播放回调。如果不实现,则自动播放
public onCanplay?: () => void;
public onStatusChange?: (status: number) => void;
public onFirstFrameDisplay?: () => void
constructor() {
Logger.info("初始化")
initGlobalPlayerSettings()
this.initPromise = this.createAVPlayer();
}
/**
* 创建 videoPlayer对象
*/
private createAVPlayer(): Promise<void> {
return new Promise((resolve, reject) => {
Logger.debug("开始创建")
let traceId = ''
this.avPlayer = AliPlayerFactory.createAliPlayer(getContext(), traceId)
if (this.avPlayer) {
Logger.debug("创建完成1")
setupPlayerConfig(this.avPlayer!)
this.bindState();
resolve();
} else {
Logger.error("创建完成0")
Logger.error('[WDPlayerController] createAvPlayer fail!');
reject();
}
});
}
public destory() {
Logger.debug("播放器销毁")
this.avPlayer?.stop()
this.avPlayer?.release()
}
/**
* AliPlayer 绑定事件.
*/
private bindState() {
this.avPlayer?.setOnPreparedListener({
// 当调用play()方法后,会调用
onPrepared: () => {
this.duration = this.avPlayer?.getDuration();
Logger.debug("已准备好", `${this.duration}`)
}
}
);
this.avPlayer?.setOnRenderingStartListener({
onRenderingStart: () => {
Logger.debug("首帧开始显示")
if (this.onFirstFrameDisplay) {
this.onFirstFrameDisplay()
}
}
});
this.avPlayer?.setOnCompletionListener({
onCompletion: () => {
Logger.debug("播放完成")
}
});
this.avPlayer?.setOnInfoListener({
onInfo: (bean: InfoBean) => {
if (bean.getCode() === InfoCode.CurrentPosition) {
let position : number = bean.getExtraValue()
Logger.debug(`播放进度条:${position}/ ${this.duration}`)
this.initProgress(position);
} else if (bean.getCode() === InfoCode.BufferedPosition) {
let buffer : number = bean.getExtraValue()
if (this.onBufferUpdate) {
this.onBufferUpdate(buffer, this.duration)
}
} else if (bean.getCode() === InfoCode.SwitchToSoftwareVideoDecoder) {
Logger.debug(`DOWNGRADE TO SOFTWARE DECODE`)
// this.mSwitchedToSoftListener?.onSwitched();
}
}
});
this.avPlayer?.setOnStateChangedListener({
onStateChanged: (status: number) => {
this.avPlayerStatus = status
Logger.debug("status update:" + `${this.getStatusStringWith(status)}`)
switch (status) {
case initalized: {
//this.avPlayer?.prepare();
} break
case prepared: {
if (this.startTime) {
this.setSeekTime(this.startTime, SliderChangeMode.Begin);
}
this.duration = this.avPlayer?.getDuration();
if (this.onVideoSizeChange) {
this.onVideoSizeChange(this.avPlayer?.getVideoWidth(), this.avPlayer?.getVideoHeight());
}
if (this.onCanplay) {
this.onCanplay()
} else {
this.play()
}
} break
case started: {
this.setBright();
this.status = PlayerConstants.STATUS_START;
this.watchStatus();
} break
case paused: {
this.status = PlayerConstants.STATUS_PAUSE;
this.watchStatus();
} break
case stopped: {
this.status = PlayerConstants.STATUS_STOP;
this.watchStatus();
} break
case completion: {
this.status = PlayerConstants.STATUS_COMPLETION;
this.watchStatus();
if (this.continue) {
this.continue();
} else {
//TODO:
//this.duration = 0;
//this.url = this.avPlayer.url || '';
//this.avPlayer.reset();
}
} break
case error: {
// 这里拿不到错误信息
// this.status = PlayerConstants.STATUS_ERROR;
// this.watchStatus();
}
}
}
});
this.avPlayer?.setOnErrorListener({
onError:(errorInfo) => {
Logger.error("播放错误", JSON.stringify(errorInfo))
this.errorCode = errorInfo.getCode()
this.errorMesage = errorInfo.getMsg()
this.status = PlayerConstants.STATUS_ERROR;
this.watchStatus();
}
});
this.avPlayer?.setOnLoadingStatusListener({
onLoadingBegin: () => {
// Logger.error("开始加载。。。")
},
onLoadingProgress: (percent: number, netSpeed: number) => {
// this.loadingProgress = percent;
// this.loadingSpeed = netSpeed;
},
onLoadingEnd: () => {
// Logger.error("结束加载")
// this.showLoadingScene = false;
// this.loadingProgress = 0;
// this.loadingSpeed = 0;
}
});
this.avPlayer?.setOnSeekCompleteListener({
onSeekComplete: () => {
this.initProgress(this.avPlayer?.getCurrentPosition());
}
})
}
private setAliPlayerURL(url: string) {
let urlSource : UrlSource = new UrlSource()
urlSource.setUri(url)
this.avPlayer?.setUrlDataSource(urlSource)
}
private getStatusStringWith(status: number) : string {
switch (status) {
case idle: return 'idle'
case initalized: return 'initalized'
case prepared: return 'prepared'
case started: return 'started'
case paused: return 'paused'
case stopped: return 'stopped'
case completion: return 'completion'
case error: return 'error'
}
return 'unknow'
}
setXComponentController(controller: XComponentController) {
this.setSurfaceId(controller.getXComponentSurfaceId())
}
setSurfaceId(surfaceId: string) {
this.surfaceId = surfaceId
}
async firstPlay(url: string) {
this.url = url;
if (this.avPlayer == null) {
Logger.info("等待播放器初始化")
await this.initPromise;
} else {
if (this.avPlayerStatus != idle) {
this.destory()
this.initPromise = this.createAVPlayer();
await this.initPromise;
}
}
if (this.avPlayer == null) {
return
}
this.duration = 0
this.errorCode = undefined
this.errorMesage = undefined
this.avPlayerStatus = idle
this.status = PlayerConstants.STATUS_IDLE
this.avPlayer?.setAutoPlay(false)
Logger.debug("开始播放", this.url)
this.setAliPlayerURL(this.url);
Logger.info("设置SurfaceId" + this.surfaceId)
this.avPlayer?.setSurfaceId(this.surfaceId)
this.avPlayer?.prepare()
}
release() {
if (this.avPlayer == null) {
return
}
this.avPlayer.release()
this.avPlayer = undefined
}
pause() {
Logger.debug("暂停", this.url)
this.avPlayer?.pause();
}
play() {
Logger.debug("播放", this.url)
this.avPlayer?.start();
}
stop() {
Logger.debug("停止", this.url)
this.avPlayer?.stop();
}
setLoop(loop: boolean) {
this.loop = loop;
this.avPlayer?.setLoop(loop);
}
setMute(mute: boolean) {
this.avPlayer?.setMute(mute)
}
setSpeed(playSpeed: number) {
this.playSpeed = playSpeed;
this.avPlayer?.setSpeed(this.playSpeed);
}
switchPlayOrPause() {
if (this.avPlayerStatus == started) {
this.avPlayer?.pause();
} else if (this.avPlayerStatus == completion) {
this.avPlayer?.seekTo(0, 0)
this.avPlayer?.start()
} else {
this.avPlayer?.start();
}
}
setSeekTime(value: number, mode: SliderChangeMode) {
// if (this.avPlayer == null) {
// await this.initPromise;
// }
// if (this.avPlayer == null) {
// return
// }
// if (mode == SliderChangeMode.Begin) {
// this.seekTime = value * 1000;
// this.avPlayer?.seek(this.seekTime, media.SeekMode.SEEK_PREV_SYNC);
// }
if (mode === SliderChangeMode.Moving) {
// this.progressThis.progressVal = value;
// this.progressThis.currentTime = DateFormatUtil.secondToTime(Math.floor(value * this.duration /
// 100 / 1000));
}
if (mode === SliderChangeMode.End) {
this.seekTime = Math.floor(value * this.duration / 100);
this.avPlayer?.seekTo(this.seekTime, 0);
}
}
setBright() {
// globalThis.windowClass.setWindowBrightness(this.playerThis.bright)
}
getStatus() {
return this.status;
}
getPlayer() {
return this.avPlayer != undefined
}
initProgress(time: number) {
if (this.onTimeUpdate) {
this.onTimeUpdate(time, this.duration);
}
}
resetProgress() {
this.seekTime = 0;
this.duration = 0;
}
onVolumeActionStart(event: GestureEvent) {
this.positionY = event.offsetY;
}
onBrightActionStart(event: GestureEvent) {
this.positionY = event.offsetY;
}
volume: number = 1
onVolumeActionUpdate(event: GestureEvent) {
if (!this.avPlayer) {
return
}
if (this.avPlayerStatus != prepared &&
this.avPlayerStatus != started &&
this.avPlayerStatus != paused &&
this.avPlayerStatus != completion) {
return;
}
let changeVolume = (event.offsetY - this.positionY) / 300;
let currentVolume = this.volume - changeVolume;
if (currentVolume > 1) {
currentVolume = 1;
}
if (currentVolume <= 0) {
currentVolume = 0;
}
this.volume = currentVolume;
this.avPlayer?.setVolume(this.volume);
this.positionY = event.offsetY;
if (this.onVolumeUpdate) {
this.onVolumeUpdate(this.volume);
}
console.log("volume : " + this.volume)
}
onBrightActionUpdate(event: GestureEvent) {
// if (!this.playerThis.volumeShow) {
// this.playerThis.brightShow = true;
// let changeBright = (this.positionY - event.offsetY) / globalThis.screenHeight;
// let currentBright = this.playerThis.bright + changeBright;
// let brightMinFlag = currentBright <= 0;
// let brightMaxFlag = currentBright > 1;
// this.playerThis.bright = brightMinFlag ? 0 :
// (brightMaxFlag ? 1 : currentBright);
// this.setBright();
// this.positionY = event.offsetY;
// }
}
onActionEnd() {
setTimeout(() => {
this.positionY = 0;
}, 200);
}
watchStatus() {
console.log('watchStatus', this.status)
if (this.onStatusChange) {
this.onStatusChange(this.status)
}
// if (this.status === PlayConstants.STATUS_START) {
// globalThis.windowClass.setWindowKeepScreenOn(true);
// } else {
// globalThis.windowClass.setWindowKeepScreenOn(false);
// }
}
playError(msg?: string) {
prompt.showToast({
duration: 3000,
message: msg ? msg : "请检查地址输入正确且网络正常"
});
}
setStartTime(time?: number) {
this.startTime = time ?? 0;
}
}
\ No newline at end of file
... ... @@ -134,10 +134,6 @@ export class WDPlayerController {
this.surfaceId = controller.getXComponentSurfaceId()
}
setSurfaceId(surfaceId: string) {
this.surfaceId = surfaceId
}
async firstPlay(url: string) {
this.url = url;
if (this.avPlayer == null) {
... ...
... ... @@ -2,7 +2,6 @@ import componentUtils from '@ohos.arkui.componentUtils';
import { WDPlayerController } from '../controller/WDPlayerController'
import { WindowModel } from 'wdKit';
import { Logger } from '../utils/Logger';
import { enableAliPlayer } from '../utils/GlobalSetting';
class Size {
width: Length = "100%";
... ... @@ -75,9 +74,8 @@ export struct WDPlayerRenderLiveView {
Row() {
// 设置为“surface“类型时XComponent组件可以和其他组件一起进行布局和渲染。
XComponent({
id: enableAliPlayer ? this.insId : 'xComponentId',
type: XComponentType.SURFACE,
libraryname: enableAliPlayer ? "premierlibrary" : undefined,
id: 'xComponentId',
type: 'surface',
controller: this.xComponentController
})
.onLoad(async (event) => {
... ... @@ -89,11 +87,7 @@ export struct WDPlayerRenderLiveView {
surfaceWidth: 1920,
surfaceHeight: 720
});
if (enableAliPlayer) {
this.playerController?.setSurfaceId(this.insId)
} else {
this.playerController?.setXComponentController(this.xComponentController)
}
if (this.onLoad) {
this.onLoad(event)
}
... ...
... ... @@ -2,7 +2,6 @@ import componentUtils from '@ohos.arkui.componentUtils';
import { WDPlayerController } from '../controller/WDPlayerController'
import { WindowModel } from 'wdKit';
import { Logger } from '../utils/Logger';
import { enableAliPlayer } from '../utils/GlobalSetting';
class Size {
width: Length = "100%";
... ... @@ -74,9 +73,8 @@ export struct WDPlayerRenderVLiveView {
Row() {
// 设置为“surface“类型时XComponent组件可以和其他组件一起进行布局和渲染。
XComponent({
id: enableAliPlayer ? this.insId : 'xComponentId',
type: XComponentType.SURFACE,
libraryname: enableAliPlayer ? "premierlibrary" : undefined,
id: 'xComponentId',
type: 'surface',
controller: this.xComponentController
})
.onLoad(async (event) => {
... ... @@ -86,11 +84,7 @@ export struct WDPlayerRenderVLiveView {
surfaceWidth: 1920,
surfaceHeight: 1080
});
if (enableAliPlayer) {
this.playerController?.setSurfaceId(this.insId)
} else {
this.playerController?.setXComponentController(this.xComponentController)
}
if (this.onLoad) {
this.onLoad(event)
}
... ...
... ... @@ -2,7 +2,6 @@ import componentUtils from '@ohos.arkui.componentUtils';
import { WDPlayerController } from '../controller/WDPlayerController'
import { WindowModel } from 'wdKit';
import { Logger } from '../utils/Logger';
import { enableAliPlayer } from '../utils/GlobalSetting';
class Size {
width: Length = "100%";
... ... @@ -76,7 +75,6 @@ export struct WDPlayerRenderView {
XComponent({
id: this.insId,
type: XComponentType.SURFACE,
libraryname: enableAliPlayer ? "premierlibrary" : undefined,
controller: this.xComponentController
})
.onLoad(async (event) => {
... ... @@ -85,11 +83,7 @@ export struct WDPlayerRenderView {
surfaceWidth: 1920,
surfaceHeight: 1080
});
if (enableAliPlayer) {
this.playerController?.setSurfaceId(this.insId)
} else {
this.playerController?.setXComponentController(this.xComponentController)
}
if (this.onLoad) {
this.onLoad(event)
}
... ...
import { AliPlayerGlobalSettings, AliPlayer } from 'premierlibrary';
import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';
import { error } from 'premierlibrary/src/main/ets/com/aliyun/player/IPlayer';
import { BusinessError } from '@kit.BasicServicesKit';
let currentContext = getContext() as common.UIAbilityContext
export function initGlobalPlayerSettings(context?: common.UIAbilityContext) {
AliPlayerGlobalSettings.setUseHttp2(true);
let filesDir = (context != undefined ? context : currentContext).filesDir;
let cachePath = filesDir + "/player-cache"
fs.stat(cachePath).catch((error: BusinessError) => {
if (error.code = 13900002) {
fs.mkdirSync(cachePath)
}
})
AliPlayerGlobalSettings.enableLocalCache(true,1 * 1024, cachePath)
AliPlayerGlobalSettings.setCacheFileClearConfig(3 * 24 * 6, 1024, 300)
}
export function setupPlayerConfig(player: AliPlayer) {
let config = player.getConfig()
if (config) {
config.mMaxDelayTime = 500
config.mMaxBufferDuration = 50000
config.mHighBufferDuration = 3000
config.mStartBufferDuration = 50
player.setConfig(config)
}
}
/*
* 开启前注意:
* 1、配置好包名对应的license文件
* 2、页面组件播放器控制器使用WDAliPlayerController
* 3、WDAliListPlayerController 暂时由于SDK问题,不能使用
* 4、
* */
export const enableAliPlayer = false
\ No newline at end of file
... ... @@ -9,23 +9,6 @@
"2in1"
],
"deliveryWithInstall": true,
"pages": "$profile:main_pages",
"metadata": [
{
"name": "com.aliyun.alivc_license.licensekey",
// "value": "MoCTfuQ391Z01mNqG8f8786e23c8a457a8ff8d5faedc1040c"
"value": "KoETnmCmxJ1e1ZXDj0eb2ddb6c81c4cb7b9912df65e6d8eb2"
},
{
"name": "com.aliyun.alivc_license.licensefile",
// "value": "license.crt"
"value": "pre-license.crt"
},
{
"name": "com.aliyun.alivc_license.service_env",
"value": "PreRelease"
}
]
"pages": "$profile:main_pages"
}
}
\ No newline at end of file
... ...
... ... @@ -5,161 +5,10 @@
"lockfileVersion": 3,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@mpaas/compress@^1.0.0": "@mpaas/compress@1.0.0",
"@mpaas/fake-island@^1.0.0": "@mpaas/fake-island@1.0.0",
"@mpaas/framework@0.0.2": "@mpaas/framework@0.0.2",
"@mpaas/framework@^0.0.2": "@mpaas/framework@0.0.2",
"@mpaas/fs-ext@^1.0.0": "@mpaas/fs-ext@1.0.0",
"@mpaas/lang@^1.0.0": "@mpaas/lang@1.0.0",
"@mpaas/path@^1.0.0": "@mpaas/path@1.0.0",
"@mpaas/rpc@^0.0.2": "@mpaas/rpc@0.0.2",
"@mpaas/shuckle@^1.0.0": "@mpaas/shuckle@1.0.0",
"@mpaas/trace-log@^0.0.2": "@mpaas/trace-log@0.0.2",
"@mpaas/transport_build@^0.0.2": "@mpaas/transport_build@0.0.2",
"@mpaas/udid@0.0.2": "@mpaas/udid@0.0.2",
"@mpaas/upgrade@0.0.2": "@mpaas/upgrade@0.0.2",
"@ohos/crypto-js@^2.0.2": "@ohos/crypto-js@2.0.3",
"@ohos/hypium@1.0.16": "@ohos/hypium@1.0.16",
"@ohos/pulltorefresh@^2.0.5": "@ohos/pulltorefresh@2.0.5",
"dayjs@^1.11.7": "dayjs@1.11.7",
"libcompress.so@oh_modules/.ohpm/@mpaas+compress@1.0.0/oh_modules/@mpaas/compress/src/main/cpp/types/libcompress": "libcompress.so@oh_modules/.ohpm/@mpaas+compress@1.0.0/oh_modules/@mpaas/compress/src/main/cpp/types/libcompress",
"libframework_api.so@oh_modules/.ohpm/@mpaas+framework@0.0.2/oh_modules/@mpaas/framework/src/main/cpp/types/libframework_api": "libframework_api.so@oh_modules/.ohpm/@mpaas+framework@0.0.2/oh_modules/@mpaas/framework/src/main/cpp/types/libframework_api",
"libgwcli.so@oh_modules/.ohpm/@mpaas+fake-island@1.0.0/oh_modules/@mpaas/fake-island/types": "libgwcli.so@oh_modules/.ohpm/@mpaas+fake-island@1.0.0/oh_modules/@mpaas/fake-island/types",
"liblang.so@oh_modules/.ohpm/@mpaas+lang@1.0.0/oh_modules/@mpaas/lang/types": "liblang.so@oh_modules/.ohpm/@mpaas+lang@1.0.0/oh_modules/@mpaas/lang/types",
"libmplog.so@oh_modules/.ohpm/@mpaas+trace-log@0.0.2/oh_modules/@mpaas/trace-log/types": "libmplog.so@oh_modules/.ohpm/@mpaas+trace-log@0.0.2/oh_modules/@mpaas/trace-log/types",
"libshuckle.so@oh_modules/.ohpm/@mpaas+shuckle@1.0.0/oh_modules/@mpaas/shuckle/src/main/cpp/types/libshuckle": "libshuckle.so@oh_modules/.ohpm/@mpaas+shuckle@1.0.0/oh_modules/@mpaas/shuckle/src/main/cpp/types/libshuckle",
"long@^5.2.1": "long@5.2.1",
"pako@^2.1.0": "pako@2.1.0"
"@ohos/pulltorefresh@^2.0.5": "@ohos/pulltorefresh@2.0.5"
},
"packages": {
"@mpaas/compress@1.0.0": {
"name": "@mpaas/compress",
"integrity": "sha512-x/aUK/zKjoUnd4kYGNAI1JMcEY2n4N6Rn+F+zcIYs8WLgobY6kFXTphLJ/NlSgjJklc2009U8zeStvtjon1zaQ==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/compress/compress-1.0.0.har",
"registryType": "ohpm",
"dependencies": {
"libcompress.so": "file:./src/main/cpp/types/libcompress"
}
},
"@mpaas/fake-island@1.0.0": {
"name": "@mpaas/fake-island",
"integrity": "sha512-cEt0Zsie0rwfvnYmqA+6pa93L6NLkJKwiqJCoE9Z2hFjhk9s4RSz7F0AUuj4WobrpdElXuipoCNFPXWLb4ZBlA==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/fake-island/fake-island-1.0.0.har",
"registryType": "ohpm",
"dependencies": {
"libgwcli.so": "file:./types"
}
},
"@mpaas/framework@0.0.2": {
"name": "@mpaas/framework",
"integrity": "sha512-nNpCI44zvg4fN9GNM5m31LdqfLrej9mMo/+BMny8QK+/Jvc3m/itE45bWZZ7unfflq40H2t4YOgtNAIW3m8MaA==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/framework/framework-0.0.2.har",
"registryType": "ohpm",
"dependencies": {
"libframework_api.so": "file:./src/main/cpp/types/libframework_api",
"@mpaas/udid": "0.0.2"
}
},
"@mpaas/fs-ext@1.0.0": {
"name": "@mpaas/fs-ext",
"integrity": "sha512-4TGUdrkmVSFktp1NcRdcs4uLYH6GvN1aTkMD2z8TJLztz5Hq5fMrvuznsmwTsSaRxGfGuyHPER8enMQo8wcfKA==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/fs-ext/fs-ext-1.0.0.har",
"registryType": "ohpm",
"dependencies": {
"@mpaas/path": "^1.0.0"
}
},
"@mpaas/lang@1.0.0": {
"name": "@mpaas/lang",
"integrity": "sha512-dcQ2QPrvwZgBhoGUjAbSFfkReDkwqEPMTzy/Xk05dhIB9VVznpLPahlQLVi0Am1FPATCT8J7DDrko9aJLOba+w==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/lang/lang-1.0.0.har",
"registryType": "ohpm",
"dependencies": {
"liblang.so": "file:./types"
}
},
"@mpaas/path@1.0.0": {
"name": "@mpaas/path",
"integrity": "sha512-TNjPaVOiq4DTiNFexSeI9isxeJ1H4q9Vieh3Bnv66o0U/e7rwV1qjEUtMvihX3MlsX0VKVkT0Xyf/wm18l4XYw==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/path/path-1.0.0.har",
"registryType": "ohpm"
},
"@mpaas/rpc@0.0.2": {
"name": "@mpaas/rpc",
"integrity": "sha512-BeiXDHW77CpZF5x4nuQc+3A7MfhFfU3+Wc73gac/ZRhIPuAAzfLmlzm5alqdm6oiWAw17ERQydUSG4SQSCHQ4g==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/rpc/rpc-0.0.2.har",
"registryType": "ohpm",
"dependencies": {
"@mpaas/transport_build": "^0.0.2",
"@mpaas/lang": "^1.0.0",
"@mpaas/framework": "^0.0.2"
}
},
"@mpaas/shuckle@1.0.0": {
"name": "@mpaas/shuckle",
"integrity": "sha512-B0MhrNzwG9pIoPxYVBldyenQWtWfTv5twd/0Ur1LbMpbp09AQ5wrZjKgDoeUtsIls9gzL9T8ngDZU6mRn8SYgQ==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/shuckle/shuckle-1.0.0.har",
"registryType": "ohpm",
"dependencies": {
"libshuckle.so": "file:./src/main/cpp/types/libshuckle",
"@mpaas/framework": "^0.0.2"
}
},
"@mpaas/trace-log@0.0.2": {
"name": "@mpaas/trace-log",
"integrity": "sha512-Llsdnx3L2tJJDg9vwJY01YsK4IOSmCo4SmAIW9yFHTzylrzFSWdFefRhJbNlkQQilXdYygEkBByXVvT1wFSmAg==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/trace-log/trace-log-0.0.2.har",
"registryType": "ohpm",
"dependencies": {
"@mpaas/lang": "^1.0.0",
"@mpaas/fs-ext": "^1.0.0",
"@mpaas/path": "^1.0.0",
"@mpaas/framework": "0.0.2",
"libmplog.so": "file:types",
"dayjs": "^1.11.7"
}
},
"@mpaas/transport_build@0.0.2": {
"name": "@mpaas/transport_build",
"integrity": "sha512-utz9C/cKIWbYrNiTBjk1gUhPH4/M73G64hWlrYKDpkfJHJmdYcQmmYV3v7Jit1z7Qg7hhu0aOaZzShqdQdC7rg==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/transport_build/transport_build-0.0.2.har",
"registryType": "ohpm",
"dependencies": {
"@ohos/crypto-js": "^2.0.2",
"dayjs": "^1.11.7",
"pako": "^2.1.0",
"@mpaas/fake-island": "^1.0.0",
"long": "^5.2.1",
"@mpaas/framework": "^0.0.2",
"@mpaas/shuckle": "^1.0.0",
"@mpaas/compress": "^1.0.0"
}
},
"@mpaas/udid@0.0.2": {
"name": "@mpaas/udid",
"integrity": "sha512-YFLSgBOrIjjmcFm4Cn2BB1tspHKHdB4qipVl4MUhHHDfiUYbLIVuv7x5xB9xPuPf0gKO8rx0yqUuzkaNDoNsAw==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/udid/udid-0.0.2.har",
"registryType": "ohpm"
},
"@mpaas/upgrade@0.0.2": {
"name": "@mpaas/upgrade",
"integrity": "sha512-VWamULIoJPA6nxUADwwNXd3uOspZeYAsRh05pApVilIdum5ktIMXIFl71jAKsChs3jtrhs9y5EShoZD4MZrGsA==",
"resolved": "https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/dist/@mpaas/upgrade/upgrade-0.0.2.har",
"registryType": "ohpm",
"dependencies": {
"@mpaas/framework": "^0.0.2",
"@mpaas/rpc": "^0.0.2",
"@mpaas/lang": "^1.0.0",
"@mpaas/transport_build": "^0.0.2",
"@mpaas/trace-log": "^0.0.2"
}
},
"@ohos/crypto-js@2.0.3": {
"name": "@ohos/crypto-js",
"integrity": "sha512-LuHaR1kD5PxnOXnuR1fWvPwGtbed9Q/QGzk6JOh8y5Wdzvi8brPesODZiaWf9scOVRHsbTPOtZw91vWB35p1vQ==",
"resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/crypto-js/-/crypto-js-2.0.3.har",
"registryType": "ohpm"
},
"@ohos/hypium@1.0.16": {
"name": "@ohos/hypium",
"integrity": "sha512-PC3jpwKERg68V+4dmKU+SLjNps9i5JcQH57rQriaTsh62NBgVZs4SceMmNOtrIOyldbEJ5mXSwoZwiG/nkRmTw==",
... ... @@ -171,60 +20,6 @@
"integrity": "sha512-mgBvJ6Ga70LmAoPKTOEPLFJluHUEAaBt2+7wF7R6223Vw6UEbZrof1MyvVOLEHk8Uc64ASIMW/TNQ8AHraTV5A==",
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/pulltorefresh/-/pulltorefresh-2.0.5.har",
"registryType": "ohpm"
},
"dayjs@1.11.7": {
"name": "dayjs",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==",
"resolved": "https://ohpm.openharmony.cn/ohpm/dayjs/-/dayjs-1.11.7.tgz",
"shasum": "4b296922642f70999544d1144a2c25730fce63e2",
"registryType": "ohpm"
},
"libcompress.so@oh_modules/.ohpm/@mpaas+compress@1.0.0/oh_modules/@mpaas/compress/src/main/cpp/types/libcompress": {
"name": "libcompress.so",
"resolved": "oh_modules/.ohpm/@mpaas+compress@1.0.0/oh_modules/@mpaas/compress/src/main/cpp/types/libcompress",
"registryType": "local"
},
"libframework_api.so@oh_modules/.ohpm/@mpaas+framework@0.0.2/oh_modules/@mpaas/framework/src/main/cpp/types/libframework_api": {
"name": "libframework_api.so",
"resolved": "oh_modules/.ohpm/@mpaas+framework@0.0.2/oh_modules/@mpaas/framework/src/main/cpp/types/libframework_api",
"registryType": "local"
},
"libgwcli.so@oh_modules/.ohpm/@mpaas+fake-island@1.0.0/oh_modules/@mpaas/fake-island/types": {
"name": "libgwcli.so",
"resolved": "oh_modules/.ohpm/@mpaas+fake-island@1.0.0/oh_modules/@mpaas/fake-island/types",
"registryType": "local"
},
"liblang.so@oh_modules/.ohpm/@mpaas+lang@1.0.0/oh_modules/@mpaas/lang/types": {
"name": "liblang.so",
"resolved": "oh_modules/.ohpm/@mpaas+lang@1.0.0/oh_modules/@mpaas/lang/types",
"registryType": "local"
},
"libmplog.so@oh_modules/.ohpm/@mpaas+trace-log@0.0.2/oh_modules/@mpaas/trace-log/types": {
"name": "libmplog.so",
"resolved": "oh_modules/.ohpm/@mpaas+trace-log@0.0.2/oh_modules/@mpaas/trace-log/types",
"registryType": "local"
},
"libshuckle.so@oh_modules/.ohpm/@mpaas+shuckle@1.0.0/oh_modules/@mpaas/shuckle/src/main/cpp/types/libshuckle": {
"name": "lishuckle.so",
"resolved": "oh_modules/.ohpm/@mpaas+shuckle@1.0.0/oh_modules/@mpaas/shuckle/src/main/cpp/types/libshuckle",
"registryType": "local",
"dependencies": {
"@mpaas/framework": "^0.0.2"
}
},
"long@5.2.1": {
"name": "long",
"integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==",
"resolved": "https://ohpm.openharmony.cn/ohpm/long/-/long-5.2.1.tgz",
"shasum": "e27595d0083d103d2fa2c20c7699f8e0c92b897f",
"registryType": "ohpm"
},
"pako@2.1.0": {
"name": "pako",
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
"resolved": "https://ohpm.openharmony.cn/ohpm/pako/-/pako-2.1.0.tgz",
"shasum": "266cc37f98c7d883545d11335c00fbd4062c9a86",
"registryType": "ohpm"
}
}
}
\ No newline at end of file
... ...
... ... @@ -9,10 +9,7 @@
"main": "",
"version": "1.0.0",
"dependencies": {
"@ohos/pulltorefresh": "^2.0.5",
"@mpaas/udid": "0.0.2",
"@mpaas/upgrade": "0.0.2",
"@mpaas/framework": "0.0.2"
"@ohos/pulltorefresh": "^2.0.5"
},
"dynamicDependencies": {}
}
\ No newline at end of file
... ...
@mpaas:registry=https://mpaas-ohpm.oss-cn-hangzhou.aliyuncs.com/meta
\ No newline at end of file
... ... @@ -8,7 +8,6 @@ import {
EmitterEventId,
EmitterUtils,
Logger,
MpaasUtils,
NetworkManager,
NetworkType,
SPHelper,
... ... @@ -21,10 +20,6 @@ export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
SPHelper.init(this.context);
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
// mPaaS 初始化
MpaasUtils.initApp(this.context)
registerRouter();
NetworkManager.getInstance().init()
WDHttp.initHttpHeader()
... ...
import { BottomNavigationComponent, LogoutViewModel } from 'wdComponent';
import { BreakpointConstants } from 'wdConstant';
import { BreakpointSystem, EmitterEventId, EmitterUtils, Logger, MpaasUpgradeCheck } from 'wdKit';
import { BreakpointSystem, EmitterEventId, EmitterUtils, Logger } from 'wdKit';
import router from '@ohos.router';
import { promptAction } from '@kit.ArkUI';
import { HWLocationUtils } from 'wdHwAbility/Index';
import { UpgradeTipDialog } from "./upgradePage/UpgradeTipDialog"
const TAG = 'MainPage';
... ... @@ -16,7 +16,6 @@ struct MainPage {
@Provide pageHide: number = -1
private breakpointSystem: BreakpointSystem = new BreakpointSystem()
@StorageLink('currentBreakpoint') @Watch('watchCurrentBreakpoint') currentBreakpoint: string = BreakpointConstants.BREAKPOINT_XS;
upgradeDialogController?: CustomDialogController
watchCurrentBreakpoint() {
Logger.info(TAG, `watchCurrentBreakpoint, this.currentBreakpoint: ${this.currentBreakpoint}`);
... ... @@ -44,26 +43,6 @@ struct MainPage {
onPageShow() {
Logger.info(TAG, 'onPageShow');
this.pageShow = Math.random()
// TODO: 升级检查,暂时不开放
// this.upgradeCheck()
}
upgradeCheck() {
const mpaas = new MpaasUpgradeCheck()
mpaas.checkNewVersion().then((data) => {
if (data != null) {
this.upgradeDialogController = new CustomDialogController({
builder: UpgradeTipDialog({
tipContent:data
})
})
this.upgradeDialogController?.open()
}
}).catch(() => {
})
}
onBackPress() {
... ...
import { UpgradeTipContent } from 'wdKit/Index'
@Preview
@CustomDialog
export struct UpgradeTipDialog {
private tipContent: UpgradeTipContent = {} as UpgradeTipContent
cancel?: () => void
confirm?: () => void
controller: CustomDialogController
build() {
Column() {
Text(this.tipContent.content).fontSize(20).margin({ top: 10, bottom: 10 })
Flex({ justifyContent: FlexAlign.SpaceAround }) {
Button('cancel')
.onClick(() => {
this.controller.close()
if (this.cancel) {
this.cancel()
}
}).backgroundColor(0xffffff).fontColor(Color.Black)
Button('立即升级')
.onClick(() => {
this.controller.close()
if (this.confirm) {
this.confirm()
}
}).backgroundColor(0xffffff).fontColor(Color.Red)
}.margin({ bottom: 10 })
}
}
}
\ No newline at end of file
{
"absBase64Code":"",
"appId":"PRI2B87143171150",
"appKey":"PRI2B87143171150_HARMONY",
"base64Code":"",
"v6Base64Code":"",
"workspaceId":"default",
"rpcGW":"http://123.56.249.180/mgw.htm",
"mpaasapi":"http://123.56.249.180/mgw.htm",
"pushPort":"",
"pushGW":"",
"logGW":"",
"mvetAppWS":"10.250.12.199"
}
\ No newline at end of file
-----BEGIN ALI VIDEO CERT-----
LmlsQS5jaUwAAWU1MGY1NWU1Y2U1MzIxMDc5MjQ4ZjUzNGQ2ZjVmZmQ2ZmY1MTFmM
WMzZTlmZDU4NjUxNmU4YmI0NmMxNzM0MTU1OTBjYzQyY2Y4NGY4Y2U2MGZmYjMzMG
Q5NTQ1NjFmMGMxNzBjMmUyZGQ5MjYwNjY2YjVlN2Y2YTlhMjZhMzc0YjNhNjExN2N
lYzRlNGYzMGIxODViMmRlOTVhNzU1Nzg2YzY4MzhkYTY1YWI5NTUzMjQyNjRkN2Q0
OGE0OTExZjFkYzM5MzllZGQ2YjE2OThkNjJjMGI3ZmUwNDRkOGMwYTI0ZTgzZTRiM
jUwMTk2MDgwNWFkYzBmMGMwNDU3MDE5ZGI0NDNjYzRiNjc3MjRhMTg5YjAyYmU1YT
E4NDg1ZWQ4NWRmZDQxYzVkZTUzOTUyNmZiOWNiODNjNTE5MWZhMWE4N2E3YjE3M2I
xY2I4NzI2YTFiZDFjZjBkZTNlNzM2ZmU3NmFmMjQyOWRlY2FjNTUzYjdhZmFjNDM1
NTRhNDYwY2RkNWE2NGFmZDg5N2ZmYmVjMWQ3NTc0MDdlOGM2ODBkYzMyYjM1YzU0Z
Dk1N2MyMTk2YjlmYzEwNjA0YTVmZGQ1Yzg0OTE1N2VkZDNiYjk4OTc4YjZjMGY1OD
Q4MDY5MjQzMTQzZmMyZDA1ZGJiNTJjMjVhZjMwMWFjYTNkAAAB1u6ksgCgo8C07iY
q52y6BA6nGYLr+YxZCDTYa0zPm21WZhNlUYE8xR1KKPxoOfhgADCG7FubFonJ5pyD
2+O7g21xWr3CbYQ1S1D/qWE9pYtIoIUl3USIr8pfRQz2/Lk4TUPO/VzgAWeQrbclC
wgz50pvVzVAwGjBQfofHlCMO6iIbgSazoopOZSeDfOULs7dPkIOfjeSm1ZMCpytgh
SKCsd0GwaV+yWn+Uk2DOLafFk2logpRGmQzxcZ/K+vJuedUPHzMSRV8VfXc86wix9
Tx1sokTb9Xt3wqYgbO/5jn2RhOdBYruFUOrFt3LIp1rKj8XngtwI7Cjr7oBAlEXMf
Uk2A1s/+AAABZB0FG6sG6bbq5JZuwpbmlC7QuD/rUW5iJavqQwZbylmgDuHTZKe22
mpbwLrw+3w0j9WAsytGn1C07nnmdjzJGe7oujnqOEgUSId9kkBN898rVMjfMy0ckt
QgBLtxy6nHvgXLbxUzG4rXHccWAwyTGnEfwNl3FRSuB8jGPewQvrV/HyRKMY7MASv
EA2uo6NGxLfkz+YrqKjFywqsBmTACkE7kJzL2MoNJ6hfJkKl92Z1+HvpwJEV7EdwN
Qd7MoB+Jd2gF9YLbnk0h+h+d+aI9tIoM8CksdkHsCLLAONvi7LwwN/RcoytfKts8i
YQ+b5do3+z/ybD/XZVSPswWmuW1BqEAAAGNchb17gAAAFMAAAAgZ2E3ODYwZGNhMT
g1NDQ0MTlhNTMzNzBhYTQ4ZGIzZDEAAAABAAAAJwAAAAAAAABAAAAAG2NvbS5hbGl
5dW4ucGxheWVyLm9ob3NfZGVtbwAAAAEAAAEFAAAAAgAAAAAAAABAAAAj8QAAAZiU
tdAAAQAAAOgAAAABAAAACAAAABgAAE4hAAABjXIW8ngAAAGYlLXQAAAAAAAAAAAYA
ABOIgAAAY1yFvJ4AAABmJS10AAAAAAAAAAAGAAATiMAAAGNchbyeAAAAZiUtdAAAA
AAAAAAABgAAE4kAAABjXIW8ngAAAGYlLXQAAAAAAAAAAAYAABOJQAAAY1yFvJ4AAA
BmJS10AAAAAAAAAAAGAAATiYAAAGNchbyeAAAAZiUtdAAAAAAAAAAABgAAE4nAAAB
jXIW8ngAAAGYlLXQAAAAAAAAAAAYAABOhQAAAY1yFvJ4AAABmJS10AAAAAAA
-----END ALI VIDEO CERT-----
\ No newline at end of file