wangyujian_wd

feat:1)直播详情信息直播间信息获取

2)横屏直播逻辑添加
Showing 25 changed files with 645 additions and 35 deletions
import { StringUtils } from './StringUtils';
import getLunar from './GetLunar'
import getLunar from './GetLunar';
/**
* 日期/时间工具
*/
... ... @@ -480,6 +481,34 @@ export class DateTimeUtils {
return 0
}
}
/**
* 进度值换算
* @param seconds
* @returns
*/
static secondToTime(seconds: number) {
let time = '00:00'
let hourUnit = 60 * 60;
let hour = Math.floor(seconds / hourUnit);
let minute = Math.floor((seconds - hour * hourUnit) / 60);
let second = seconds - hour * hourUnit - minute * 60;
if (hour > 0) {
return `${DateTimeUtils.padding(hour.toString())}${':'}${DateTimeUtils.padding(minute.toString())}${':'}${DateTimeUtils.padding(second.toString())}`;
}
if (minute > 0) {
return `${DateTimeUtils.padding(minute.toString())}${':'}${DateTimeUtils.padding(second.toString())}`;
} else {
return `${'00'}${':'}${DateTimeUtils.padding(second.toString())}`;
}
}
static padding(num: string) {
let length = 2;
for (let len = (num.toString()).length; len < length; len = num.length) {
num = `${'0'}${num}`;
}
return num;
}
}
// const dateTimeUtils = new DateTimeUtils()
\ No newline at end of file
... ...
import HashMap from '@ohos.util.HashMap'
import { ConfigConstants, SpConstants } from 'wdConstant'
import { DateTimeUtils, Logger, SPHelper, StringUtils } from 'wdKit'
import HashMap from '@ohos.util.HashMap';
import { SpConstants } from 'wdConstant';
import { SPHelper, StringUtils } from 'wdKit';
/**
* 网络请求业务侧工具类
... ... @@ -213,6 +213,18 @@ export class HttpUrlUtils {
*/
static readonly LIVE_CHAT_LIST_PATH: string = "/api/live-center-message/zh/a/live/message/chat/list";
/**
* 直播详情-直播数据
*/
static readonly LIVE_ROOM_DATA_PATH: string = "/api/live-center-message/zh/a/live/room/number/all";
/**
* 直播详情-预约直播状态
*/
static readonly LIVE_APPOINTMENT_STATUS_PATH: string = "/api/live-center-message/zh/c/live/subscribe/query";
/**
* 直播详情-预约/取消预约直播
*/
static readonly LIVE_APPOINTMENT_PATH: string = "/api/live-center-message/zh/c/live/subscribe";
/**
* 搜索结果 显示tab 数
*/
... ... @@ -653,6 +665,21 @@ export class HttpUrlUtils {
return url
}
static getLiveRoomDataUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_ROOM_DATA_PATH
return url
}
static getLiveAppointmentStatusUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_APPOINTMENT_STATUS_PATH
return url
}
static getLiveAppointmentUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_APPOINTMENT_PATH
return url
}
static getSearchResultCountDataUrl() {
let url = HttpUrlUtils._hostUrl + HttpUrlUtils.SEARCH_RESULT_COUNT_DATA_PATH
return url
... ...
... ... @@ -120,3 +120,5 @@ export { appStyleImagesDTO } from './src/main/ets/bean/content/appStyleImagesDTO
export { LiveRoomBean,LiveRoomItemBean } from './src/main/ets/bean/live/LiveRoomBean';
export { LiveRoomDataBean } from './src/main/ets/bean/live/LiveRoomDataBean';
... ...
... ... @@ -158,9 +158,12 @@ export interface LiveDetailsBean {
*/
liveInfo: LiveInfo
fullColumnImgUrls: Array<FullColumnImgUrls>
vlive: Array<Vlive>
newsTitle: string
newsId: string
newIntroduction: string
//迁移id
oldNewsId: string
reLInfo: ReLInfo
}
export interface LiveInfo {
... ... @@ -168,6 +171,8 @@ export interface LiveInfo {
liveState: string
//2024-04-12 15:00:00 直播开始时间
planStartTime: string
mliveId:string
vlive: Array<Vlive>
}
export interface FullColumnImgUrls {
... ... @@ -179,4 +184,8 @@ export interface Vlive {
liveUrl: string
//直播回看地址,多路直播录制文件URL
replayUri: string
}
export interface ReLInfo {
relId: string
}
\ No newline at end of file
... ...
export interface LiveRoomDataBean {
barrageNum: number,
likeNum: number,
liveId: number,
pv: number,
subscribeNum: number,
}
\ No newline at end of file
... ...
... ... @@ -12,6 +12,7 @@
"wdNetwork": "file:../../commons/wdNetwork",
"wdKit": "file:../../commons/wdKit",
"wdBean": "file:../../features/wdBean",
"wdConstant": "file:../../commons/wdConstant"
"wdConstant": "file:../../commons/wdConstant",
"wdDetailPlayApi": "file:../../features/wdDetailPlayApi"
}
}
... ...
import { LiveDetailsBean } from 'wdBean/Index';
import { Action, LiveDetailsBean, LiveRoomDataBean } from 'wdBean/Index';
import { LiveViewModel } from '../viewModel/LiveViewModel';
import { BottomComponent } from '../widgets/details/BottomComponent';
import { TabComponent } from '../widgets/details/TabComponent';
import { TopPlayComponent } from '../widgets/details/video/TopPlayComponet';
import router from '@ohos.router';
@Entry
@Component
export struct DetailPlayLivePage {
TAG: string = 'DetailPlayLivePage';
liveViewModel: LiveViewModel = new LiveViewModel()
@State relId: string = ''
@State contentId: string = ''
@State relType: string = ''
@Provide liveDetailsBean: LiveDetailsBean = {} as LiveDetailsBean
@Provide liveRoomDataBean: LiveRoomDataBean = {} as LiveRoomDataBean
aboutToAppear(): void {
let par: Action = router.getParams() as Action;
let params = par?.params;
this.relId = params?.extra?.relId || '';
this.relType = params?.extra?.relType || '';
this.contentId = params?.contentID || '';
this.getLiveDetails()
this.getLiveRoomData()
}
build() {
Column() {
TopPlayComponent({playUrl:'http://mlive3.video.weibocdn.com/record/alicdn/5018726527666338/index.m3u8'})
TopPlayComponent()
TabComponent()
BottomComponent()
}
... ... @@ -30,8 +41,7 @@ export struct DetailPlayLivePage {
}
getLiveDetails() {
this.liveViewModel.getLiveDetails('20000016333', '500005300349', '1')//2024-04-12 15:00:00
// this.liveViewModel.getLiveDetails('20000016229', '500005272745', '1')//2024-04-03 05:00:00
this.liveViewModel.getLiveDetails(this.contentId, this.relId, this.relType)
.then(
(data) => {
if (data.length > 0) {
... ... @@ -43,6 +53,17 @@ export struct DetailPlayLivePage {
})
}
getLiveRoomData() {
this.liveViewModel.getLiveRoomData(this.contentId)
.then(
(data) => {
this.liveRoomDataBean = data
},
() => {
})
}
aboutToDisappear(): void {
}
... ...
import HashMap from '@ohos.util.HashMap';
import { HttpUrlUtils, ResponseDTO } from 'wdNetwork';
import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest';
import { Logger } from 'wdKit';
import { LiveDetailsBean, LiveRoomBean } from 'wdBean/Index';
import { Logger, ToastUtils } from 'wdKit';
import { LiveDetailsBean, LiveRoomBean, LiveRoomDataBean } from 'wdBean/Index';
const TAG = 'LiveModel'
... ... @@ -107,5 +107,91 @@ export class LiveModel {
})
})
}
/**
* 获取直播数据
* @param liveId
* @returns
*/
getLiveRoomData(liveId: string) {
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return new Promise<LiveRoomDataBean>((success, fail) => {
HttpRequest.get<ResponseDTO<LiveRoomDataBean>>(
HttpUrlUtils.getLiveRoomDataUrl() + `?liveId=${liveId}`,
headers).then((data: ResponseDTO<LiveRoomDataBean>) => {
if (!data || !data.data) {
fail("数据为空")
return
}
if (data.code != 0) {
fail(data.message)
return
}
success(data.data)
}, (error: Error) => {
fail(error.message)
Logger.debug(TAG + ":error ", error.toString())
})
})
}
/**
* 获取直播预约状态
* @param relationId
* @param liveId
* @returns
*/
getLiveAppointmentStatus(relationId: string, liveId: string) {
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return new Promise<boolean>((success, fail) => {
HttpRequest.get<ResponseDTO<boolean>>(
HttpUrlUtils.getLiveAppointmentStatusUrl() + `?relationId=${relationId}&liveId=${liveId}`,
headers).then((data: ResponseDTO<boolean>) => {
if (!data || !data.data) {
fail("数据为空")
return
}
if (data.code != 0) {
fail(data.message)
return
}
success(data.data)
}, (error: Error) => {
fail(error.message)
Logger.debug(TAG + ":error ", error.toString())
})
})
}
/**
* 直播预约/取消预约
* @param relationId
* @param mLiveId
* @param isSubscribe
* @returns
*/
liveAppointment(relationId: string, mLiveId: string, isSubscribe: boolean) {
let params: Record<string, string> = {};
params['relationId'] = relationId
params['liveId'] = mLiveId
params['isSubscribe'] = `${isSubscribe}`
let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
return new Promise<ResponseDTO<string>>((success, fail) => {
HttpRequest.post<ResponseDTO<string>>(
HttpUrlUtils.getLiveAppointmentUrl(),
params,
headers).then((data: ResponseDTO<string>) => {
if (data.code != 0) {
fail(data.message)
ToastUtils.shortToast(data.message)
return
}
success(data)
}, (error: Error) => {
fail(error.message)
Logger.debug(TAG + ":error ", error.toString())
})
})
}
}
... ...
import { LiveDetailsBean, LiveRoomBean } from 'wdBean/Index'
import { LiveDetailsBean, LiveRoomBean, LiveRoomDataBean } from 'wdBean/Index'
import { ResponseDTO } from 'wdNetwork/Index'
import { LiveModel } from './LiveModel'
const TAG = "LiveViewModel"
... ... @@ -42,4 +43,37 @@ export class LiveViewModel {
})
})
}
//直播详情直播间数据
getLiveRoomData(liveId: string) {
return new Promise<LiveRoomDataBean>((success, fail) => {
this.liveModel.getLiveRoomData(liveId).then((data) => {
success(data)
}).catch((message: string) => {
fail(message)
})
})
}
//直播预约状态查询
getLiveAppointmentStatus(relationId: string, liveId: string) {
return new Promise<boolean>((success, fail) => {
this.liveModel.getLiveAppointmentStatus(relationId, liveId).then((data) => {
success(data)
}).catch((message: string) => {
fail(message)
})
})
}
//直播预约/取消预约
liveAppointment(relationId: string, mLiveId: string, isSubscribe: boolean) {
return new Promise<ResponseDTO<string>>((success, fail) => {
this.liveModel.liveAppointment(relationId, mLiveId, isSubscribe).then((data) => {
success(data)
}).catch((message: string) => {
fail(message)
})
})
}
}
\ No newline at end of file
... ...
import font from '@ohos.font'
import { LiveDetailsBean } from 'wdBean/Index'
import { DateTimeUtils, StringUtils } from 'wdKit/Index'
import { LiveViewModel } from '../../viewModel/LiveViewModel'
@Component
export struct LiveCountdownComponent {
... ... @@ -13,6 +14,9 @@ export struct LiveCountdownComponent {
@State minute: string = ''
@State differenceTimeStamp: number = 0
@State isCountDownStart: boolean = false
//是否预约过直播
@State isAppointmentLive: boolean = false
liveViewModel: LiveViewModel = new LiveViewModel()
aboutToAppear(): void {
//注册字体
... ... @@ -107,15 +111,23 @@ export struct LiveCountdownComponent {
top: 16
})
.border({ radius: 4 })
.backgroundColor('#ED2800')
// .backgroundColor('#CCCCCC')
.backgroundColor(this.isAppointmentLive ? '#CCCCCC' : '#ED2800')
.onClick(() => {
if (this.liveDetailsBean && this.liveDetailsBean.liveInfo) {
this.liveAppointment()
}
})
}
calculateDataStatus() {
if (!this.liveDetailsBean) {
return
}
this.getLiveAppointmentStatus()
let startTimeStamp: number = DateTimeUtils.getDateTimestamp(this.liveDetailsBean.liveInfo.planStartTime)
let currentTimeStamp: number = DateTimeUtils.getTimeStamp()
let _differenceTimeStampTmp = startTimeStamp - currentTimeStamp
this.isCountDownStart = _differenceTimeStampTmp <= 4 * 60 * 60 * 1000
this.isCountDownStart = _differenceTimeStampTmp <= 0 ? false : _differenceTimeStampTmp <= 4 * 60 * 60 * 1000
if (this.isCountDownStart) {
this.differenceTimeStamp = _differenceTimeStampTmp
return
... ... @@ -129,6 +141,34 @@ export struct LiveCountdownComponent {
this.minute = playStartTimeTmp.substring(14, 16)
}
}
getLiveAppointmentStatus() {
this.liveViewModel.getLiveAppointmentStatus(
this.liveDetailsBean.reLInfo ? this.liveDetailsBean.reLInfo.relId : '',
this.liveDetailsBean.newsId
).then(
(data) => {
this.isAppointmentLive = data
},
() => {
})
}
liveAppointment() {
this.liveViewModel.liveAppointment(
this.liveDetailsBean.reLInfo ? this.liveDetailsBean.reLInfo.relId : '',
this.liveDetailsBean.newsId,
!this.isAppointmentLive).then(
(data) => {
if (data.success) {
this.isAppointmentLive = !this.isAppointmentLive
}
},
() => {
})
}
}
@Extend(Text)
... ...
import { LiveRoomItemBean } from 'wdBean/Index'
import { LiveDetailsBean, LiveRoomItemBean } from 'wdBean/Index'
import { ListHasNoMoreDataUI } from 'wdComponent/Index'
import { StringUtils } from 'wdKit/Index'
import { LiveViewModel } from '../../viewModel/LiveViewModel'
import { TabLiveItemComponent } from './TabLiveItemComponent'
... ... @@ -7,6 +8,7 @@ import { TabLiveItemComponent } from './TabLiveItemComponent'
export struct TabLiveComponent {
liveViewModel: LiveViewModel = new LiveViewModel()
@State liveList: Array<LiveRoomItemBean> = []
@Consume liveDetailsBean: LiveDetailsBean
aboutToAppear(): void {
this.getLiveList()
... ... @@ -40,6 +42,20 @@ export struct TabLiveComponent {
this.liveViewModel.getLiveList(1, '20000016257', '20000016229', 20,)
.then(
(data) => {
/**
* 在直播聊天添加一条新内容逻辑:
判断 oldNewsId:迁移id非空 且 直播状态不是预约:"wait"
消息内容:
1.头像固定:APP默认头像
2.名称固定:人民日报主持人
3.内容:详情接口的简介,newIntroduction
*/
if (StringUtils.isNotEmpty(this.liveDetailsBean.oldNewsId) && this.liveDetailsBean && this.liveDetailsBean.liveInfo.liveState != 'wait') {
let liveRoomItemBeanTemp: LiveRoomItemBean = {} as LiveRoomItemBean
liveRoomItemBeanTemp.text = this.liveDetailsBean.newIntroduction
liveRoomItemBeanTemp.senderUserName = '人民日报主持人'
data.barrageResponses.push(liveRoomItemBeanTemp)
}
this.liveList = data.barrageResponses
},
() => {
... ...
import { LiveRoomItemBean } from 'wdBean/Index'
import { DateTimeUtils } from 'wdKit/Index'
import { DateTimeUtils, StringUtils } from 'wdKit/Index'
@Component
export struct TabLiveItemComponent {
... ... @@ -12,7 +12,7 @@ export struct TabLiveItemComponent {
build() {
Column() {
Row() {
Image(this.item.senderUserAvatarUrl)
Image(StringUtils.isEmpty(this.item.senderUserAvatarUrl) ? $r('app.media.default_head') : this.item.senderUserAvatarUrl)
.borderRadius(90)
.width(24)
.height(24)
... ... @@ -46,6 +46,7 @@ export struct TabLiveItemComponent {
.fontWeight(400)
.fontColor('#999999')
.margin({ left: 8 })
.visibility(StringUtils.isNotEmpty(this.item.time) ? Visibility.Visible : Visibility.None)
Blank()
Text('置顶')
.maxLines(1)
... ...
import { window } from '@kit.ArkUI'
import { DateTimeUtils, NumberFormatterUtils, WindowModel } from 'wdKit/Index'
import { devicePLSensorManager } from 'wdDetailPlayApi/Index'
import { LiveDetailsBean, LiveRoomDataBean } from 'wdBean/Index'
import { WDPlayerController } from 'wdPlayer/Index'
@Entry
@Component
export struct PlayUIComponent {
playerController: WDPlayerController = new WDPlayerController();
//菜单键是否可见
@State isMenuVisible: boolean = true
@State isFullScreen: boolean = false
@Consume liveDetailsBean: LiveDetailsBean
@Consume liveRoomDataBean: LiveRoomDataBean
@State currentTime: string = ''
@State totalTime: string = ''
@State progressVal: number = 0;
//是否处于播放状态中
@State isPlayStatus: boolean = true
aboutToAppear(): void {
//播放进度监听
this.playerController.onTimeUpdate = (position: number, duration: number) => {
this.currentTime = DateTimeUtils.secondToTime(position);
this.totalTime = DateTimeUtils.secondToTime(duration);
this.progressVal = Math.floor(position * 100 / duration);
}
}
build() {
Column() {
this.getTopUIComponent()
this.getMiddleUIComponent()
this.getBottomUIComponent()
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
getTopUIComponent() {
Column() {
Row() {
Image($r('app.media.icon_arrow_left_white'))
.width(24)
.aspectRatio(1)
.visibility(Visibility.None)
.margin({
right: 10
})
Text(this.liveDetailsBean.newsTitle)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize('16fp')
.fontWeight(500)
.fontColor(Color.White)
.textAlign(TextAlign.Start)
.layoutWeight(1)
Image($r('app.media.icon_share'))
.width(24)
.aspectRatio(1)
.visibility(Visibility.None)
}
.width('100%')
.alignItems(VerticalAlign.Center)
.margin({
bottom: 5
})
this.getLiveStatusView()
}.width('100%')
.padding({
top: 10,
bottom: 6,
left: 10,
right: 10
})
.alignItems(HorizontalAlign.Start)
.visibility(this.isMenuVisible ? Visibility.Visible : Visibility.None)
}
@Builder
getLiveStatusView() {
//预约
//直播中
//回看
Row() {
Text('回看')
.fontSize('11fp')
.fontWeight(400)
.fontColor(Color.White)
Image($r('app.media.icon_live_player_status_end'))
.width(12)
.height(12)
Text(`${NumberFormatterUtils.formatNumberWithWan(this.liveRoomDataBean.pv)}人参与`)
.fontSize('11fp')
.fontWeight(400)
.fontColor(Color.White)
}
.backgroundColor('#4D000000')
.padding({
left: 4,
top: 1,
right: 4,
bottom: 1
})
}
@Builder
getMiddleUIComponent() {
Stack()
.layoutWeight(1)
.width('100%')
.onClick(() => {
this.isMenuVisible = !this.isMenuVisible
})
}
@Builder
getBottomUIComponent() {
Row() {
this.playOrPauseBtn()
Text(this.currentTime)
.fontColor(Color.White)
.fontWeight(600)
.fontSize('12fp')
.margin({
left: 16
})
this.playProgressView()
Text(this.totalTime)
.fontColor(Color.White)
.fontWeight(600)
.fontSize('12fp')
.margin({
right: 16
})
Image($r('app.media.icon_live_player_full_screen'))
.width(24)
.height(24)
.onClick(() => {
this.isFullScreen = !this.isFullScreen
WindowModel.shared.setPreferredOrientation(this.isFullScreen ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT);
devicePLSensorManager.devicePLSensorOn(this.isFullScreen ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT);
})
}
.alignItems(VerticalAlign.Center)
.linearGradient({ angle: 0, colors: [['#99000000', 0], ['#00000000', 1]] })
.width('100%')
.padding({
left: 10,
right: 10,
top: 15,
bottom: 15
})
.visibility(this.isMenuVisible ? Visibility.Visible : Visibility.None)
}
@Builder
playOrPauseBtn() {
//暂停、播放
Image(this.isPlayStatus ? $r('app.media.icon_live_player_pause') : $r('app.media.player_play_ic'))
.width(24)
.height(24)
.onClick(() => {
if (this.isPlayStatus) {
this.isPlayStatus = false
this.playerController.pause()
} else {
this.isPlayStatus = true
this.playerController.play()
}
})
}
@Builder
playProgressView() {
Slider({
value: this.progressVal,
step: 1,
// style: SliderStyle.OutSet
})
.blockStyle({
type: SliderBlockType.IMAGE,
image: $r('app.media.ic_player_block')
})
.blockColor(Color.White)
.trackColor('#4DFFFFFF')
.selectedColor('#FFED2800')
.height(2)
.trackThickness(1)
.layoutWeight(1)
.margin({
left: 8,
right: 8
})
.onChange((value: number, mode: SliderChangeMode) => {
this.playerController?.setSeekTime(value, mode);
})
}
}
\ No newline at end of file
... ...
import { WDPlayerController, WDPlayerRenderView } from 'wdPlayer/Index';
import { LiveDetailsBean } from 'wdBean/Index';
import { WDPlayerController, WDPlayerRenderLiveView } from 'wdPlayer/Index';
import { PlayUIComponent } from './PlayUIComponent';
@Component
export struct TopPlayComponent {
@Prop playUrl: string=''
aspectRatioPlayer: number = 375 / 211
@State playerController: WDPlayerController = new WDPlayerController();
@Consume @Watch('updateData') liveDetailsBean: LiveDetailsBean
playerController: WDPlayerController = new WDPlayerController();
aboutToAppear(): void {
setTimeout(() => {
this.playerController.switchPlayOrPause()
},2000)
this.playerController.onCanplay = () => {
this.playerController.play()
}
}
updateData() {
if (this.liveDetailsBean.liveInfo && this.liveDetailsBean.liveInfo.vlive.length > 0) {
let playUrl: string = this.liveDetailsBean.liveInfo.vlive[0].replayUri
this.playerController.firstPlay(playUrl);
}
}
build() {
Stack() {
WDPlayerRenderView({
WDPlayerRenderLiveView({
playerController: this.playerController,
onLoad: async () => {
this.playerController.firstPlay(this.playUrl);
}
})
.height('100%')
.width('100%')
.onClick(() => {
console.error('WDPlayerRenderView=== onClick')
this.playerController?.switchPlayOrPause();
})
PlayUIComponent({ playerController: this.playerController })
}
.height(211)
.aspectRatio(this.aspectRatioPlayer)
.backgroundColor(Color.Black)
.width('100%')
}
aboutToDisappear(): void {
this.playerController.pause()
}
}
\ No newline at end of file
... ...
... ... @@ -9,6 +9,11 @@
"2in1"
],
"deliveryWithInstall": true,
"pages": "$profile:main_pages"
"pages": "$profile:main_pages",
"requestPermissions": [
{
"name":"ohos.permission.ACCELEROMETER"
}
]
}
}
\ No newline at end of file
... ...
... ... @@ -2,6 +2,8 @@ export { WDPlayerController } from "./src/main/ets/controller/WDPlayerController
export { WDPlayerRenderView } from "./src/main/ets/pages/WDPlayerRenderView"
export { WDPlayerRenderLiveView } from "./src/main/ets/pages/WDPlayerRenderLiveView"
export { PlayerConstants } from "./src/main/ets/constants/PlayerConstants"
export { SpeedBean } from "./src/main/ets/bean/SpeedBean"
... ...
import componentUtils from '@ohos.arkui.componentUtils';
import { WDPlayerController } from '../controller/WDPlayerController'
import { WindowModel } from 'wdKit';
import { Logger } from '../utils/Logger';
class Size {
width: Length = "100%";
height: Length = "100%";
constructor(width: Length, height: Length) {
this.width = width;
this.height = height;
}
}
let insIndex: number = 0;
const TAG = 'WDPlayerRenderLiveView'
class MGPlayRenderViewIns {
static intCount: number = 0;
static add() {
MGPlayRenderViewIns.intCount++;
WindowModel.shared.setWindowKeepScreenOn(true);
console.log("add-- +1")
}
static del() {
console.log("del-- -1")
MGPlayRenderViewIns.intCount--;
if (MGPlayRenderViewIns.intCount <= 0) {
WindowModel.shared.setWindowKeepScreenOn(false);
}
}
}
/**
* 播放窗口组件
*/
@Component
export struct WDPlayerRenderLiveView {
private playerController?: WDPlayerController;
private xComponentController: XComponentController = new XComponentController();
onLoad?: ((event?: object) => void);
videoWidth: number = 0
videoHeight: number = 0
@State selfSize: Size = new Size('100%', '100%');
private insId: string = "WDPlayRenderView" + insIndex;
aboutToAppear() {
MGPlayRenderViewIns.add();
console.log('playerController', this.playerController)
insIndex++;
if (!this.playerController) {
return
}
this.playerController.onVideoSizeChange = (width: number, height: number) => {
// console.log(`WDPlayerRenderView onVideoSizeChange width:${width} videoTop:${height}`)
Logger.info(TAG, ` onVideoSizeChange width:${width} videoTop:${height}`)
this.videoWidth = width;
this.videoHeight = height;
this.updateLayout()
}
}
aboutToDisappear() {
Logger.info(TAG, `aboutToDisappear`)
MGPlayRenderViewIns.del();
}
build() {
Row() {
// 设置为“surface“类型时XComponent组件可以和其他组件一起进行布局和渲染。
XComponent({
id: 'xComponentId',
type: 'surface',
controller: this.xComponentController
})
.onLoad(async (event) => {
Logger.info(TAG, 'onLoad')
let surfaceId = this.xComponentController.getXComponentSurfaceId()
console.log('surfaceId===', surfaceId)
console.log('insId===', this.insId)
this.xComponentController.setXComponentSurfaceSize({
surfaceWidth: 1920,
surfaceHeight: 1080
});
this.playerController?.setXComponentController(this.xComponentController)
if (this.onLoad) {
this.onLoad(event)
}
})
.width(this.selfSize.width)
.height(this.selfSize.height)
}
.id(this.insId)
.onAreaChange(() => {
// this.updateLayout()
})
.backgroundColor("#000000")
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
updateLayout() {
let info = componentUtils.getRectangleById(this.insId);
if (info.size.width > 0 && info.size.height > 0 && this.videoHeight > 0 && this.videoWidth > 0) {
if (info.size.width / info.size.height > this.videoWidth / this.videoHeight) {
let scale = info.size.height / this.videoHeight;
this.selfSize = new Size((this.videoWidth * scale / info.size.width) * 100 + "%", '100%');
} else {
let scale = info.size.width / this.videoWidth;
this.selfSize = new Size('100%', (this.videoHeight * scale / info.size.height) * 100 + "%");
}
}
}
}
\ No newline at end of file
... ...