Showing
25 changed files
with
645 additions
and
35 deletions
| 1 | import { StringUtils } from './StringUtils'; | 1 | import { StringUtils } from './StringUtils'; |
| 2 | -import getLunar from './GetLunar' | 2 | +import getLunar from './GetLunar'; |
| 3 | + | ||
| 3 | /** | 4 | /** |
| 4 | * 日期/时间工具 | 5 | * 日期/时间工具 |
| 5 | */ | 6 | */ |
| @@ -480,6 +481,34 @@ export class DateTimeUtils { | @@ -480,6 +481,34 @@ export class DateTimeUtils { | ||
| 480 | return 0 | 481 | return 0 |
| 481 | } | 482 | } |
| 482 | } | 483 | } |
| 484 | + /** | ||
| 485 | + * 进度值换算 | ||
| 486 | + * @param seconds | ||
| 487 | + * @returns | ||
| 488 | + */ | ||
| 489 | + static secondToTime(seconds: number) { | ||
| 490 | + let time = '00:00' | ||
| 491 | + let hourUnit = 60 * 60; | ||
| 492 | + let hour = Math.floor(seconds / hourUnit); | ||
| 493 | + let minute = Math.floor((seconds - hour * hourUnit) / 60); | ||
| 494 | + let second = seconds - hour * hourUnit - minute * 60; | ||
| 495 | + if (hour > 0) { | ||
| 496 | + return `${DateTimeUtils.padding(hour.toString())}${':'}${DateTimeUtils.padding(minute.toString())}${':'}${DateTimeUtils.padding(second.toString())}`; | ||
| 497 | + } | ||
| 498 | + if (minute > 0) { | ||
| 499 | + return `${DateTimeUtils.padding(minute.toString())}${':'}${DateTimeUtils.padding(second.toString())}`; | ||
| 500 | + } else { | ||
| 501 | + return `${'00'}${':'}${DateTimeUtils.padding(second.toString())}`; | ||
| 502 | + } | ||
| 503 | + } | ||
| 504 | + | ||
| 505 | + static padding(num: string) { | ||
| 506 | + let length = 2; | ||
| 507 | + for (let len = (num.toString()).length; len < length; len = num.length) { | ||
| 508 | + num = `${'0'}${num}`; | ||
| 509 | + } | ||
| 510 | + return num; | ||
| 511 | + } | ||
| 483 | } | 512 | } |
| 484 | 513 | ||
| 485 | // const dateTimeUtils = new DateTimeUtils() | 514 | // const dateTimeUtils = new DateTimeUtils() |
| 1 | -import HashMap from '@ohos.util.HashMap' | ||
| 2 | -import { ConfigConstants, SpConstants } from 'wdConstant' | ||
| 3 | -import { DateTimeUtils, Logger, SPHelper, StringUtils } from 'wdKit' | 1 | +import HashMap from '@ohos.util.HashMap'; |
| 2 | +import { SpConstants } from 'wdConstant'; | ||
| 3 | +import { SPHelper, StringUtils } from 'wdKit'; | ||
| 4 | 4 | ||
| 5 | /** | 5 | /** |
| 6 | * 网络请求业务侧工具类 | 6 | * 网络请求业务侧工具类 |
| @@ -213,6 +213,18 @@ export class HttpUrlUtils { | @@ -213,6 +213,18 @@ export class HttpUrlUtils { | ||
| 213 | */ | 213 | */ |
| 214 | static readonly LIVE_CHAT_LIST_PATH: string = "/api/live-center-message/zh/a/live/message/chat/list"; | 214 | static readonly LIVE_CHAT_LIST_PATH: string = "/api/live-center-message/zh/a/live/message/chat/list"; |
| 215 | /** | 215 | /** |
| 216 | + * 直播详情-直播数据 | ||
| 217 | + */ | ||
| 218 | + static readonly LIVE_ROOM_DATA_PATH: string = "/api/live-center-message/zh/a/live/room/number/all"; | ||
| 219 | + /** | ||
| 220 | + * 直播详情-预约直播状态 | ||
| 221 | + */ | ||
| 222 | + static readonly LIVE_APPOINTMENT_STATUS_PATH: string = "/api/live-center-message/zh/c/live/subscribe/query"; | ||
| 223 | + /** | ||
| 224 | + * 直播详情-预约/取消预约直播 | ||
| 225 | + */ | ||
| 226 | + static readonly LIVE_APPOINTMENT_PATH: string = "/api/live-center-message/zh/c/live/subscribe"; | ||
| 227 | + /** | ||
| 216 | 228 | ||
| 217 | * 搜索结果 显示tab 数 | 229 | * 搜索结果 显示tab 数 |
| 218 | */ | 230 | */ |
| @@ -653,6 +665,21 @@ export class HttpUrlUtils { | @@ -653,6 +665,21 @@ export class HttpUrlUtils { | ||
| 653 | return url | 665 | return url |
| 654 | } | 666 | } |
| 655 | 667 | ||
| 668 | + static getLiveRoomDataUrl() { | ||
| 669 | + let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_ROOM_DATA_PATH | ||
| 670 | + return url | ||
| 671 | + } | ||
| 672 | + | ||
| 673 | + static getLiveAppointmentStatusUrl() { | ||
| 674 | + let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_APPOINTMENT_STATUS_PATH | ||
| 675 | + return url | ||
| 676 | + } | ||
| 677 | + | ||
| 678 | + static getLiveAppointmentUrl() { | ||
| 679 | + let url = HttpUrlUtils._hostUrl + HttpUrlUtils.LIVE_APPOINTMENT_PATH | ||
| 680 | + return url | ||
| 681 | + } | ||
| 682 | + | ||
| 656 | static getSearchResultCountDataUrl() { | 683 | static getSearchResultCountDataUrl() { |
| 657 | let url = HttpUrlUtils._hostUrl + HttpUrlUtils.SEARCH_RESULT_COUNT_DATA_PATH | 684 | let url = HttpUrlUtils._hostUrl + HttpUrlUtils.SEARCH_RESULT_COUNT_DATA_PATH |
| 658 | return url | 685 | return url |
| @@ -120,3 +120,5 @@ export { appStyleImagesDTO } from './src/main/ets/bean/content/appStyleImagesDTO | @@ -120,3 +120,5 @@ export { appStyleImagesDTO } from './src/main/ets/bean/content/appStyleImagesDTO | ||
| 120 | 120 | ||
| 121 | export { LiveRoomBean,LiveRoomItemBean } from './src/main/ets/bean/live/LiveRoomBean'; | 121 | export { LiveRoomBean,LiveRoomItemBean } from './src/main/ets/bean/live/LiveRoomBean'; |
| 122 | 122 | ||
| 123 | +export { LiveRoomDataBean } from './src/main/ets/bean/live/LiveRoomDataBean'; | ||
| 124 | + |
| @@ -158,9 +158,12 @@ export interface LiveDetailsBean { | @@ -158,9 +158,12 @@ export interface LiveDetailsBean { | ||
| 158 | */ | 158 | */ |
| 159 | liveInfo: LiveInfo | 159 | liveInfo: LiveInfo |
| 160 | fullColumnImgUrls: Array<FullColumnImgUrls> | 160 | fullColumnImgUrls: Array<FullColumnImgUrls> |
| 161 | - vlive: Array<Vlive> | ||
| 162 | newsTitle: string | 161 | newsTitle: string |
| 162 | + newsId: string | ||
| 163 | newIntroduction: string | 163 | newIntroduction: string |
| 164 | + //迁移id | ||
| 165 | + oldNewsId: string | ||
| 166 | + reLInfo: ReLInfo | ||
| 164 | } | 167 | } |
| 165 | 168 | ||
| 166 | export interface LiveInfo { | 169 | export interface LiveInfo { |
| @@ -168,6 +171,8 @@ export interface LiveInfo { | @@ -168,6 +171,8 @@ export interface LiveInfo { | ||
| 168 | liveState: string | 171 | liveState: string |
| 169 | //2024-04-12 15:00:00 直播开始时间 | 172 | //2024-04-12 15:00:00 直播开始时间 |
| 170 | planStartTime: string | 173 | planStartTime: string |
| 174 | + mliveId:string | ||
| 175 | + vlive: Array<Vlive> | ||
| 171 | } | 176 | } |
| 172 | 177 | ||
| 173 | export interface FullColumnImgUrls { | 178 | export interface FullColumnImgUrls { |
| @@ -179,4 +184,8 @@ export interface Vlive { | @@ -179,4 +184,8 @@ export interface Vlive { | ||
| 179 | liveUrl: string | 184 | liveUrl: string |
| 180 | //直播回看地址,多路直播录制文件URL | 185 | //直播回看地址,多路直播录制文件URL |
| 181 | replayUri: string | 186 | replayUri: string |
| 187 | +} | ||
| 188 | + | ||
| 189 | +export interface ReLInfo { | ||
| 190 | + relId: string | ||
| 182 | } | 191 | } |
| @@ -12,6 +12,7 @@ | @@ -12,6 +12,7 @@ | ||
| 12 | "wdNetwork": "file:../../commons/wdNetwork", | 12 | "wdNetwork": "file:../../commons/wdNetwork", |
| 13 | "wdKit": "file:../../commons/wdKit", | 13 | "wdKit": "file:../../commons/wdKit", |
| 14 | "wdBean": "file:../../features/wdBean", | 14 | "wdBean": "file:../../features/wdBean", |
| 15 | - "wdConstant": "file:../../commons/wdConstant" | 15 | + "wdConstant": "file:../../commons/wdConstant", |
| 16 | + "wdDetailPlayApi": "file:../../features/wdDetailPlayApi" | ||
| 16 | } | 17 | } |
| 17 | } | 18 | } |
| 1 | -import { LiveDetailsBean } from 'wdBean/Index'; | 1 | +import { Action, LiveDetailsBean, LiveRoomDataBean } from 'wdBean/Index'; |
| 2 | import { LiveViewModel } from '../viewModel/LiveViewModel'; | 2 | import { LiveViewModel } from '../viewModel/LiveViewModel'; |
| 3 | import { BottomComponent } from '../widgets/details/BottomComponent'; | 3 | import { BottomComponent } from '../widgets/details/BottomComponent'; |
| 4 | import { TabComponent } from '../widgets/details/TabComponent'; | 4 | import { TabComponent } from '../widgets/details/TabComponent'; |
| 5 | import { TopPlayComponent } from '../widgets/details/video/TopPlayComponet'; | 5 | import { TopPlayComponent } from '../widgets/details/video/TopPlayComponet'; |
| 6 | +import router from '@ohos.router'; | ||
| 6 | 7 | ||
| 7 | @Entry | 8 | @Entry |
| 8 | @Component | 9 | @Component |
| 9 | export struct DetailPlayLivePage { | 10 | export struct DetailPlayLivePage { |
| 10 | TAG: string = 'DetailPlayLivePage'; | 11 | TAG: string = 'DetailPlayLivePage'; |
| 11 | liveViewModel: LiveViewModel = new LiveViewModel() | 12 | liveViewModel: LiveViewModel = new LiveViewModel() |
| 13 | + @State relId: string = '' | ||
| 14 | + @State contentId: string = '' | ||
| 15 | + @State relType: string = '' | ||
| 12 | @Provide liveDetailsBean: LiveDetailsBean = {} as LiveDetailsBean | 16 | @Provide liveDetailsBean: LiveDetailsBean = {} as LiveDetailsBean |
| 17 | + @Provide liveRoomDataBean: LiveRoomDataBean = {} as LiveRoomDataBean | ||
| 13 | 18 | ||
| 14 | aboutToAppear(): void { | 19 | aboutToAppear(): void { |
| 20 | + let par: Action = router.getParams() as Action; | ||
| 21 | + let params = par?.params; | ||
| 22 | + this.relId = params?.extra?.relId || ''; | ||
| 23 | + this.relType = params?.extra?.relType || ''; | ||
| 24 | + this.contentId = params?.contentID || ''; | ||
| 15 | this.getLiveDetails() | 25 | this.getLiveDetails() |
| 26 | + this.getLiveRoomData() | ||
| 16 | } | 27 | } |
| 17 | 28 | ||
| 18 | build() { | 29 | build() { |
| 19 | Column() { | 30 | Column() { |
| 20 | - TopPlayComponent({playUrl:'http://mlive3.video.weibocdn.com/record/alicdn/5018726527666338/index.m3u8'}) | 31 | + TopPlayComponent() |
| 21 | TabComponent() | 32 | TabComponent() |
| 22 | BottomComponent() | 33 | BottomComponent() |
| 23 | } | 34 | } |
| @@ -30,8 +41,7 @@ export struct DetailPlayLivePage { | @@ -30,8 +41,7 @@ export struct DetailPlayLivePage { | ||
| 30 | } | 41 | } |
| 31 | 42 | ||
| 32 | getLiveDetails() { | 43 | getLiveDetails() { |
| 33 | - this.liveViewModel.getLiveDetails('20000016333', '500005300349', '1')//2024-04-12 15:00:00 | ||
| 34 | - // this.liveViewModel.getLiveDetails('20000016229', '500005272745', '1')//2024-04-03 05:00:00 | 44 | + this.liveViewModel.getLiveDetails(this.contentId, this.relId, this.relType) |
| 35 | .then( | 45 | .then( |
| 36 | (data) => { | 46 | (data) => { |
| 37 | if (data.length > 0) { | 47 | if (data.length > 0) { |
| @@ -43,6 +53,17 @@ export struct DetailPlayLivePage { | @@ -43,6 +53,17 @@ export struct DetailPlayLivePage { | ||
| 43 | }) | 53 | }) |
| 44 | } | 54 | } |
| 45 | 55 | ||
| 56 | + getLiveRoomData() { | ||
| 57 | + this.liveViewModel.getLiveRoomData(this.contentId) | ||
| 58 | + .then( | ||
| 59 | + (data) => { | ||
| 60 | + this.liveRoomDataBean = data | ||
| 61 | + }, | ||
| 62 | + () => { | ||
| 63 | + | ||
| 64 | + }) | ||
| 65 | + } | ||
| 66 | + | ||
| 46 | aboutToDisappear(): void { | 67 | aboutToDisappear(): void { |
| 47 | 68 | ||
| 48 | } | 69 | } |
| 1 | import HashMap from '@ohos.util.HashMap'; | 1 | import HashMap from '@ohos.util.HashMap'; |
| 2 | import { HttpUrlUtils, ResponseDTO } from 'wdNetwork'; | 2 | import { HttpUrlUtils, ResponseDTO } from 'wdNetwork'; |
| 3 | import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest'; | 3 | import { HttpRequest } from 'wdNetwork/src/main/ets/http/HttpRequest'; |
| 4 | -import { Logger } from 'wdKit'; | ||
| 5 | -import { LiveDetailsBean, LiveRoomBean } from 'wdBean/Index'; | 4 | +import { Logger, ToastUtils } from 'wdKit'; |
| 5 | +import { LiveDetailsBean, LiveRoomBean, LiveRoomDataBean } from 'wdBean/Index'; | ||
| 6 | 6 | ||
| 7 | const TAG = 'LiveModel' | 7 | const TAG = 'LiveModel' |
| 8 | 8 | ||
| @@ -107,5 +107,91 @@ export class LiveModel { | @@ -107,5 +107,91 @@ export class LiveModel { | ||
| 107 | }) | 107 | }) |
| 108 | }) | 108 | }) |
| 109 | } | 109 | } |
| 110 | + | ||
| 111 | + /** | ||
| 112 | + * 获取直播数据 | ||
| 113 | + * @param liveId | ||
| 114 | + * @returns | ||
| 115 | + */ | ||
| 116 | + getLiveRoomData(liveId: string) { | ||
| 117 | + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders(); | ||
| 118 | + return new Promise<LiveRoomDataBean>((success, fail) => { | ||
| 119 | + HttpRequest.get<ResponseDTO<LiveRoomDataBean>>( | ||
| 120 | + HttpUrlUtils.getLiveRoomDataUrl() + `?liveId=${liveId}`, | ||
| 121 | + headers).then((data: ResponseDTO<LiveRoomDataBean>) => { | ||
| 122 | + if (!data || !data.data) { | ||
| 123 | + fail("数据为空") | ||
| 124 | + return | ||
| 125 | + } | ||
| 126 | + if (data.code != 0) { | ||
| 127 | + fail(data.message) | ||
| 128 | + return | ||
| 129 | + } | ||
| 130 | + success(data.data) | ||
| 131 | + }, (error: Error) => { | ||
| 132 | + fail(error.message) | ||
| 133 | + Logger.debug(TAG + ":error ", error.toString()) | ||
| 134 | + }) | ||
| 135 | + }) | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + /** | ||
| 139 | + * 获取直播预约状态 | ||
| 140 | + * @param relationId | ||
| 141 | + * @param liveId | ||
| 142 | + * @returns | ||
| 143 | + */ | ||
| 144 | + getLiveAppointmentStatus(relationId: string, liveId: string) { | ||
| 145 | + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders(); | ||
| 146 | + return new Promise<boolean>((success, fail) => { | ||
| 147 | + HttpRequest.get<ResponseDTO<boolean>>( | ||
| 148 | + HttpUrlUtils.getLiveAppointmentStatusUrl() + `?relationId=${relationId}&liveId=${liveId}`, | ||
| 149 | + headers).then((data: ResponseDTO<boolean>) => { | ||
| 150 | + if (!data || !data.data) { | ||
| 151 | + fail("数据为空") | ||
| 152 | + return | ||
| 153 | + } | ||
| 154 | + if (data.code != 0) { | ||
| 155 | + fail(data.message) | ||
| 156 | + return | ||
| 157 | + } | ||
| 158 | + success(data.data) | ||
| 159 | + }, (error: Error) => { | ||
| 160 | + fail(error.message) | ||
| 161 | + Logger.debug(TAG + ":error ", error.toString()) | ||
| 162 | + }) | ||
| 163 | + }) | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + /** | ||
| 167 | + * 直播预约/取消预约 | ||
| 168 | + * @param relationId | ||
| 169 | + * @param mLiveId | ||
| 170 | + * @param isSubscribe | ||
| 171 | + * @returns | ||
| 172 | + */ | ||
| 173 | + liveAppointment(relationId: string, mLiveId: string, isSubscribe: boolean) { | ||
| 174 | + let params: Record<string, string> = {}; | ||
| 175 | + params['relationId'] = relationId | ||
| 176 | + params['liveId'] = mLiveId | ||
| 177 | + params['isSubscribe'] = `${isSubscribe}` | ||
| 178 | + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders(); | ||
| 179 | + return new Promise<ResponseDTO<string>>((success, fail) => { | ||
| 180 | + HttpRequest.post<ResponseDTO<string>>( | ||
| 181 | + HttpUrlUtils.getLiveAppointmentUrl(), | ||
| 182 | + params, | ||
| 183 | + headers).then((data: ResponseDTO<string>) => { | ||
| 184 | + if (data.code != 0) { | ||
| 185 | + fail(data.message) | ||
| 186 | + ToastUtils.shortToast(data.message) | ||
| 187 | + return | ||
| 188 | + } | ||
| 189 | + success(data) | ||
| 190 | + }, (error: Error) => { | ||
| 191 | + fail(error.message) | ||
| 192 | + Logger.debug(TAG + ":error ", error.toString()) | ||
| 193 | + }) | ||
| 194 | + }) | ||
| 195 | + } | ||
| 110 | } | 196 | } |
| 111 | 197 |
| 1 | -import { LiveDetailsBean, LiveRoomBean } from 'wdBean/Index' | 1 | +import { LiveDetailsBean, LiveRoomBean, LiveRoomDataBean } from 'wdBean/Index' |
| 2 | +import { ResponseDTO } from 'wdNetwork/Index' | ||
| 2 | import { LiveModel } from './LiveModel' | 3 | import { LiveModel } from './LiveModel' |
| 3 | 4 | ||
| 4 | const TAG = "LiveViewModel" | 5 | const TAG = "LiveViewModel" |
| @@ -42,4 +43,37 @@ export class LiveViewModel { | @@ -42,4 +43,37 @@ export class LiveViewModel { | ||
| 42 | }) | 43 | }) |
| 43 | }) | 44 | }) |
| 44 | } | 45 | } |
| 46 | + | ||
| 47 | + //直播详情直播间数据 | ||
| 48 | + getLiveRoomData(liveId: string) { | ||
| 49 | + return new Promise<LiveRoomDataBean>((success, fail) => { | ||
| 50 | + this.liveModel.getLiveRoomData(liveId).then((data) => { | ||
| 51 | + success(data) | ||
| 52 | + }).catch((message: string) => { | ||
| 53 | + fail(message) | ||
| 54 | + }) | ||
| 55 | + }) | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + //直播预约状态查询 | ||
| 59 | + getLiveAppointmentStatus(relationId: string, liveId: string) { | ||
| 60 | + return new Promise<boolean>((success, fail) => { | ||
| 61 | + this.liveModel.getLiveAppointmentStatus(relationId, liveId).then((data) => { | ||
| 62 | + success(data) | ||
| 63 | + }).catch((message: string) => { | ||
| 64 | + fail(message) | ||
| 65 | + }) | ||
| 66 | + }) | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + //直播预约/取消预约 | ||
| 70 | + liveAppointment(relationId: string, mLiveId: string, isSubscribe: boolean) { | ||
| 71 | + return new Promise<ResponseDTO<string>>((success, fail) => { | ||
| 72 | + this.liveModel.liveAppointment(relationId, mLiveId, isSubscribe).then((data) => { | ||
| 73 | + success(data) | ||
| 74 | + }).catch((message: string) => { | ||
| 75 | + fail(message) | ||
| 76 | + }) | ||
| 77 | + }) | ||
| 78 | + } | ||
| 45 | } | 79 | } |
| 1 | import font from '@ohos.font' | 1 | import font from '@ohos.font' |
| 2 | import { LiveDetailsBean } from 'wdBean/Index' | 2 | import { LiveDetailsBean } from 'wdBean/Index' |
| 3 | import { DateTimeUtils, StringUtils } from 'wdKit/Index' | 3 | import { DateTimeUtils, StringUtils } from 'wdKit/Index' |
| 4 | +import { LiveViewModel } from '../../viewModel/LiveViewModel' | ||
| 4 | 5 | ||
| 5 | @Component | 6 | @Component |
| 6 | export struct LiveCountdownComponent { | 7 | export struct LiveCountdownComponent { |
| @@ -13,6 +14,9 @@ export struct LiveCountdownComponent { | @@ -13,6 +14,9 @@ export struct LiveCountdownComponent { | ||
| 13 | @State minute: string = '' | 14 | @State minute: string = '' |
| 14 | @State differenceTimeStamp: number = 0 | 15 | @State differenceTimeStamp: number = 0 |
| 15 | @State isCountDownStart: boolean = false | 16 | @State isCountDownStart: boolean = false |
| 17 | + //是否预约过直播 | ||
| 18 | + @State isAppointmentLive: boolean = false | ||
| 19 | + liveViewModel: LiveViewModel = new LiveViewModel() | ||
| 16 | 20 | ||
| 17 | aboutToAppear(): void { | 21 | aboutToAppear(): void { |
| 18 | //注册字体 | 22 | //注册字体 |
| @@ -107,15 +111,23 @@ export struct LiveCountdownComponent { | @@ -107,15 +111,23 @@ export struct LiveCountdownComponent { | ||
| 107 | top: 16 | 111 | top: 16 |
| 108 | }) | 112 | }) |
| 109 | .border({ radius: 4 }) | 113 | .border({ radius: 4 }) |
| 110 | - .backgroundColor('#ED2800') | ||
| 111 | - // .backgroundColor('#CCCCCC') | 114 | + .backgroundColor(this.isAppointmentLive ? '#CCCCCC' : '#ED2800') |
| 115 | + .onClick(() => { | ||
| 116 | + if (this.liveDetailsBean && this.liveDetailsBean.liveInfo) { | ||
| 117 | + this.liveAppointment() | ||
| 118 | + } | ||
| 119 | + }) | ||
| 112 | } | 120 | } |
| 113 | 121 | ||
| 114 | calculateDataStatus() { | 122 | calculateDataStatus() { |
| 123 | + if (!this.liveDetailsBean) { | ||
| 124 | + return | ||
| 125 | + } | ||
| 126 | + this.getLiveAppointmentStatus() | ||
| 115 | let startTimeStamp: number = DateTimeUtils.getDateTimestamp(this.liveDetailsBean.liveInfo.planStartTime) | 127 | let startTimeStamp: number = DateTimeUtils.getDateTimestamp(this.liveDetailsBean.liveInfo.planStartTime) |
| 116 | let currentTimeStamp: number = DateTimeUtils.getTimeStamp() | 128 | let currentTimeStamp: number = DateTimeUtils.getTimeStamp() |
| 117 | let _differenceTimeStampTmp = startTimeStamp - currentTimeStamp | 129 | let _differenceTimeStampTmp = startTimeStamp - currentTimeStamp |
| 118 | - this.isCountDownStart = _differenceTimeStampTmp <= 4 * 60 * 60 * 1000 | 130 | + this.isCountDownStart = _differenceTimeStampTmp <= 0 ? false : _differenceTimeStampTmp <= 4 * 60 * 60 * 1000 |
| 119 | if (this.isCountDownStart) { | 131 | if (this.isCountDownStart) { |
| 120 | this.differenceTimeStamp = _differenceTimeStampTmp | 132 | this.differenceTimeStamp = _differenceTimeStampTmp |
| 121 | return | 133 | return |
| @@ -129,6 +141,34 @@ export struct LiveCountdownComponent { | @@ -129,6 +141,34 @@ export struct LiveCountdownComponent { | ||
| 129 | this.minute = playStartTimeTmp.substring(14, 16) | 141 | this.minute = playStartTimeTmp.substring(14, 16) |
| 130 | } | 142 | } |
| 131 | } | 143 | } |
| 144 | + | ||
| 145 | + getLiveAppointmentStatus() { | ||
| 146 | + this.liveViewModel.getLiveAppointmentStatus( | ||
| 147 | + this.liveDetailsBean.reLInfo ? this.liveDetailsBean.reLInfo.relId : '', | ||
| 148 | + this.liveDetailsBean.newsId | ||
| 149 | + ).then( | ||
| 150 | + (data) => { | ||
| 151 | + this.isAppointmentLive = data | ||
| 152 | + }, | ||
| 153 | + () => { | ||
| 154 | + | ||
| 155 | + }) | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + liveAppointment() { | ||
| 159 | + this.liveViewModel.liveAppointment( | ||
| 160 | + this.liveDetailsBean.reLInfo ? this.liveDetailsBean.reLInfo.relId : '', | ||
| 161 | + this.liveDetailsBean.newsId, | ||
| 162 | + !this.isAppointmentLive).then( | ||
| 163 | + (data) => { | ||
| 164 | + if (data.success) { | ||
| 165 | + this.isAppointmentLive = !this.isAppointmentLive | ||
| 166 | + } | ||
| 167 | + }, | ||
| 168 | + () => { | ||
| 169 | + | ||
| 170 | + }) | ||
| 171 | + } | ||
| 132 | } | 172 | } |
| 133 | 173 | ||
| 134 | @Extend(Text) | 174 | @Extend(Text) |
| 1 | -import { LiveRoomItemBean } from 'wdBean/Index' | 1 | +import { LiveDetailsBean, LiveRoomItemBean } from 'wdBean/Index' |
| 2 | import { ListHasNoMoreDataUI } from 'wdComponent/Index' | 2 | import { ListHasNoMoreDataUI } from 'wdComponent/Index' |
| 3 | +import { StringUtils } from 'wdKit/Index' | ||
| 3 | import { LiveViewModel } from '../../viewModel/LiveViewModel' | 4 | import { LiveViewModel } from '../../viewModel/LiveViewModel' |
| 4 | import { TabLiveItemComponent } from './TabLiveItemComponent' | 5 | import { TabLiveItemComponent } from './TabLiveItemComponent' |
| 5 | 6 | ||
| @@ -7,6 +8,7 @@ import { TabLiveItemComponent } from './TabLiveItemComponent' | @@ -7,6 +8,7 @@ import { TabLiveItemComponent } from './TabLiveItemComponent' | ||
| 7 | export struct TabLiveComponent { | 8 | export struct TabLiveComponent { |
| 8 | liveViewModel: LiveViewModel = new LiveViewModel() | 9 | liveViewModel: LiveViewModel = new LiveViewModel() |
| 9 | @State liveList: Array<LiveRoomItemBean> = [] | 10 | @State liveList: Array<LiveRoomItemBean> = [] |
| 11 | + @Consume liveDetailsBean: LiveDetailsBean | ||
| 10 | 12 | ||
| 11 | aboutToAppear(): void { | 13 | aboutToAppear(): void { |
| 12 | this.getLiveList() | 14 | this.getLiveList() |
| @@ -40,6 +42,20 @@ export struct TabLiveComponent { | @@ -40,6 +42,20 @@ export struct TabLiveComponent { | ||
| 40 | this.liveViewModel.getLiveList(1, '20000016257', '20000016229', 20,) | 42 | this.liveViewModel.getLiveList(1, '20000016257', '20000016229', 20,) |
| 41 | .then( | 43 | .then( |
| 42 | (data) => { | 44 | (data) => { |
| 45 | + /** | ||
| 46 | + * 在直播聊天添加一条新内容逻辑: | ||
| 47 | + 判断 oldNewsId:迁移id非空 且 直播状态不是预约:"wait" | ||
| 48 | + 消息内容: | ||
| 49 | + 1.头像固定:APP默认头像 | ||
| 50 | + 2.名称固定:人民日报主持人 | ||
| 51 | + 3.内容:详情接口的简介,newIntroduction | ||
| 52 | + */ | ||
| 53 | + if (StringUtils.isNotEmpty(this.liveDetailsBean.oldNewsId) && this.liveDetailsBean && this.liveDetailsBean.liveInfo.liveState != 'wait') { | ||
| 54 | + let liveRoomItemBeanTemp: LiveRoomItemBean = {} as LiveRoomItemBean | ||
| 55 | + liveRoomItemBeanTemp.text = this.liveDetailsBean.newIntroduction | ||
| 56 | + liveRoomItemBeanTemp.senderUserName = '人民日报主持人' | ||
| 57 | + data.barrageResponses.push(liveRoomItemBeanTemp) | ||
| 58 | + } | ||
| 43 | this.liveList = data.barrageResponses | 59 | this.liveList = data.barrageResponses |
| 44 | }, | 60 | }, |
| 45 | () => { | 61 | () => { |
| 1 | import { LiveRoomItemBean } from 'wdBean/Index' | 1 | import { LiveRoomItemBean } from 'wdBean/Index' |
| 2 | -import { DateTimeUtils } from 'wdKit/Index' | 2 | +import { DateTimeUtils, StringUtils } from 'wdKit/Index' |
| 3 | 3 | ||
| 4 | @Component | 4 | @Component |
| 5 | export struct TabLiveItemComponent { | 5 | export struct TabLiveItemComponent { |
| @@ -12,7 +12,7 @@ export struct TabLiveItemComponent { | @@ -12,7 +12,7 @@ export struct TabLiveItemComponent { | ||
| 12 | build() { | 12 | build() { |
| 13 | Column() { | 13 | Column() { |
| 14 | Row() { | 14 | Row() { |
| 15 | - Image(this.item.senderUserAvatarUrl) | 15 | + Image(StringUtils.isEmpty(this.item.senderUserAvatarUrl) ? $r('app.media.default_head') : this.item.senderUserAvatarUrl) |
| 16 | .borderRadius(90) | 16 | .borderRadius(90) |
| 17 | .width(24) | 17 | .width(24) |
| 18 | .height(24) | 18 | .height(24) |
| @@ -46,6 +46,7 @@ export struct TabLiveItemComponent { | @@ -46,6 +46,7 @@ export struct TabLiveItemComponent { | ||
| 46 | .fontWeight(400) | 46 | .fontWeight(400) |
| 47 | .fontColor('#999999') | 47 | .fontColor('#999999') |
| 48 | .margin({ left: 8 }) | 48 | .margin({ left: 8 }) |
| 49 | + .visibility(StringUtils.isNotEmpty(this.item.time) ? Visibility.Visible : Visibility.None) | ||
| 49 | Blank() | 50 | Blank() |
| 50 | Text('置顶') | 51 | Text('置顶') |
| 51 | .maxLines(1) | 52 | .maxLines(1) |
sight_harmony/features/wdDetailPlayLive/src/main/ets/widgets/details/video/PlayUIComponent.ets
0 → 100644
| 1 | +import { window } from '@kit.ArkUI' | ||
| 2 | +import { DateTimeUtils, NumberFormatterUtils, WindowModel } from 'wdKit/Index' | ||
| 3 | + | ||
| 4 | +import { devicePLSensorManager } from 'wdDetailPlayApi/Index' | ||
| 5 | +import { LiveDetailsBean, LiveRoomDataBean } from 'wdBean/Index' | ||
| 6 | +import { WDPlayerController } from 'wdPlayer/Index' | ||
| 7 | + | ||
| 8 | +@Entry | ||
| 9 | +@Component | ||
| 10 | +export struct PlayUIComponent { | ||
| 11 | + playerController: WDPlayerController = new WDPlayerController(); | ||
| 12 | + //菜单键是否可见 | ||
| 13 | + @State isMenuVisible: boolean = true | ||
| 14 | + @State isFullScreen: boolean = false | ||
| 15 | + @Consume liveDetailsBean: LiveDetailsBean | ||
| 16 | + @Consume liveRoomDataBean: LiveRoomDataBean | ||
| 17 | + @State currentTime: string = '' | ||
| 18 | + @State totalTime: string = '' | ||
| 19 | + @State progressVal: number = 0; | ||
| 20 | + //是否处于播放状态中 | ||
| 21 | + @State isPlayStatus: boolean = true | ||
| 22 | + | ||
| 23 | + aboutToAppear(): void { | ||
| 24 | + //播放进度监听 | ||
| 25 | + this.playerController.onTimeUpdate = (position: number, duration: number) => { | ||
| 26 | + this.currentTime = DateTimeUtils.secondToTime(position); | ||
| 27 | + this.totalTime = DateTimeUtils.secondToTime(duration); | ||
| 28 | + this.progressVal = Math.floor(position * 100 / duration); | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + build() { | ||
| 33 | + Column() { | ||
| 34 | + this.getTopUIComponent() | ||
| 35 | + this.getMiddleUIComponent() | ||
| 36 | + this.getBottomUIComponent() | ||
| 37 | + } | ||
| 38 | + .width('100%') | ||
| 39 | + .height('100%') | ||
| 40 | + .alignItems(HorizontalAlign.Start) | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Builder | ||
| 44 | + getTopUIComponent() { | ||
| 45 | + Column() { | ||
| 46 | + Row() { | ||
| 47 | + Image($r('app.media.icon_arrow_left_white')) | ||
| 48 | + .width(24) | ||
| 49 | + .aspectRatio(1) | ||
| 50 | + .visibility(Visibility.None) | ||
| 51 | + .margin({ | ||
| 52 | + right: 10 | ||
| 53 | + }) | ||
| 54 | + Text(this.liveDetailsBean.newsTitle) | ||
| 55 | + .maxLines(1) | ||
| 56 | + .textOverflow({ overflow: TextOverflow.Ellipsis }) | ||
| 57 | + .fontSize('16fp') | ||
| 58 | + .fontWeight(500) | ||
| 59 | + .fontColor(Color.White) | ||
| 60 | + .textAlign(TextAlign.Start) | ||
| 61 | + .layoutWeight(1) | ||
| 62 | + Image($r('app.media.icon_share')) | ||
| 63 | + .width(24) | ||
| 64 | + .aspectRatio(1) | ||
| 65 | + .visibility(Visibility.None) | ||
| 66 | + } | ||
| 67 | + .width('100%') | ||
| 68 | + .alignItems(VerticalAlign.Center) | ||
| 69 | + .margin({ | ||
| 70 | + bottom: 5 | ||
| 71 | + }) | ||
| 72 | + | ||
| 73 | + this.getLiveStatusView() | ||
| 74 | + }.width('100%') | ||
| 75 | + .padding({ | ||
| 76 | + top: 10, | ||
| 77 | + bottom: 6, | ||
| 78 | + left: 10, | ||
| 79 | + right: 10 | ||
| 80 | + }) | ||
| 81 | + .alignItems(HorizontalAlign.Start) | ||
| 82 | + .visibility(this.isMenuVisible ? Visibility.Visible : Visibility.None) | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + @Builder | ||
| 86 | + getLiveStatusView() { | ||
| 87 | + //预约 | ||
| 88 | + //直播中 | ||
| 89 | + //回看 | ||
| 90 | + Row() { | ||
| 91 | + Text('回看') | ||
| 92 | + .fontSize('11fp') | ||
| 93 | + .fontWeight(400) | ||
| 94 | + .fontColor(Color.White) | ||
| 95 | + Image($r('app.media.icon_live_player_status_end')) | ||
| 96 | + .width(12) | ||
| 97 | + .height(12) | ||
| 98 | + Text(`${NumberFormatterUtils.formatNumberWithWan(this.liveRoomDataBean.pv)}人参与`) | ||
| 99 | + .fontSize('11fp') | ||
| 100 | + .fontWeight(400) | ||
| 101 | + .fontColor(Color.White) | ||
| 102 | + } | ||
| 103 | + .backgroundColor('#4D000000') | ||
| 104 | + .padding({ | ||
| 105 | + left: 4, | ||
| 106 | + top: 1, | ||
| 107 | + right: 4, | ||
| 108 | + bottom: 1 | ||
| 109 | + }) | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + @Builder | ||
| 113 | + getMiddleUIComponent() { | ||
| 114 | + Stack() | ||
| 115 | + .layoutWeight(1) | ||
| 116 | + .width('100%') | ||
| 117 | + .onClick(() => { | ||
| 118 | + this.isMenuVisible = !this.isMenuVisible | ||
| 119 | + }) | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + @Builder | ||
| 123 | + getBottomUIComponent() { | ||
| 124 | + Row() { | ||
| 125 | + this.playOrPauseBtn() | ||
| 126 | + Text(this.currentTime) | ||
| 127 | + .fontColor(Color.White) | ||
| 128 | + .fontWeight(600) | ||
| 129 | + .fontSize('12fp') | ||
| 130 | + .margin({ | ||
| 131 | + left: 16 | ||
| 132 | + }) | ||
| 133 | + | ||
| 134 | + this.playProgressView() | ||
| 135 | + | ||
| 136 | + Text(this.totalTime) | ||
| 137 | + .fontColor(Color.White) | ||
| 138 | + .fontWeight(600) | ||
| 139 | + .fontSize('12fp') | ||
| 140 | + .margin({ | ||
| 141 | + right: 16 | ||
| 142 | + }) | ||
| 143 | + Image($r('app.media.icon_live_player_full_screen')) | ||
| 144 | + .width(24) | ||
| 145 | + .height(24) | ||
| 146 | + .onClick(() => { | ||
| 147 | + this.isFullScreen = !this.isFullScreen | ||
| 148 | + WindowModel.shared.setPreferredOrientation(this.isFullScreen ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT); | ||
| 149 | + devicePLSensorManager.devicePLSensorOn(this.isFullScreen ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT); | ||
| 150 | + }) | ||
| 151 | + } | ||
| 152 | + .alignItems(VerticalAlign.Center) | ||
| 153 | + .linearGradient({ angle: 0, colors: [['#99000000', 0], ['#00000000', 1]] }) | ||
| 154 | + .width('100%') | ||
| 155 | + .padding({ | ||
| 156 | + left: 10, | ||
| 157 | + right: 10, | ||
| 158 | + top: 15, | ||
| 159 | + bottom: 15 | ||
| 160 | + }) | ||
| 161 | + .visibility(this.isMenuVisible ? Visibility.Visible : Visibility.None) | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + @Builder | ||
| 165 | + playOrPauseBtn() { | ||
| 166 | + //暂停、播放 | ||
| 167 | + Image(this.isPlayStatus ? $r('app.media.icon_live_player_pause') : $r('app.media.player_play_ic')) | ||
| 168 | + .width(24) | ||
| 169 | + .height(24) | ||
| 170 | + .onClick(() => { | ||
| 171 | + if (this.isPlayStatus) { | ||
| 172 | + this.isPlayStatus = false | ||
| 173 | + this.playerController.pause() | ||
| 174 | + } else { | ||
| 175 | + this.isPlayStatus = true | ||
| 176 | + this.playerController.play() | ||
| 177 | + } | ||
| 178 | + }) | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + @Builder | ||
| 182 | + playProgressView() { | ||
| 183 | + Slider({ | ||
| 184 | + value: this.progressVal, | ||
| 185 | + step: 1, | ||
| 186 | + // style: SliderStyle.OutSet | ||
| 187 | + }) | ||
| 188 | + .blockStyle({ | ||
| 189 | + type: SliderBlockType.IMAGE, | ||
| 190 | + image: $r('app.media.ic_player_block') | ||
| 191 | + }) | ||
| 192 | + .blockColor(Color.White) | ||
| 193 | + .trackColor('#4DFFFFFF') | ||
| 194 | + .selectedColor('#FFED2800') | ||
| 195 | + .height(2) | ||
| 196 | + .trackThickness(1) | ||
| 197 | + .layoutWeight(1) | ||
| 198 | + .margin({ | ||
| 199 | + left: 8, | ||
| 200 | + right: 8 | ||
| 201 | + }) | ||
| 202 | + .onChange((value: number, mode: SliderChangeMode) => { | ||
| 203 | + this.playerController?.setSeekTime(value, mode); | ||
| 204 | + }) | ||
| 205 | + } | ||
| 206 | +} |
| 1 | -import { WDPlayerController, WDPlayerRenderView } from 'wdPlayer/Index'; | 1 | +import { LiveDetailsBean } from 'wdBean/Index'; |
| 2 | +import { WDPlayerController, WDPlayerRenderLiveView } from 'wdPlayer/Index'; | ||
| 3 | +import { PlayUIComponent } from './PlayUIComponent'; | ||
| 2 | 4 | ||
| 3 | @Component | 5 | @Component |
| 4 | export struct TopPlayComponent { | 6 | export struct TopPlayComponent { |
| 5 | - @Prop playUrl: string='' | ||
| 6 | - aspectRatioPlayer: number = 375 / 211 | ||
| 7 | - @State playerController: WDPlayerController = new WDPlayerController(); | 7 | + @Consume @Watch('updateData') liveDetailsBean: LiveDetailsBean |
| 8 | + playerController: WDPlayerController = new WDPlayerController(); | ||
| 8 | 9 | ||
| 9 | aboutToAppear(): void { | 10 | aboutToAppear(): void { |
| 10 | - setTimeout(() => { | ||
| 11 | - this.playerController.switchPlayOrPause() | ||
| 12 | - },2000) | 11 | + this.playerController.onCanplay = () => { |
| 12 | + this.playerController.play() | ||
| 13 | + } | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + updateData() { | ||
| 17 | + if (this.liveDetailsBean.liveInfo && this.liveDetailsBean.liveInfo.vlive.length > 0) { | ||
| 18 | + let playUrl: string = this.liveDetailsBean.liveInfo.vlive[0].replayUri | ||
| 19 | + this.playerController.firstPlay(playUrl); | ||
| 20 | + } | ||
| 13 | } | 21 | } |
| 14 | 22 | ||
| 15 | build() { | 23 | build() { |
| 16 | Stack() { | 24 | Stack() { |
| 17 | - WDPlayerRenderView({ | 25 | + WDPlayerRenderLiveView({ |
| 18 | playerController: this.playerController, | 26 | playerController: this.playerController, |
| 19 | onLoad: async () => { | 27 | onLoad: async () => { |
| 20 | - this.playerController.firstPlay(this.playUrl); | ||
| 21 | } | 28 | } |
| 22 | }) | 29 | }) |
| 23 | .height('100%') | 30 | .height('100%') |
| 24 | .width('100%') | 31 | .width('100%') |
| 25 | - .onClick(() => { | ||
| 26 | - console.error('WDPlayerRenderView=== onClick') | ||
| 27 | - this.playerController?.switchPlayOrPause(); | ||
| 28 | - }) | 32 | + PlayUIComponent({ playerController: this.playerController }) |
| 29 | } | 33 | } |
| 30 | .height(211) | 34 | .height(211) |
| 31 | - .aspectRatio(this.aspectRatioPlayer) | ||
| 32 | - .backgroundColor(Color.Black) | 35 | + .width('100%') |
| 33 | } | 36 | } |
| 34 | 37 | ||
| 35 | aboutToDisappear(): void { | 38 | aboutToDisappear(): void { |
| 39 | + this.playerController.pause() | ||
| 36 | } | 40 | } |
| 37 | } | 41 | } |
| @@ -9,6 +9,11 @@ | @@ -9,6 +9,11 @@ | ||
| 9 | "2in1" | 9 | "2in1" |
| 10 | ], | 10 | ], |
| 11 | "deliveryWithInstall": true, | 11 | "deliveryWithInstall": true, |
| 12 | - "pages": "$profile:main_pages" | 12 | + "pages": "$profile:main_pages", |
| 13 | + "requestPermissions": [ | ||
| 14 | + { | ||
| 15 | + "name":"ohos.permission.ACCELEROMETER" | ||
| 16 | + } | ||
| 17 | + ] | ||
| 13 | } | 18 | } |
| 14 | } | 19 | } |
4.9 KB
sight_harmony/features/wdDetailPlayLive/src/main/resources/base/media/ic_player_block.png
0 → 100644
736 Bytes
sight_harmony/features/wdDetailPlayLive/src/main/resources/base/media/icon_arrow_left_white.png
0 → 100644
570 Bytes
439 Bytes
sight_harmony/features/wdDetailPlayLive/src/main/resources/base/media/icon_live_player_pause.png
0 → 100644
581 Bytes
318 Bytes
2.09 KB
2.13 KB
| @@ -2,6 +2,8 @@ export { WDPlayerController } from "./src/main/ets/controller/WDPlayerController | @@ -2,6 +2,8 @@ export { WDPlayerController } from "./src/main/ets/controller/WDPlayerController | ||
| 2 | 2 | ||
| 3 | export { WDPlayerRenderView } from "./src/main/ets/pages/WDPlayerRenderView" | 3 | export { WDPlayerRenderView } from "./src/main/ets/pages/WDPlayerRenderView" |
| 4 | 4 | ||
| 5 | +export { WDPlayerRenderLiveView } from "./src/main/ets/pages/WDPlayerRenderLiveView" | ||
| 6 | + | ||
| 5 | export { PlayerConstants } from "./src/main/ets/constants/PlayerConstants" | 7 | export { PlayerConstants } from "./src/main/ets/constants/PlayerConstants" |
| 6 | 8 | ||
| 7 | export { SpeedBean } from "./src/main/ets/bean/SpeedBean" | 9 | export { SpeedBean } from "./src/main/ets/bean/SpeedBean" |
| 1 | +import componentUtils from '@ohos.arkui.componentUtils'; | ||
| 2 | +import { WDPlayerController } from '../controller/WDPlayerController' | ||
| 3 | +import { WindowModel } from 'wdKit'; | ||
| 4 | +import { Logger } from '../utils/Logger'; | ||
| 5 | + | ||
| 6 | +class Size { | ||
| 7 | + width: Length = "100%"; | ||
| 8 | + height: Length = "100%"; | ||
| 9 | + | ||
| 10 | + constructor(width: Length, height: Length) { | ||
| 11 | + this.width = width; | ||
| 12 | + this.height = height; | ||
| 13 | + } | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +let insIndex: number = 0; | ||
| 17 | +const TAG = 'WDPlayerRenderLiveView' | ||
| 18 | + | ||
| 19 | +class MGPlayRenderViewIns { | ||
| 20 | + static intCount: number = 0; | ||
| 21 | + | ||
| 22 | + static add() { | ||
| 23 | + MGPlayRenderViewIns.intCount++; | ||
| 24 | + WindowModel.shared.setWindowKeepScreenOn(true); | ||
| 25 | + console.log("add-- +1") | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + static del() { | ||
| 29 | + console.log("del-- -1") | ||
| 30 | + MGPlayRenderViewIns.intCount--; | ||
| 31 | + if (MGPlayRenderViewIns.intCount <= 0) { | ||
| 32 | + WindowModel.shared.setWindowKeepScreenOn(false); | ||
| 33 | + } | ||
| 34 | + } | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +/** | ||
| 38 | + * 播放窗口组件 | ||
| 39 | + */ | ||
| 40 | +@Component | ||
| 41 | +export struct WDPlayerRenderLiveView { | ||
| 42 | + private playerController?: WDPlayerController; | ||
| 43 | + private xComponentController: XComponentController = new XComponentController(); | ||
| 44 | + onLoad?: ((event?: object) => void); | ||
| 45 | + videoWidth: number = 0 | ||
| 46 | + videoHeight: number = 0 | ||
| 47 | + @State selfSize: Size = new Size('100%', '100%'); | ||
| 48 | + private insId: string = "WDPlayRenderView" + insIndex; | ||
| 49 | + | ||
| 50 | + aboutToAppear() { | ||
| 51 | + MGPlayRenderViewIns.add(); | ||
| 52 | + | ||
| 53 | + console.log('playerController', this.playerController) | ||
| 54 | + insIndex++; | ||
| 55 | + if (!this.playerController) { | ||
| 56 | + return | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + this.playerController.onVideoSizeChange = (width: number, height: number) => { | ||
| 60 | + // console.log(`WDPlayerRenderView onVideoSizeChange width:${width} videoTop:${height}`) | ||
| 61 | + Logger.info(TAG, ` onVideoSizeChange width:${width} videoTop:${height}`) | ||
| 62 | + this.videoWidth = width; | ||
| 63 | + this.videoHeight = height; | ||
| 64 | + this.updateLayout() | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + aboutToDisappear() { | ||
| 69 | + Logger.info(TAG, `aboutToDisappear`) | ||
| 70 | + MGPlayRenderViewIns.del(); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + build() { | ||
| 74 | + Row() { | ||
| 75 | + // 设置为“surface“类型时XComponent组件可以和其他组件一起进行布局和渲染。 | ||
| 76 | + XComponent({ | ||
| 77 | + id: 'xComponentId', | ||
| 78 | + type: 'surface', | ||
| 79 | + controller: this.xComponentController | ||
| 80 | + }) | ||
| 81 | + .onLoad(async (event) => { | ||
| 82 | + Logger.info(TAG, 'onLoad') | ||
| 83 | + let surfaceId = this.xComponentController.getXComponentSurfaceId() | ||
| 84 | + console.log('surfaceId===', surfaceId) | ||
| 85 | + console.log('insId===', this.insId) | ||
| 86 | + this.xComponentController.setXComponentSurfaceSize({ | ||
| 87 | + surfaceWidth: 1920, | ||
| 88 | + surfaceHeight: 1080 | ||
| 89 | + }); | ||
| 90 | + this.playerController?.setXComponentController(this.xComponentController) | ||
| 91 | + if (this.onLoad) { | ||
| 92 | + this.onLoad(event) | ||
| 93 | + } | ||
| 94 | + }) | ||
| 95 | + .width(this.selfSize.width) | ||
| 96 | + .height(this.selfSize.height) | ||
| 97 | + } | ||
| 98 | + .id(this.insId) | ||
| 99 | + .onAreaChange(() => { | ||
| 100 | + // this.updateLayout() | ||
| 101 | + }) | ||
| 102 | + .backgroundColor("#000000") | ||
| 103 | + .justifyContent(FlexAlign.Center) | ||
| 104 | + .height('100%') | ||
| 105 | + .width('100%') | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + updateLayout() { | ||
| 109 | + let info = componentUtils.getRectangleById(this.insId); | ||
| 110 | + if (info.size.width > 0 && info.size.height > 0 && this.videoHeight > 0 && this.videoWidth > 0) { | ||
| 111 | + if (info.size.width / info.size.height > this.videoWidth / this.videoHeight) { | ||
| 112 | + let scale = info.size.height / this.videoHeight; | ||
| 113 | + this.selfSize = new Size((this.videoWidth * scale / info.size.width) * 100 + "%", '100%'); | ||
| 114 | + } else { | ||
| 115 | + let scale = info.size.width / this.videoWidth; | ||
| 116 | + this.selfSize = new Size('100%', (this.videoHeight * scale / info.size.height) * 100 + "%"); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | +} |
-
Please register or login to post a comment