会议回放,观看直播与会议

This commit is contained in:
XiuYun CHEN 2025-05-19 16:42:50 +08:00
parent f44649d8dc
commit f821535e18
25 changed files with 725 additions and 55 deletions

View File

@ -20,7 +20,7 @@ export { preferenceStore } from './src/main/ets/utils/PreferenceStore'
export { LoginInfo,Data } from './src/main/ets/models/LoginInfoModel'
export { DataWebModel } from './src/main/ets/models/DataWebModel'
export { DataWebModel,DataWebModels } from './src/main/ets/models/DataWebModel'
export { PromptActionClass } from './src/main/ets/components/PromptActionClass'
@ -28,4 +28,8 @@ export { RequestDefaultModel,ExpertData } from './src/main/ets/models/RequestDef
export { HdList, HdListController } from './src/main/ets/components/HdList'
export { AESEncryptionDecryption } from './src/main/ets/utils/AESEncryptionDecryption'
export { HdGrid } from './src/main/ets/components/HdGrid'

View File

@ -0,0 +1,113 @@
import { BasicConstant } from '../constants/BasicConstant'
import { HdListController } from '../components/HdList'
@Component
export struct HdGrid {
@State
refreshing: boolean = false
@State
finished: boolean = false
@State
loading: boolean = false
// options
lw: number = 0
@Builder
defaultListContent() {
}
@BuilderParam
listContent: () => void = this.defaultListContent
// function
onLoad: () => void = () => {
}
onRefresh: () => void = () => {
}
// controller
controller: HdListController = new HdListController()
scroller: Scroller = new Scroller()
aboutToAppear() {
if (this.controller) {
this.controller.loaded = () => this.loading = false
this.controller.finished = () => this.finished = true
this.controller.refreshed = () => this.refreshing = false
this.controller.reload = () => {
this.finished = false
this.refreshing = true
}
}
}
@Builder
loadMoreBuilder() {
GridItem() {
if (this.finished) {
Row() {
Text($r('app.string.hd_list_finished'))
.fontColor(Color.Gray)
.fontSize($r('app.float.hd_list_load_font'))
}
.height($r('app.float.hd_list_load_height'))
.width('100%')
.justifyContent(FlexAlign.Center)
} else if (this.loading && !this.finished) {
Row() {
LoadingProgress()
.width($r('app.float.hd_list_load_icon'))
Text($r('app.string.hd_list_loading'))
.fontColor(Color.Gray)
.fontSize($r('app.float.hd_list_load_font'))
}
.height($r('app.float.hd_list_load_height'))
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
.height($r('app.float.hd_list_load_height'))
}
build() {
Refresh({ refreshing: $$this.refreshing }) {
Grid(this.scroller) {
this.listContent()
this.loadMoreBuilder()
}
.columnsTemplate('1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('100%')
.height('100%')
.padding({ left: BasicConstant.SPACE_LG, right: BasicConstant.SPACE_LG })
// .divider({
// strokeWidth: $r('app.float.common_border_width'),
// color: $r('app.color.common_gray_border')
// })
.onReachEnd(() => {
if (this.loading || this.refreshing || this.finished) {
return;
}
this.loading = true
this.onLoad()
})
.scrollBar(BarState.Off)
.nestedScroll({
scrollForward: NestedScrollMode.PARENT_FIRST,
scrollBackward: NestedScrollMode.SELF_FIRST
})
.edgeEffect(EdgeEffect.None)
}
.width('100%')
.height('100%')
.layoutWeight(this.lw)
.onRefreshing(() => {
if (this.loading) {
return;
}
this.finished = false
this.onRefresh()
// tip: must next tick
})
}
}

View File

@ -11,7 +11,7 @@ export class BasicConstant {
static readonly urlHtml = "http://dev-doc.igandan.com/app/"
static readonly urlImage = "https://dev-doc.igandan.com/app/"
static readonly urlExpert = "https://dev-app.igandan.com/app/expert/"
static readonly wxUrl = "https://dev-wx.igandan.com/";
//正式环境
// static readonly urlExpertAPI = "https://app.igandan.com/app/expertAPI/";
@ -19,10 +19,14 @@ export class BasicConstant {
// static readonly urlHtml = "http://doc.igandan.com/app/"
// static readonly urlImage = "http://app.igandan.com/app/"
// static readonly urlExpert = "http://app.igandan.com/app/expert/"
// static readonly wxUrl = "https://wx.igandan.com/";// 微信服务器地址
static readonly getStartpage=BasicConstant.urlExpertApp + "startpage";
static readonly meetingListV2=BasicConstant.urlExpertAPI + "meetingListV2";
static readonly meetingV2Video=BasicConstant.urlExpertAPI + "meetingV2Video";
static readonly getTypeUuidByName=BasicConstant.urlExpertApp + "getTypeUuidByName";
static readonly zhibourl = BasicConstant.wxUrl+"hcp/setInfo";
static readonly videoByTypeNew = BasicConstant.urlExpertApp + 'videoByTypeNew'
static readonly videoDetail = BasicConstant.urlExpertAPI + "videoDetail";
}

View File

@ -1,4 +1,10 @@
export class DataWebModel {
url: string = '';
title: string = '';
}
export class DataWebModels extends DataWebModel {
type:string=''
}

View File

@ -0,0 +1,115 @@
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer, util } from '@kit.ArkTS';
export const base = new util.Base64Helper();
export class AESEncryptionDecryption {
// 字节流转成可理解的字符串
static uint8ArrayToString(array: Uint8Array) {
// 将UTF-8编码转换成Unicode编码
let out: string = '';
let index: number = 0;
let len: number = array.length;
while (index < len) {
let character = array[index++];
switch (character >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
out += String.fromCharCode(character);
break;
case 12:
case 13:
out += String.fromCharCode(((character & 0x1F) << 6) | (array[index++] & 0x3F));
break;
case 14:
out += String.fromCharCode(((character & 0x0F) << 12) | ((array[index++] & 0x3F) << 6) |
((array[index++] & 0x3F) << 0));
break;
default:
break;
}
}
return out;
}
// 字符串转成字节流
static stringToUint8Array(str: string) {
return new Uint8Array(buffer.from(str, 'utf-8').buffer);
}
// 获取密钥
static async getKey() {
let symAlgName = 'AES128';
let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
let dataUint8Array = AESEncryptionDecryption.stringToUint8Array('Whh82GtW/EVjBkD8');
let keyBlob: cryptoFramework.DataBlob = { data: dataUint8Array };
let promiseSymKey = await symKeyGenerator.convertKey(keyBlob);
let key = base.encodeToStringSync(promiseSymKey.getEncoded().data); // 将密钥转换为base64存储
return key;
}
// 加密
static async aesEncrypt(text: string, puKey: string): Promise<string> {
let globalResult = '';
try {
let cipherAlgName = 'AES128|ECB|PKCS7';
let globalCipher = cryptoFramework.createCipher(cipherAlgName);
let symAlgName = 'AES128';
let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
// let dataUint8Array = base.decodeSync(puKey);
let dataUint8Array = AESEncryptionDecryption.stringToUint8Array(puKey);
let keyBlob: cryptoFramework.DataBlob = { data: dataUint8Array };
let promiseSymKey = await symKeyGenerator.convertKey(keyBlob);
await globalCipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, promiseSymKey, null);
let result = await globalCipher.doFinal({ data: AESEncryptionDecryption.stringToUint8Array(text) });
globalResult = base.encodeToStringSync(result.data);
console.info('加密后的明文:' + globalResult);
} catch (err) {
console.info('加密错误:' +err.message);
}
return globalResult;
}
// 使用 AES 密钥加密数据
static encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
let cipher = cryptoFramework.createCipher('AES128|ECB|PKCS7');
cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null); // ECB模式params为null。
let cipherData = cipher.doFinalSync(plainText);
return cipherData;
}
// 解密
static async aesDecrypt(text: string, key: string) {
let globalResult = '';
try {
let cipherAlgName = 'AES128|ECB|PKCS7';
let globalCipher = cryptoFramework.createCipher(cipherAlgName);
let symAlgName = 'AES128';
let symKeyGenerator = cryptoFramework.createSymKeyGenerator(symAlgName);
let dataUint8Array = base.decodeSync(key);
let keyBlob: cryptoFramework.DataBlob = { data: dataUint8Array };
let promiseSymKey = await symKeyGenerator.convertKey(keyBlob);
await globalCipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, promiseSymKey, null);
let plainText: cryptoFramework.DataBlob = { data: base.decodeSync(text) };
let result = await globalCipher.doFinal(plainText);
globalResult = AESEncryptionDecryption.uint8ArrayToString(result.data);
console.info('解密后的明文:' + globalResult);
} catch (err) {
console.info(err.message);
}
}
}

View File

@ -5,3 +5,5 @@ export { VideoPage } from './src/main/ets/pages/VideoPage';
export { PlayBack } from './src/main/ets/pages/PlayBack';
export { VideoMore } from './src/main/ets/pages/VideoMore'
export { VideoDetailModel } from './src/main/ets/model/VideoDetailModel'

View File

@ -1,6 +1,6 @@
import { runCatching, seconds } from '@polyvharmony/media-player-sdk';
import { MeetingItemModel,ItemModel } from '../model/ItemModel'
import { BasicConstant } from '@itcast/basic'
import { BasicConstant,DataWebModels } from '@itcast/basic'
import { promptAction, router } from '@kit.ArkUI';
import { PLVMockMediaResourceData } from '../polyv/PLVMockMediaResourceData'
import {
@ -59,26 +59,30 @@ export struct ItemComp {
right: { anchor: "__container__", align: HorizontalAlign.End }
})
.border({ width:1, color:Color.White })
.backgroundColor($r('app.color.22000000'))
.borderRadius(30)
}
}
.height(162).backgroundColor(Color.Orange)
.height(162).backgroundColor(Color.White)
.margin({top:10,right:5}).clip(true).id('rr')
.onClick(async()=>{
const mediaResourcesResult = await runCatching(PLVMockMediaResourceData.getInstance().setupMediaResourcesFromLocal('e97dbe3e648aefc2eb6f68b96db9db6c_e'))
if (mediaResourcesResult.success === false) {
promptAction.showToast({
message: `'视频数据初始化失败': ${mediaResourcesResult.error}`,
duration: seconds(3).toMillis()
})
.onClick(()=>{
if(this.item.status=='3')
{
return
}
const mediaResource = mediaResourcesResult.data[0]
let paramsInfo: DataWebModels = {
url:this.item.liveurl ,
title:'肝胆直播',
type:'live'
};
router.pushUrl({
url:'pages/VideoPage/PLVMediaPlayerSingleVideoPage',
params: new PLVMediaPlayerSingleVideoPageParam(mediaResource)
url: 'pages/WebView/LivebroadcastPages', // 目标url
params: paramsInfo // 添加params属性传递自定义参数
})
})
}
Row(){
@ -108,11 +112,19 @@ export struct ItemComp {
}.width('100%').height(this.heightss).clip(true).
backgroundColor(Color.White).borderRadius(5)
.onClick(()=>{
router.pushUrl({
url: 'pages/WebView/WebPage',
params: { url: this.item.path ,title:'会议详情'}
});
})
}.backgroundColor($r('app.color.e4e4e4'))
.width('100%').padding({left:10,right:10}).clip(true)
}
getTime(str1:string, str2:string) {

View File

@ -47,7 +47,7 @@ export struct ItemCompBack {
}
}
.height(162).backgroundColor(Color.Orange)
.height(162).backgroundColor(Color.White)
.margin({top:10,right:5}).clip(true).id('rr')
Row(){
Image($r('app.media.meetingtime')).width(13).height(13)

View File

@ -0,0 +1,96 @@
import { runCatching, seconds } from '@polyvharmony/media-player-sdk';
import { VideoMore } from '../model/VideoMoreModel'
import { BasicConstant } from '@itcast/basic'
import { promptAction, router } from '@kit.ArkUI';
import { PLVMockMediaResourceData } from '../polyv/PLVMockMediaResourceData'
import {
PLVMediaPlayerSingleVideoPageParam
} from 'media-player-common';
import HashMap from '@ohos.util.HashMap';
import { hdHttp, HdResponse ,logger} from '@itcast/basic/Index'
import { BusinessError } from '@kit.BasicServicesKit';
import { VideoDetailModel } from '../model/VideoDetailModel'
@Preview
@Component
export struct ItemCompVideo {
@Prop item: VideoMore ;
hashMap: HashMap<string, string> = new HashMap();
@State heightss:Length=247
aboutToAppear(): void {
}
build() {
Column() {
Image(BasicConstant.urlHtml+this.item.imgpath).width('100%').height(102)
.objectFit(ImageFit.Fill)
Text(this.item.name).maxLines(2).fontSize(15).fontColor('app.color.666666').textAlign(TextAlign.Start).height(36)
.textOverflow({ overflow: TextOverflow.Ellipsis }).id('title').width('100%').margin({top:10}).padding({left:10,right:10})
Row(){
Text(this.item.public_name).fontSize(14)
.fontColor($r('app.color.999999'))
Blank()
Image($r('app.media.video_look')).width(18).height(11)
Text(this.item.readnum+'').fontSize(14)
.fontColor($r('app.color.999999'))
}
.padding({left:10,right:10,bottom:10})
.width('100%')
.margin({top:6})
}.backgroundColor(Color.White)
.borderRadius(5)
.onClick(()=>{
this.getVideoDetail(this.item.uuid)
})
.width('100%').clip(true)
}
getVideoDetail(video_uuid:string)
{
this.hashMap.clear();
this.hashMap.set('video_uuid', video_uuid)
hdHttp.httpReq<string>(BasicConstant.videoDetail,this.hashMap).then(async (res: HdResponse<string>) => {
logger.info('Response videoDetail'+res);
let json:VideoDetailModel = JSON.parse(res+'') as VideoDetailModel;
this.goPLVMediaPlayerSingleVideoPage(json.video.polyv_uuid,video_uuid)
}).catch((err: BusinessError) => {
})
}
async goPLVMediaPlayerSingleVideoPage(vid:string,video_uuid:string)
{
const mediaResourcesResult = await runCatching(PLVMockMediaResourceData.getInstance().setupMediaResourcesFromLocal(vid))
if (mediaResourcesResult.success === false) {
promptAction.showToast({
message: `'视频数据初始化失败': ${mediaResourcesResult.error}`,
duration: seconds(3).toMillis()
})
return
}
const mediaResource = mediaResourcesResult.data[0]
router.pushUrl({
url:'pages/VideoPage/PLVMediaPlayerSingleVideoPage',
params: {
video_uuid:video_uuid,
param:new PLVMediaPlayerSingleVideoPageParam(mediaResource)
}
})
}
}

View File

@ -0,0 +1,89 @@
import { ItemCompVideo } from './ItemCompVideo'
import { VideoMoreModel,VideoMore } from '../model/VideoMoreModel'
import { HdGrid, HdListController,BasicConstant,hdHttp, HdResponse ,logger} from '@itcast/basic/Index'
import { promptAction, router } from '@kit.ArkUI'
import { BusinessError } from '@kit.BasicServicesKit';
import HashMap from '@ohos.util.HashMap';
@Component
export struct ListCompVideo {
@Prop
type_uuid:string=''
@State
list: VideoMore[] = []
controller = new HdListController()
@State
page: number = 1
@State
keyword: string = ''
hashMap: HashMap<string, string> = new HashMap();
onRefresh() {
this.page = 1
this.initData(0)
}
initData(type:number)
{
this.hashMap.clear();
this.hashMap.set('page', this.page+"")
this.hashMap.set('typeUuid', this.type_uuid)
hdHttp.httpReq<string>(BasicConstant.videoByTypeNew,this.hashMap).then(async (res: HdResponse<string>) => {
logger.info('Response videoByTypeNew'+res);
let json:VideoMoreModel = JSON.parse(res+'') as VideoMoreModel;
if(type==0)
{
this.controller.refreshed()
}
else
{
this.controller.loaded()
}
if(this.page==1&&json.data.list!=null&&json.data.list.length>0)
{
this.list = json.data.list
}
else if(this.page>1)
{
this.list.push(...json.data.list)
}
if (this.page >= json.data.totalPage) {
this.controller.finished()
} else {
this.page++
}
}).catch((err: BusinessError) => {
})
}
build() {
HdGrid({
lw: 1,
controller: this.controller,
onRefresh: () => {
this.onRefresh()
},
onLoad: () => {
this.initData(1)
}
}) {
ForEach(this.list, (items: VideoMore) => {
GridItem() {
ItemCompVideo({ item:items })
}
})
}
}
}

View File

@ -0,0 +1,21 @@
export interface VideoDetailModel{
code:string;
video:VideoModel;
message:string;
}
export interface VideoModel{
note:string;
path:string;
readnum:string;
imgpath:string;
name:string;
isCollection:number;
polyv_uuid:string;
uuid:string;
public_name:string;
content:string;
point:number;
tags:string;
}

View File

@ -0,0 +1,29 @@
export interface VideoMoreModel {
code:string;
data:VideoMoreData;
message:string;
}
export interface VideoMoreData{
totalPage:number;
pageNumber:number;
pageSize:number;
totalRow:number;
list: VideoMore[] ;
}
export interface VideoMore{
type_uuid:string;
public_name:string;
imgpath:string;
sort:string;
uuid:string;
create_date:string;
status:string;
name:string;
path:string;
readnum:string;
note:string;
video_type_name:string;
tags:string;
}

View File

@ -1,19 +1,19 @@
import router from '@ohos.router';
import { HdNav } from '@itcast/basic'
import { ListCompVideo } from '../components/ListCompVideo'
@Component
export struct VideoMore {
@State message: string = 'Hello World';
@State params:Record<string, string> = router.getParams() as Record<string, string>;
build() {
Row() {
Column() {
Text(this.message)
.fontSize($r('app.float.page_text_font_size'))
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.message = 'Welcome';
})
}
.width('100%')
}
.height('100%')
HdNav({ title: this.params.title, showRightIcon: false, showLeftIcon: true,showRightText:true,rightText:'精选' })
Text('').height(1).width('100%')
.backgroundColor($r('app.color.1a000000'))
.margin({bottom:10})
ListCompVideo({type_uuid:this.params.uuid}).padding({bottom:20,left:10,right:10}).backgroundColor($r('app.color.top_bg'))
}.width('100%')
.height('100%').backgroundColor($r('app.color.top_bg'))
}
}

View File

@ -10,14 +10,14 @@ import {
} from '@polyvharmony/media-player-sdk';
import {PLVMediaDownloadSetting} from '@polyvharmony/media-player-sdk-addon-cache-down';
// const mockAuthentication: PLVVodMainAccountAuthentication = {
// userId: "cfb7a69a75",
// secretKey: "4KtJhl9EqU"
// }
const mockAuthentication: PLVVodMainAccountAuthentication = {
userId: "e97dbe3e64",
secretKey: "zMV29c519P"
userId: "cfb7a69a75",
secretKey: "4KtJhl9EqU"
}
// const mockAuthentication: PLVVodMainAccountAuthentication = {
// userId: "e97dbe3e64",
// secretKey: "zMV29c519P"
// }
const mockViewerParam: PLVViewerParam = {
viewerId: "123",

View File

@ -32,6 +32,10 @@
"name": "e4e4e4",
"value": "#e4e4e4"
},
{
"name": "1a000000",
"value": "#1a000000"
},
{
"name": "333333",
"value": "#333333"
@ -55,6 +59,14 @@
{
"name": "999999",
"value": "#999999"
},
{
"name": "666666",
"value": "#666666"
},
{
"name": "22000000",
"value": "#22000000"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,4 +1,4 @@
import { hdHttp, HdResponse,BasicConstant,ExpertData, authStore, ChangeUtil,hdHttps } from '@itcast/basic'
import { hdHttp, HdResponse,BasicConstant,ExpertData, authStore, ChangeUtil } from '@itcast/basic'
import HashMap from '@ohos.util.HashMap'
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction, router } from '@kit.ArkUI'
@ -202,7 +202,7 @@ export struct EditUserDataComp {
controller:this.officePickerDialog,
officeSelected: (name:string , uuid:string) => {
this.officeName = name;
hdHttps.post<null>(this.updateDataUrl, {
hdHttp.post<null>(this.updateDataUrl, {
officeName: name,
officeUuid:uuid,
type:'2',

View File

@ -29,7 +29,7 @@ export struct PLVMediaPlayerMarqueeLayout {
.setHiddenWhenPause(false)
.setAlwaysShowWhenRun(false),
new PLVMarqueeTextSettingVO()
.setContent("播放器跑马灯 MediaPlayerMarquee")
.setContent("")
.setFontColor('#FF0000')
.setFontSize(40)
.setShadow(true)

View File

@ -140,8 +140,8 @@ struct BootPage {
this.goNextPage()
try {
router.pushUrl({
url: 'pages/WebView/WebPage',
params: { url: this.newUrl ,title:'肝胆相照'}
url: 'pages/WebView/LivebroadcastPages',
params: { url: this.newUrl ,title:'肝胆相照',type:'live'}
}, router.RouterMode.Standard);
} catch (err) {
console.error(`跳转失败: ${err.code}, ${err.message}`);

View File

@ -15,17 +15,26 @@ import { createDependScope } from '@polyvharmony/media-player-sdk'
import {
commonPageModule,
} from 'media-player-common'
import { HdNav,BasicConstant } from '@itcast/basic'
import HashMap from '@ohos.util.HashMap';
import { hdHttp, HdResponse ,logger} from '@itcast/basic/Index'
import { BusinessError } from '@kit.BasicServicesKit';
import { VideoDetailModel } from 'home'
@Entry
@Component
export struct PLVMediaPlayerSingleVideoPage {
@Provide pageDependScope: DependScope = createDependScope(commonPageModule)
// @Consume pageDependScope: DependScope
private param: PLVMediaPlayerSingleVideoPageParam = router.getParams() as PLVMediaPlayerSingleVideoPageParam
private params: VideoPageParam = router.getParams() as VideoPageParam
private param: PLVMediaPlayerSingleVideoPageParam = this.params.param
private context = getContext(this) as common.UIAbilityContext
private pageControlViewModel: PLVMPPageControlViewModel = this.pageDependScope.get(PLVMPPageControlViewModel)
private onBackPressDisposable: Disposable | undefined = undefined
private readonly plv_media_player_single_video_background: string = createId()
hashMap: HashMap<string, string> = new HashMap();
@State note:string=''
aboutToAppear(): void {
requireNotNull(this.param, () => "param is null")
this.onBackPressDisposable = this.pageControlViewModel.onBackPressHandler.register(10, () => this.onBackPress())
@ -33,24 +42,62 @@ export struct PLVMediaPlayerSingleVideoPage {
const windowInstance = await window.getLastWindow(this.context)
windowInstance.setWindowKeepScreenOn(true)
})
this.getVideoDetail(this.params.video_uuid)
}
@State currentIndex: number = 0;
build() {
Stack() {
// 背景图
// Image($r('app.media.plv_media_player_video_item_background_portrait'))
// .id(this.plv_media_player_single_video_background)
// .objectFit(ImageFit.Cover)
// .expandSafeArea(undefined, [SafeAreaEdge.BOTTOM])
@Builder tabBuilder(title: string, targetIndex: number) {
Column() {
Text(title)
.fontColor(this.currentIndex === targetIndex ? '#8D2316' : '#848284')
.fontSize(14)
.lineHeight(45)
.height(45)
PLVMediaPlayerSingleVideoLayout({
mediaResource: this.param.mediaResource,
enterFromDownloadCenter: this.param.enterFromDownloadCenter
})
// 屏幕方向监听器
PLVOrientationManagerObserver()
}
.width('100%')
.height(50)
.justifyContent(FlexAlign.Center)
}
build() {
Column(){
HdNav({ title: '视频详情', showRightIcon: false, showLeftIcon: true})
Stack() {
// 背景图
// Image($r('app.media.plv_media_player_video_item_background_portrait'))
// .id(this.plv_media_player_single_video_background)
// .objectFit(ImageFit.Cover)
// .expandSafeArea(undefined, [SafeAreaEdge.BOTTOM])
PLVMediaPlayerSingleVideoLayout({
mediaResource: this.param.mediaResource,
enterFromDownloadCenter: this.param.enterFromDownloadCenter
})
// 屏幕方向监听器
PLVOrientationManagerObserver()
}
.width('100%')
.height(204)
Tabs() {
TabContent() {
Text(this.note).fontSize(14).fontColor(Color.Black)
}
.align(Alignment.TopStart)
.padding(15)
.tabBar(this.tabBuilder('视频简介', 0))
TabContent() {
Text('推荐的内容').fontSize(30).alignSelf(ItemAlign.Start)
}
.tabBar(this.tabBuilder('评论', 1))
}.layoutWeight(1)
.onChange((index: number) => {
this.currentIndex = index;
})
}
}
onBackPress(): boolean {
@ -69,4 +116,24 @@ export struct PLVMediaPlayerSingleVideoPage {
})
}
getVideoDetail(video_uuid:string)
{
this.hashMap.clear();
this.hashMap.set('video_uuid', video_uuid)
hdHttp.httpReq<string>(BasicConstant.videoDetail,this.hashMap).then(async (res: HdResponse<string>) => {
logger.info('Response videoDetails'+video_uuid);
logger.info('Response videoDetail'+res);
let json:VideoDetailModel = JSON.parse(res+'') as VideoDetailModel;
this.note=json.video.note
}).catch((err: BusinessError) => {
})
}
}
interface VideoPageParam
{
video_uuid:string
param:PLVMediaPlayerSingleVideoPageParam
}

View File

@ -1,4 +1,5 @@
import { VideoMore } from 'home'
@Entry
@Component
struct VideoMorePage {

View File

@ -0,0 +1,95 @@
import webview from '@ohos.web.webview';
import { HdNav,authStore,BasicConstant,Base64Util,DataWebModels,AESEncryptionDecryption } from '@itcast/basic';
import router from '@ohos.router';
import { BusinessError } from '@kit.BasicServicesKit';
import util from '@ohos.util';
@Entry
@Component
struct LivebroadcastPages {
private controller: webview.WebviewController = new webview.WebviewController();
@State params:DataWebModels = router.getParams() as DataWebModels;
@State url: string = this.params.url;
@State title: string = this.params.title;
customUserAgent: string = 'gdxz-expert';
@State plyvvparams:string=''
aboutToAppear(): void {
this.getUrl()
}
build() {
Column() {
HdNav({ title: this.title, showRightIcon: false, hasBorder: true })
Web({
src: this.url,
controller: this.controller
})
.mixedMode(MixedMode.All)
.domStorageAccess(true)
.onControllerAttached(() => {
let userAgent = this.controller.getUserAgent() + this.customUserAgent;
this.controller.setCustomUserAgent(userAgent);
})
.javaScriptAccess(true)
.onPageEnd(async() => {
try {
let ids:string = authStore.getUser().uuid;
let avatar:string = BasicConstant.urlHtml+authStore.getUser().photo
let str:string =authStore.getUser().realName
let name:string =await Base64Util.encodeToStr(AESEncryptionDecryption.stringToUint8Array(str), util.Type.BASIC);
this.plyvvparams = "{\"name\":\""+name+"\",\"id\":\""+ids+"\",\"avatar\":\""+avatar+"\"}";
this.controller.runJavaScript(
"window.localStorage.setItem('watchlive_current_user','" +this.plyvvparams + "');",
(error, result) => {
if (error) {
console.error(`run JavaScript error, ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
return;
}
if (result) {
console.info(`The test() return value is: ${result}`);
}
});
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
.width('100%')
.layoutWeight(1)// 占据剩余空间
.height('100%')
}
.height('100%')// 关键:约束父容器高度
}
async getUrl()
{
if('live'==this.params.type)
{
let ids:string = authStore.getUser().uuid;
let avatar:string = BasicConstant.urlHtml+authStore.getUser().photo
let str:string =authStore.getUser().realName
let name:string =await Base64Util.encodeToStr( AESEncryptionDecryption.stringToUint8Array(str), util.Type.BASIC);
name.replaceAll("\r|\n","")
console.info(`The test() return value is22: ${name+str}`);
let signs =await AESEncryptionDecryption.aesEncrypt(ids+name+avatar+this.url,"deoep09_klodLdAo")
let temurl=BasicConstant.zhibourl+"?id="+ids+"&name="+name+"&avatar="+avatar+"&url="+this.url+"&sign="+ signs;
this.url=temurl
console.info(`The test() return value is11: ${this.url}`);
}
}
// async getUser()
// {
// let ids:string = authStore.getUser().uuid;
// let avatar:string = BasicConstant.urlHtml+authStore.getUser().photo
// let str:string =authStore.getUser().realName
// const encoder = new util.TextEncoder(); // 全局单例
// let name:string =await Base64Util.encodeToStr( encoder.encode(str), util.Type.BASIC);
// this.plyvvparams = "{\"name\":\""+name+"\",\"id\":\""+ids+"\",\"avatar\":\""+avatar+"\"}";
// }
}

View File

@ -20,6 +20,7 @@
"pages/MinePage/EditIntroductionPage",
"pages/VideoPage/PlayBackPage",
"pages/VideoPage/VideoMorePage",
"pages/VideoPage/PLVMediaPlayerSingleVideoPage"
"pages/VideoPage/PLVMediaPlayerSingleVideoPage",
"pages/WebView/LivebroadcastPages"
]
}

View File

@ -109,6 +109,7 @@ export struct PLVMediaPlayerSingleVideoLayout {
center: toCenterOf(parent),
middle: toMiddleOf(parent)
})
}
.id(this.plv_media_player_single_video_container)
.width('100%')

View File

@ -123,6 +123,7 @@ export struct PLVMediaPlayerSingleVideoControllerLayoutPort {
top: toTopOf(parent)
})
.hitTestBehavior(HitTestMode.Transparent)
.visibility(Visibility.None)
// 视频标题
PLVMediaPlayerTitleTextView()
@ -133,6 +134,7 @@ export struct PLVMediaPlayerSingleVideoControllerLayoutPort {
right: toStartOf(this.plv_media_player_more_action_iv)
})
.hitTestBehavior(HitTestMode.None)
.visibility(Visibility.None)
// 更多按钮
PLVMediaPlayerMoreActionImageView()
@ -148,7 +150,7 @@ export struct PLVMediaPlayerSingleVideoControllerLayoutPort {
right: 16
})
.hitTestBehavior(HitTestMode.Transparent)
.visibility(Visibility.None)
// 播放/暂停按钮
PLVMediaPlayerPlayButton()
.id(this.plv_media_player_play_button)