zhenghy

竖屏直播

@@ -5,6 +5,7 @@ import { WindowModel } from 'wdKit/Index'; @@ -5,6 +5,7 @@ import { WindowModel } from 'wdKit/Index';
5 import { PlayerComponent } from '../widgets/vertical/PlayerComponent'; 5 import { PlayerComponent } from '../widgets/vertical/PlayerComponent';
6 import { PlayerInfoComponent } from '../widgets/vertical/PlayerInfoComponent'; 6 import { PlayerInfoComponent } from '../widgets/vertical/PlayerInfoComponent';
7 import { WDPlayerController } from 'wdPlayer/Index'; 7 import { WDPlayerController } from 'wdPlayer/Index';
  8 +import { DisplayDirection } from 'wdConstant/Index';
8 9
9 const storage = LocalStorage.getShared(); 10 const storage = LocalStorage.getShared();
10 11
@@ -21,6 +22,7 @@ export struct DetailPlayVLivePage { @@ -21,6 +22,7 @@ export struct DetailPlayVLivePage {
21 @Provide liveRoomDataBean: LiveRoomDataBean = {} as LiveRoomDataBean 22 @Provide liveRoomDataBean: LiveRoomDataBean = {} as LiveRoomDataBean
22 @Provide isShowControl: boolean = false 23 @Provide isShowControl: boolean = false
23 @Provide liveState: string = '' 24 @Provide liveState: string = ''
  25 + @Provide displayDirection: DisplayDirection = DisplayDirection.VERTICAL //横竖屏,默认竖屏
24 @State relId: string = '' 26 @State relId: string = ''
25 @State contentId: string = '' 27 @State contentId: string = ''
26 @State relType: string = '' 28 @State relType: string = ''
@@ -43,7 +45,6 @@ export struct DetailPlayVLivePage { @@ -43,7 +45,6 @@ export struct DetailPlayVLivePage {
43 aboutToDisappear(): void { 45 aboutToDisappear(): void {
44 WindowModel.shared.setWindowLayoutFullScreen(false) 46 WindowModel.shared.setWindowLayoutFullScreen(false)
45 WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#000000', }) 47 WindowModel.shared.setWindowSystemBarProperties({ statusBarContentColor: '#000000', })
46 -  
47 } 48 }
48 49
49 build() { 50 build() {
@@ -52,9 +53,6 @@ export struct DetailPlayVLivePage { @@ -52,9 +53,6 @@ export struct DetailPlayVLivePage {
52 PlayerComponent({ 53 PlayerComponent({
53 playerController: this.playerController 54 playerController: this.playerController
54 }) 55 })
55 - .onClick(() => {  
56 - this.isShowControl = !this.isShowControl  
57 - })  
58 56
59 PlayerInfoComponent({ 57 PlayerInfoComponent({
60 playerController: this.playerController, 58 playerController: this.playerController,
@@ -67,7 +65,8 @@ export struct DetailPlayVLivePage { @@ -67,7 +65,8 @@ export struct DetailPlayVLivePage {
67 .aspectRatio(1) 65 .aspectRatio(1)
68 .visibility(this.swiperIndex === 0 ? Visibility.Visible : Visibility.Hidden) 66 .visibility(this.swiperIndex === 0 ? Visibility.Visible : Visibility.Hidden)
69 .animation({ duration: 500 }) 67 .animation({ duration: 500 })
70 - .position({ x: '90%', y: '90%' }) 68 + .position({ x: '100%', y: '100%' })
  69 + .markAnchor({ x: 56, y: 56 })
71 .onClick(() => { 70 .onClick(() => {
72 this.swiperController.showNext() 71 this.swiperController.showNext()
73 }) 72 })
1 -import { LiveDetailsBean } from 'wdBean/Index';  
2 -import { WDPlayerController, WDPlayerRenderView } from 'wdPlayer/Index';  
3 -import { PlayUIComponent } from './PlayUIComponent';  
4 -  
5 -@Component  
6 -export struct TopPlayVComponent {  
7 - @Consume @Watch('updateData') liveDetailsBean: LiveDetailsBean  
8 - playerController: WDPlayerController = new WDPlayerController();  
9 -  
10 - aboutToAppear(): void {  
11 - this.playerController.onCanplay = () => {  
12 - this.playerController.play()  
13 - }  
14 - }  
15 -  
16 - updateData() {  
17 - //直播新闻-直播状态 wait待开播running直播中end已结束cancel已取消paused暂停  
18 - if (this.liveDetailsBean.liveInfo && this.liveDetailsBean.liveInfo.vlive.length > 0) {  
19 - let playUrl = ''  
20 - if (this.liveDetailsBean.liveInfo.liveState == 'running') {  
21 - playUrl = this.liveDetailsBean.liveInfo.vlive[0].liveUrl  
22 - } else if (this.liveDetailsBean.liveInfo.liveState == 'end') {  
23 - playUrl = this.liveDetailsBean.liveInfo.vlive[0].replayUri  
24 - }  
25 - this.playerController.firstPlay(playUrl);  
26 - }  
27 - }  
28 -  
29 - build() {  
30 - Stack() {  
31 - // https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-image-effect-0000001862607345  
32 - Image(this.liveDetailsBean.fullColumnImgUrls[0].url)  
33 - .height('100%')  
34 - .width('100%')  
35 - .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])  
36 - .blur(100)  
37 -  
38 - WDPlayerRenderView({  
39 - playerController: this.playerController,  
40 - onLoad: async () => {  
41 - }  
42 - })// .height('100%')  
43 - .width('100%')// 扩展至所有非安全区域  
44 - .onClick(() => {  
45 - this.playerController.play()  
46 - })  
47 - // PlayUIComponent({ playerController: this.playerController })  
48 - }  
49 - // .height('100%')  
50 - .width('100%')  
51 - // 扩展至所有非安全区域  
52 - .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])  
53 - }  
54 -  
55 - aboutToDisappear(): void {  
56 - this.playerController.pause()  
57 - }  
58 -}  
  1 +import { LiveDetailsBean } from 'wdBean/Index'
  2 +
  3 +@Component
  4 +export struct ChartItemCompereComponent {
  5 + @Consume liveDetailsBean: LiveDetailsBean
  6 +
  7 + aboutToAppear(): void {
  8 + }
  9 +
  10 + build() {
  11 + ListItem() {
  12 + Column() {
  13 + Row() {
  14 + Image($r('app.media.icon_live_status_running'))
  15 + .borderRadius(10)
  16 + .width(20)
  17 + .height(20)
  18 + .margin({ right: 8 })
  19 +
  20 + Text('人民日报')
  21 + .fontSize(14)
  22 + .fontColor('#FFFFFFFF')
  23 + .margin({ right: 8 })
  24 +
  25 + Text(' 主持人 ')
  26 + .fontSize(11)
  27 + .backgroundColor('808562')
  28 + .fontColor('#FFFFFFFF')
  29 + .padding({ top: 2, bottom: 2, left: 4, right: 4 })
  30 + .borderRadius(4)
  31 + }.margin({ bottom: 8 })
  32 +
  33 + Text(this.liveDetailsBean.newIntroduction).lineHeight(22)
  34 + }
  35 + .backgroundColor('#4D000000')
  36 + .borderRadius(3)
  37 + .padding({
  38 + top: 6,
  39 + bottom: 6,
  40 + left: 8,
  41 + right: 8
  42 + })
  43 + .margin({ left: 16, bottom: 4 })
  44 + }
  45 +
  46 + }
  47 +}
@@ -9,31 +9,35 @@ export struct ChatItemComponent { @@ -9,31 +9,35 @@ export struct ChatItemComponent {
9 9
10 build() { 10 build() {
11 Row() { 11 Row() {
12 - Image(this.item.senderUserAvatarUrl)  
13 - .borderRadius(90)  
14 - .width(24)  
15 - .height(24)  
16 Text() { 12 Text() {
  13 + if (this.item.senderUserName) {
  14 + Span(' 主持人 ')
  15 + .fontSize(11)
  16 + .lineHeight(20)
  17 + .textBackgroundStyle({ color: '#808562', radius: 2 })
  18 + Span(' ')
  19 + }
17 Span(this.item.senderUserName + ': ') 20 Span(this.item.senderUserName + ': ')
18 - .fontColor('#666666') 21 + .fontColor('#FFFFC63F')
  22 + .padding({ right: 118 })
  23 + //
  24 +
19 Span(this.item.text) 25 Span(this.item.text)
20 - .fontColor('#222222')  
21 } 26 }
22 - .margin({ left: 8 })  
23 - .lineHeight(20)  
24 - .layoutWeight(1)  
25 - .fontSize('14fp')  
26 - .fontWeight(400) 27 + .fontSize(14)
  28 + .fontColor('#FFFFFFFF')
  29 + .lineHeight(22)
  30 + .textShadow({ offsetX: 1, offsetY: 1, color: '#4D000000', radius: 1 })
  31 +
27 } 32 }
28 - .alignItems(VerticalAlign.Top) 33 + .backgroundColor('#4D000000')
  34 + .borderRadius(3)
29 .padding({ 35 .padding({
30 - left: 15,  
31 - top: 15,  
32 - right: 15 36 + top: 6,
  37 + bottom: 6,
  38 + left: 8,
  39 + right: 8
33 }) 40 })
34 - }  
35 -  
36 - aboutToDisappear(): void {  
37 - 41 + .margin({ left: 16, bottom: 4 })
38 } 42 }
39 } 43 }
1 -import { LiveDetailsBean, LiveRoomItemBean } from 'wdBean/Index'  
2 -import { EmptyComponent, ErrorComponent, ListHasNoMoreDataUI } from 'wdComponent/Index'  
3 -import CustomRefreshLoadLayout from 'wdComponent/src/main/ets/components/page/CustomRefreshLoadLayout'  
4 -import LoadMoreLayout from 'wdComponent/src/main/ets/components/page/LoadMoreLayout'  
5 -import RefreshLayout from 'wdComponent/src/main/ets/components/page/RefreshLayout'  
6 -import { RefreshLayoutBean } from 'wdComponent/src/main/ets/components/page/RefreshLayoutBean' 1 +import { LiveDetailsBean, LiveRoomDataBean, LiveRoomItemBean } from 'wdBean/Index'
  2 +import { LiveCommentComponent } from 'wdComponent/Index'
7 import PageModel from 'wdComponent/src/main/ets/viewmodel/PageModel' 3 import PageModel from 'wdComponent/src/main/ets/viewmodel/PageModel'
8 -import { ViewType } from 'wdConstant/Index' 4 +import { DisplayDirection, ViewType } from 'wdConstant/Index'
9 import { LiveViewModel } from '../../viewModel/LiveViewModel' 5 import { LiveViewModel } from '../../viewModel/LiveViewModel'
10 -import { TabChatItemComponent } from '../details/TabChatItemComponent' 6 +import { ChartItemCompereComponent } from './ChartItemCompereComponent'
  7 +import { ChatItemComponent } from './ChartItemComponent'
11 8
12 9
13 @Component 10 @Component
14 export struct PlayerCommentComponent { 11 export struct PlayerCommentComponent {
15 liveViewModel: LiveViewModel = new LiveViewModel() 12 liveViewModel: LiveViewModel = new LiveViewModel()
16 - @Consume liveDetailsBean: LiveDetailsBean 13 + @Consume @Watch('liveDetailsBeanChange') liveDetailsBean: LiveDetailsBean
  14 + @Consume liveRoomDataBean: LiveRoomDataBean
  15 + @Consume displayDirection: DisplayDirection
17 @State private pageModel: PageModel = new PageModel() 16 @State private pageModel: PageModel = new PageModel()
18 @State liveChatList: Array<LiveRoomItemBean> = [] 17 @State liveChatList: Array<LiveRoomItemBean> = []
19 18
@@ -21,6 +20,10 @@ export struct PlayerCommentComponent { @@ -21,6 +20,10 @@ export struct PlayerCommentComponent {
21 this.getLiveChatList() 20 this.getLiveChatList()
22 } 21 }
23 22
  23 + liveDetailsBeanChange() {
  24 + this.getLiveChatList()
  25 + }
  26 +
24 getLiveChatList() { 27 getLiveChatList() {
25 this.pageModel.currentPage = 1 28 this.pageModel.currentPage = 1
26 this.liveViewModel.getLiveChatList( 29 this.liveViewModel.getLiveChatList(
@@ -31,8 +34,10 @@ export struct PlayerCommentComponent { @@ -31,8 +34,10 @@ export struct PlayerCommentComponent {
31 .then( 34 .then(
32 (data) => { 35 (data) => {
33 if (data.barrageResponses && data.barrageResponses.length > 0) { 36 if (data.barrageResponses && data.barrageResponses.length > 0) {
  37 +
34 this.pageModel.viewType = ViewType.LOADED; 38 this.pageModel.viewType = ViewType.LOADED;
35 this.liveChatList.push(...data.barrageResponses) 39 this.liveChatList.push(...data.barrageResponses)
  40 + console.log('liveChatList===', this.liveChatList)
36 if (data.barrageResponses.length === this.pageModel.pageSize) { 41 if (data.barrageResponses.length === this.pageModel.pageSize) {
37 this.pageModel.currentPage++; 42 this.pageModel.currentPage++;
38 this.pageModel.hasMore = true; 43 this.pageModel.hasMore = true;
@@ -49,58 +54,27 @@ export struct PlayerCommentComponent { @@ -49,58 +54,27 @@ export struct PlayerCommentComponent {
49 } 54 }
50 55
51 build() { 56 build() {
52 - Stack() {  
53 - if (this.pageModel.viewType == ViewType.LOADING) {  
54 - this.LoadingLayout()  
55 - } else if (this.pageModel.viewType == ViewType.ERROR) {  
56 - ErrorComponent()  
57 - } else if (this.pageModel.viewType == ViewType.EMPTY) {  
58 - EmptyComponent()  
59 - } else {  
60 - this.ListLayout()  
61 - }  
62 - }  
63 - .align(Alignment.Top)  
64 - // .backgroundColor('#F5F5F5')  
65 - .height('100%')  
66 - .width('100%')  
67 - }  
68 -  
69 - @Builder  
70 - LoadingLayout() {  
71 - CustomRefreshLoadLayout({  
72 - refreshBean: new RefreshLayoutBean(true,  
73 - $r('app.media.ic_pull_up_load'), $r('app.string.pull_up_load_text'), this.pageModel.pullDownRefreshHeight)  
74 - })  
75 - }  
76 -  
77 - @Builder  
78 - ListLayout() {  
79 - List() {  
80 - ListItem() {  
81 - // 下拉刷新  
82 - RefreshLayout({  
83 - refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullDown, this.pageModel.pullDownRefreshImage,  
84 - this.pageModel.pullDownRefreshText, this.pageModel.pullDownRefreshHeight) 57 + Column() {
  58 + List() {
  59 + // 主持人
  60 + if (this.liveDetailsBean.oldNewsId) {
  61 + ChartItemCompereComponent()
  62 + }
  63 + ForEach(this.liveChatList, (item: LiveRoomItemBean) => {
  64 + ListItem() {
  65 + ChatItemComponent({ item: item })
  66 + }
85 }) 67 })
86 } 68 }
  69 + .height(280)
  70 + .width('80%')
  71 + .scrollBar(BarState.Off)
  72 + .margin({ bottom: 20 })
  73 +
  74 + LiveCommentComponent({ heartNum: this.liveRoomDataBean.likeNum })
  75 + .visibility(this.displayDirection == DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None)
  76 + .backgroundColor(Color.Transparent)
  77 + }.alignItems(HorizontalAlign.Start)
87 78
88 - ForEach(this.liveChatList, (item: LiveRoomItemBean) => {  
89 - ListItem() {  
90 - TabChatItemComponent({ item: item })  
91 - }  
92 - })  
93 - // 加载更多  
94 - ListItem() {  
95 - if (this.pageModel.hasMore) {  
96 - LoadMoreLayout({  
97 - refreshBean: new RefreshLayoutBean(this.pageModel.isVisiblePullUpLoad, this.pageModel.pullUpLoadImage,  
98 - this.pageModel.pullUpLoadText, this.pageModel.pullUpLoadHeight)  
99 - })  
100 - } else {  
101 - ListHasNoMoreDataUI()  
102 - }  
103 - }  
104 - }  
105 } 79 }
106 } 80 }
@@ -80,7 +80,7 @@ export struct PlayerComponent { @@ -80,7 +80,7 @@ export struct PlayerComponent {
80 onLoad: () => { 80 onLoad: () => {
81 this.playerController?.firstPlay(this.playUrl); 81 this.playerController?.firstPlay(this.playUrl);
82 } 82 }
83 - }).padding({ top: 195 }) 83 + }).margin({ top: 195 }).height(211)
84 } 84 }
85 } 85 }
86 .height('100%') 86 .height('100%')
@@ -7,6 +7,8 @@ export struct PlayerInfoComponent { @@ -7,6 +7,8 @@ export struct PlayerInfoComponent {
7 private playerController?: WDPlayerController 7 private playerController?: WDPlayerController
8 @Consume bottomSafeHeight: number 8 @Consume bottomSafeHeight: number
9 @Consume topSafeHeight: number 9 @Consume topSafeHeight: number
  10 + @Consume liveState: string
  11 + @Consume isShowControl: boolean
10 @Link swiperIndex: number 12 @Link swiperIndex: number
11 13
12 build() { 14 build() {
@@ -17,7 +19,6 @@ export struct PlayerInfoComponent { @@ -17,7 +19,6 @@ export struct PlayerInfoComponent {
17 bottom: this.bottomSafeHeight + 'px', 19 bottom: this.bottomSafeHeight + 'px',
18 top: this.topSafeHeight + 'px' 20 top: this.topSafeHeight + 'px'
19 }) 21 })
20 -  
21 } 22 }
22 .cachedCount(2) 23 .cachedCount(2)
23 .indicator(false) 24 .indicator(false)
@@ -25,6 +26,11 @@ export struct PlayerInfoComponent { @@ -25,6 +26,11 @@ export struct PlayerInfoComponent {
25 .width('100%') 26 .width('100%')
26 .height('100%') 27 .height('100%')
27 .index(this.swiperIndex) 28 .index(this.swiperIndex)
  29 + .onClick(() => {
  30 + if (this.liveState === 'end') {
  31 + this.isShowControl = !this.isShowControl
  32 + }
  33 + })
28 .onChange((index) => { 34 .onChange((index) => {
29 this.swiperIndex = index 35 this.swiperIndex = index
30 }) 36 })
@@ -6,20 +6,27 @@ import { PlayerVideoControlComponent } from './PlayerVideoControlComponent'; @@ -6,20 +6,27 @@ import { PlayerVideoControlComponent } from './PlayerVideoControlComponent';
6 @Component 6 @Component
7 export struct PlayerUIComponent { 7 export struct PlayerUIComponent {
8 private playerController?: WDPlayerController 8 private playerController?: WDPlayerController
9 - @Consume liveState: string 9 + @Consume isShowControl: boolean
10 10
11 build() { 11 build() {
12 - Column() { 12 + Stack() {
13 PlayerTitleComponent() 13 PlayerTitleComponent()
14 - Blank()  
15 - // PlayerCommentComponent().layoutWeight(1)  
16 - if (this.liveState === 'end') { 14 + // Row() {
  15 + // // 全屏按钮
  16 + // }.layoutWeight(1)
  17 +
  18 + Row() {
  19 + PlayerCommentComponent()
17 PlayerVideoControlComponent({ playerController: this.playerController }) 20 PlayerVideoControlComponent({ playerController: this.playerController })
  21 + .visibility(this.isShowControl ? Visibility.Visible : Visibility.Hidden)
  22 + .animation({ duration: 500 })
18 } 23 }
19 - 24 + .position({ y: '100%' })
  25 + .markAnchor({ y: '100%' })
20 } 26 }
21 .height('100%') 27 .height('100%')
22 .width('100%') 28 .width('100%')
  29 + .alignContent(Alignment.TopStart)
23 30
24 } 31 }
25 } 32 }
@@ -11,9 +11,6 @@ export struct PlayerVideoControlComponent { @@ -11,9 +11,6 @@ export struct PlayerVideoControlComponent {
11 private playerController?: WDPlayerController 11 private playerController?: WDPlayerController
12 @Consume liveDetailsBean: LiveDetailsBean 12 @Consume liveDetailsBean: LiveDetailsBean
13 @Consume liveRoomDataBean: LiveRoomDataBean 13 @Consume liveRoomDataBean: LiveRoomDataBean
14 - //菜单键是否可见  
15 - @State isMenuVisible: boolean = true  
16 - @State isFullScreen: boolean = false  
17 @State currentTime: string = '' 14 @State currentTime: string = ''
18 @State totalTime: string = '' 15 @State totalTime: string = ''
19 @State progressVal: number = 0; 16 @State progressVal: number = 0;
@@ -24,7 +21,6 @@ export struct PlayerVideoControlComponent { @@ -24,7 +21,6 @@ export struct PlayerVideoControlComponent {
24 if (this.playerController) { 21 if (this.playerController) {
25 //播放进度监听 22 //播放进度监听
26 this.playerController.onTimeUpdate = (position: number, duration: number) => { 23 this.playerController.onTimeUpdate = (position: number, duration: number) => {
27 - console.log('onTimeUpdate===', position, duration)  
28 this.currentTime = DateFormatUtil.secondToTime(Math.floor(position / 1000)); 24 this.currentTime = DateFormatUtil.secondToTime(Math.floor(position / 1000));
29 this.totalTime = DateFormatUtil.secondToTime(Math.floor(duration / 1000)); 25 this.totalTime = DateFormatUtil.secondToTime(Math.floor(duration / 1000));
30 this.progressVal = Math.floor(position * 100 / duration); 26 this.progressVal = Math.floor(position * 100 / duration);
@@ -61,14 +57,6 @@ export struct PlayerVideoControlComponent { @@ -61,14 +57,6 @@ export struct PlayerVideoControlComponent {
61 right: 16 57 right: 16
62 }) 58 })
63 59
64 - // Image($r('app.media.icon_live_player_full_screen'))  
65 - // .width(24)  
66 - // .height(24)  
67 - // .onClick(() => {  
68 - // this.isFullScreen = !this.isFullScreen  
69 - // WindowModel.shared.setPreferredOrientation(this.isFullScreen ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT);  
70 - // devicePLSensorManager.devicePLSensorOn(this.isFullScreen ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT);  
71 - // })  
72 } 60 }
73 .alignItems(VerticalAlign.Center) 61 .alignItems(VerticalAlign.Center)
74 // .linearGradient({ angle: 0, colors: [['#99000000', 0], ['#00000000', 1]] }) 62 // .linearGradient({ angle: 0, colors: [['#99000000', 0], ['#00000000', 1]] })
@@ -79,7 +67,6 @@ export struct PlayerVideoControlComponent { @@ -79,7 +67,6 @@ export struct PlayerVideoControlComponent {
79 top: 15, 67 top: 15,
80 bottom: 15 68 bottom: 15
81 }) 69 })
82 - .visibility(this.isMenuVisible ? Visibility.Visible : Visibility.None)  
83 } 70 }
84 71
85 @Builder 72 @Builder