zhenghy

视频全屏

import { BottomNavi, CommonConstants } from 'wdConstant';
import { BottomNavi, CommonConstants, DisplayDirection } from 'wdConstant';
import { BottomNavDTO, NavigationBodyDTO, NavigationDetailDTO, TopNavDTO } from 'wdBean';
import { EmitterEventId, EmitterUtils, Logger, StringUtils } from 'wdKit';
import { TopNavigationComponent } from './TopNavigationComponent';
... ... @@ -21,6 +21,7 @@ export struct BottomNavigationComponent {
@Provide bottomRectHeight: number = 0
@Provide topRectHeight: number = 0
@Provide isLayoutFullScreen: boolean = false
@Provide displayDirection: DisplayDirection = DisplayDirection.VERTICAL
@Provide isImmersive: boolean = false // 是否开启沉浸式模式 http://192.168.1.3:3300/project/3802/interface/api/189229
@Provide isNight: boolean = false // 是否开启夜间模式
@Provide currentBottomNavInfo: BottomNavDTO = {} as BottomNavDTO; // 当前底导信息
... ... @@ -73,7 +74,7 @@ export struct BottomNavigationComponent {
TabContent() {
if (CompUtils.isMine(navItem)) {
// 我的页面组件数据列表
MinePageComponent({isMinePage: this.currentNavIndex === this.bottomNavList.length-1})
MinePageComponent({ isMinePage: this.currentNavIndex === this.bottomNavList.length - 1 })
} else if (navItem.name === '视频') {
// 视频频道,包含视频和直播
VideoChannelPage({
... ... @@ -102,7 +103,8 @@ export struct BottomNavigationComponent {
.zIndex(10)
.scrollable(false)
.animationDuration(0)
.barHeight($r('app.float.bottom_navigation_barHeight'))
.barHeight(this.displayDirection === DisplayDirection.VERTICAL ? $r('app.float.bottom_navigation_barHeight') :
0.001)
.barMode(BarMode.Fixed)
.barBackgroundColor(this.barBackgroundColor)
// 备注:鸿蒙目前只有修改三线导航背景方法,对于全面屏导航条手机需要设置背景色并使其扩散到导航区域
... ... @@ -137,6 +139,7 @@ export struct BottomNavigationComponent {
.zIndex(10)
.height($r('app.float.bottom_navigation_barHeight'))
.hoverEffect(HoverEffect.Highlight)
.visibility(this.displayDirection === DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None)
.onClick(() => {
Logger.info(TAG, `onChange, index: ${index}`);
this.onBottomNavigationIndexChange(navItem, index)
... ...
... ... @@ -5,7 +5,8 @@
import { BottomNavDTO, TopNavDTO } from 'wdBean/Index'
import { VideoChannelDetail } from 'wdDetailPlayShortVideo/Index';
import { PageComponent } from './PageComponent';
import { WDRouterPage, WDRouterRule } from 'wdRouter';
import { WDRouterPage, WDRouterRule } from 'wdRouter';
import { DisplayDirection } from 'wdConstant/Index';
const TAG = 'VideoChannelPage'
... ... @@ -19,6 +20,7 @@ export struct VideoChannelPage {
@Prop topNavList: TopNavDTO[]
@Link _currentNavIndex?: number;
@Consume barBackgroundColor: Color
@Consume displayDirection: DisplayDirection
@Consume @Watch('setBarBackgroundColor') currentBottomNavInfo: BottomNavDTO // 当前底导信息
@State @Watch('setBarBackgroundColor') currentTopNavSelectedIndex: number = 0;
@State animationDuration: number = 0
... ... @@ -68,7 +70,7 @@ export struct VideoChannelPage {
@Builder
topNavView() {
Stack({alignContent: Alignment.TopEnd}) {
Stack({ alignContent: Alignment.TopEnd }) {
Row() {
ForEach(this.topNavList, (item: TopNavDTO, index: number) => {
Column() {
... ... @@ -127,6 +129,8 @@ export struct VideoChannelPage {
.backgroundColor(Color.Transparent)
}
.zIndex(20)
.visibility(this.displayDirection === DisplayDirection.VERTICAL ? Visibility.Visible : Visibility.None)
}
... ...
import { ContentDetailDTO, InteractDataDTO } from 'wdBean';
import { WDPlayerController, WDPlayerRenderView } from 'wdPlayer';
import { PlayerConstants, WDPlayerController, WDPlayerRenderView } from 'wdPlayer';
import { ContentDetailRequest } from 'wdDetailPlayApi';
import {
batchLikeAndCollectParams,
... ... @@ -18,6 +18,7 @@ import { PlayerRightView } from '../view/PlayerRightView';
import { DisplayDirection } from 'wdConstant/Index';
import { CommentDialogView } from '../view/CommentDialogView';
import { window } from '@kit.ArkUI';
import { PlayerFullScreenView } from '../view/PlayerFullScreenView';
const TAG = 'DetailPlayShortVideoPage';
... ... @@ -40,6 +41,7 @@ export struct DetailPlayShortVideoPage {
@Provide followStatus: string = '0' // 关注状态
@Provide isOpenDetail: boolean = false // 查看详情按钮点击
@Provide isDragging: boolean = false // 拖动时间进度条
@Provide status: number = PlayerConstants.STATUS_START;
@Consume showCommentList: boolean
@Consume displayDirection: DisplayDirection
@Consume @Watch('videoStatusChange') switchVideoStatus: boolean
... ... @@ -254,16 +256,23 @@ export struct DetailPlayShortVideoPage {
}
}
})
.width('100%')
.height(this.windowWidth / this.ratio + 'px')
.width(this.displayDirection === DisplayDirection.VERTICAL ? '100%' : this.windowWidth * 16 / 9 + 'px')
.height(this.displayDirection === DisplayDirection.VERTICAL ? this.windowWidth / this.ratio + 'px' : '100%')
this.playerCoverBuilder()
// 横屏-全屏观看
// 点击查看详情 不展示
if (this.videoLandScape === 1 && !this.isOpenDetail) {
if (this.videoLandScape === 1 && !this.isOpenDetail && this.displayDirection === DisplayDirection.VERTICAL) {
this.playerFullscreenBuilder()
}
if (this.displayDirection === DisplayDirection.VIDEO_HORIZONTAL && this.index === this.currentIndex) {
PlayerFullScreenView({
playerController: this.playerController
})
}
}
.width('100%')
.height('100%')
... ... @@ -296,7 +305,7 @@ export struct DetailPlayShortVideoPage {
.onClick(() => {
// 全屏方案待定
// this.displayDirection = DisplayDirection.VERTICAL
this.displayDirection = this.displayDirection == DisplayDirection.VERTICAL ?
this.displayDirection = this.displayDirection === DisplayDirection.VERTICAL ?
DisplayDirection.VIDEO_HORIZONTAL :
DisplayDirection.VERTICAL
WindowModel.shared.setPreferredOrientation(this.displayDirection == DisplayDirection.VERTICAL ?
... ...
... ... @@ -52,7 +52,8 @@ export struct VideoChannelDetail {
@Consume @Watch('pageShowChange') pageShow: number
@Consume @Watch('pageHideChange') pageHide: number
@Provide switchVideoStatus: boolean = true
@Provide displayDirection: DisplayDirection = DisplayDirection.VERTICAL
// @Provide displayDirection: DisplayDirection = DisplayDirection.VERTICAL
@Consume displayDirection: DisplayDirection
@Provide showCommentList: boolean = false
@State data: ContentDetailDTO[] = []
@State currentIndex: number = 0
... ...
import { ContentDetailDTO } from 'wdBean/Index'
import { WDShare } from 'wdShare/Index'
import { PlayerProgressFullScreenView } from './PlayerProgressFullScreenView'
import { PlayerConstants, WDPlayerController } from 'wdPlayer/Index'
import { DateTimeUtils, WindowModel } from 'wdKit/Index'
import { DisplayDirection } from 'wdConstant/Index'
import { window } from '@kit.ArkUI'
@Component
export struct PlayerFullScreenView {
private playerController?: WDPlayerController;
@Consume contentDetailData: ContentDetailDTO
@Consume progressVal: number;
@Consume status: number
@Consume displayDirection: DisplayDirection
@Consume isDragging: boolean
@State videoDuration: number = this.contentDetailData?.videoInfo?.[0]?.videoDuration || 1
@State showOperator: boolean = true
private timer: number = -1
getTitle() {
return this.contentDetailData?.newsTitle
// || this.contentDetailData?.newsSummary || ''
}
share() {
WDShare.shareContent(this.contentDetailData)
}
aboutToAppear(): void {
WindowModel.shared.setWindowSystemBarEnable([])
this.timer = setInterval(() => {
this.showOperator = false
}, 5)
}
aboutToDisappear(): void {
WindowModel.shared.setWindowSystemBarEnable(['status', 'navigation'])
clearInterval(this.timer)
}
restartTimer() {
clearInterval(this.timer)
this.timer = setInterval(() => {
this.showOperator = false
}, 5)
}
build() {
Stack() {
this.headerBuilder()
this.bottomBuilder()
}
.zIndex(99999)
.height('100%')
.width('100%')
.onClick(() => {
this.restartTimer()
})
}
@Builder
headerBuilder() {
Row() {
Row() {
Image($r(`app.media.ic_back`)).height(24).width(24)
.onClick(() => {
this.displayDirection = this.displayDirection == DisplayDirection.VERTICAL ?
DisplayDirection.VIDEO_HORIZONTAL :
DisplayDirection.VERTICAL
WindowModel.shared.setPreferredOrientation(this.displayDirection == DisplayDirection.VERTICAL ?
window.Orientation.PORTRAIT :
window.Orientation.LANDSCAPE_INVERTED)
})
Text(this.getTitle())
.fontSize(18)
.fontColor(Color.White)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ left: 10 })
}
Image($r(`app.media.ic_share`)).height(24).width(24)
.onClick(() => {
this.share()
})
}
.width('100%')
.position({ x: 0, y: 0 })
.align(Alignment.Top)
.height(73)
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.SpaceBetween)
.padding({ left: 40, right: 40 })
.linearGradient({
direction: GradientDirection.Bottom, // 渐变方向
colors: [['rgba(0,0,0,0.5)', 0],
['rgba(1,1,1,0)', 1.0]] // 数组末尾元素占比小于1时满足重复着色效果
})
}
@Builder
bottomBuilder() {
Column() {
Text() {
Span(DateTimeUtils.secondToTime(Math.floor(this.progressVal / 100 * this.videoDuration)))
Span(' / ')
Span(DateTimeUtils.secondToTime(this.videoDuration))
}
.fontSize(24)
.fontColor(Color.White)
.fontWeight(600)
.margin({ bottom: 30 })
.visibility(this.isDragging ? Visibility.Visible : Visibility.None)
Row() {
Image($r(`app.media.ic_play`)).height(24).width(24)
.visibility(this.status === PlayerConstants.STATUS_START ? Visibility.None : Visibility.Visible)
.onClick(() => {
this.playerController?.switchPlayOrPause()
})
Image($r(`app.media.ic_pause`)).height(24).width(24)
.visibility(this.status === PlayerConstants.STATUS_PAUSE ? Visibility.None : Visibility.Visible)
.onClick(() => {
this.playerController?.switchPlayOrPause()
})
Text(DateTimeUtils.secondToTime(Math.ceil((this.progressVal / 100 * this.videoDuration))))
.fontSize(12)
.fontWeight(600)
.fontColor(Color.White)
.margin({ left: 16, right: 8 })
PlayerProgressFullScreenView({ playerController: this.playerController }).layoutWeight(1)
Text(DateTimeUtils.secondToTime(this.videoDuration))
.fontSize(12)
.fontWeight(600)
.fontColor(Color.White)
.margin({ left: 16 })
}
.width('100%')
.height(73)
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.position({ x: 0, y: '100%' })
.markAnchor({ y: '100%' })
.align(Alignment.Bottom)
.padding({ left: 40, right: 40 })
.linearGradient({
direction: GradientDirection.Bottom, // 渐变方向
colors: [['rgba(0,0,0,0.5)', 0],
['rgba(1,1,1,0)', 1.0]] // 数组末尾元素占比小于1时满足重复着色效果
})
}
}
\ No newline at end of file
... ...
import { ContentDetailDTO } from 'wdBean/Index';
import { DateTimeUtils } from 'wdKit/Index';
import { PlayerConstants, WDPlayerController } from 'wdPlayer/Index';
@Component
export struct PlayerProgressFullScreenView {
private playerController?: WDPlayerController;
@Consume contentDetailData: ContentDetailDTO
@Consume progressVal: number;
@Consume isOpenDetail: boolean
@Consume isDragging: boolean
@Consume status: number
@State videoDuration: number = this.contentDetailData?.videoInfo?.[0]?.videoDuration || 1
aboutToAppear() {
if (this.playerController) {
this.playerController.onSeekDone = (status: number) => {
this.playerController?.play()
}
}
}
build() {
Column() {
Slider({
value: this.progressVal,
step: 0.01,
// style: SliderStyle.OutSet
})
.blockColor($r('app.color.play_block_color'))
.trackColor($r('app.color.pause_track_color'))
.selectedColor($r('app.color.pause_selected_color'))
.trackThickness(4)
.blockStyle({
type: SliderBlockType.IMAGE,
image: $r('app.media.ic_player_block')
})
.blockSize({ width: 18, height: 12 })
.width('100%')
.height(19)
.onChange((value: number, mode: SliderChangeMode) => {
this.progressVal = value
if (mode === SliderChangeMode.Moving) {
this.isDragging = true
}
if (mode === SliderChangeMode.End) {
this.isDragging = false
}
this.playerController?.setSeekTime(value, mode);
console.log('slider onChange:', value, mode)
})
}
}
}
\ No newline at end of file
... ...
... ... @@ -9,7 +9,7 @@ export struct PlayerProgressView {
@Consume progressVal: number;
@Consume isOpenDetail: boolean
@Consume isDragging: boolean
@State status: number = PlayerConstants.STATUS_START;
@Consume status: number
@State videoDuration: number = this.contentDetailData?.videoInfo?.[0]?.videoDuration || 1
aboutToAppear() {
... ...