This commit is contained in:
2025-09-11 10:54:06 +08:00
parent 53f2037c49
commit a590433a91
7 changed files with 413 additions and 419 deletions
+93 -104
View File
@@ -63,40 +63,117 @@ export class SceneBgVideoLayer extends li_BaseView {
//================== 公共 API 方法 ==================
/**
* 播放视频
* 播放视频 - 统一的视频播放接口
* @param path 视频路径
* @param loop 是否循环播放
* @param options 可选配置项
* @param options.loop 是否循环播放,默认true
* @param options.size 视频尺寸 {width, height}
* @param options.position 视频位置 {x, y, z}
* @param options.scale 视频缩放值
* @param options.autoFill 是否自动填充到指定尺寸
*/
playVideo(path: string, loop: boolean = false) {
playVideo(
path: string,
options?: {
loop?: boolean;
size?: { width: number; height: number } | Size;
position?: { x: number; y: number; z?: number } | Vec3;
scale?: number | Vec3;
}
) {
if (!this.videoPlayer) {
console.error("SceneBgVideoLayer: VideoPlayer未初始化");
return;
}
// 默认参数
const config = {
loop: options?.loop ?? true,
size: options?.size,
position: options?.position,
scale: options?.scale,
};
// 先停止当前视频
if (this.isPlaying) {
this.stop();
}
// 加载本地视频资源
ResManager.I.changeBundleVideo(
this.videoPlayer,
path,
"Girls",
(res: VideoClip) => {
this.videoPlayer.loop = loop;
this.videoPlayer.loop = config.loop;
// 设置锚点为中心,确保位置对齐
const uiTransform = this.videoPlayer.node.getComponent(UITransform);
if (uiTransform) {
uiTransform.setAnchorPoint(0.5, 0.5);
}
// 应用位置设置(使用世界坐标)
if (config.position) {
const pos = config.position;
if (pos instanceof Vec3) {
this.videoPlayer.node.setWorldPosition(pos);
} else {
this.videoPlayer.node.setWorldPosition(pos.x, pos.y, pos.z || 0);
}
}
// 如果传入了目标尺寸,计算并应用缩放
if (config.size && uiTransform) {
// 获取视频的原始尺寸
const videoWidth = uiTransform.contentSize.width;
const videoHeight = uiTransform.contentSize.height;
if (videoWidth > 0 && videoHeight > 0) {
const targetWidth = config.size instanceof Size ? config.size.width : config.size.width;
const targetHeight = config.size instanceof Size ? config.size.height : config.size.height;
// 计算缩放比例(填满整个区域)
const scaleX = targetWidth / videoWidth;
const scaleY = targetHeight / videoHeight;
const scale = Math.max(scaleX, scaleY);
this.videoPlayer.node.setScale(new Vec3(scale, scale, 1));
console.log(`SceneBgVideoLayer: 视频原始尺寸: ${videoWidth}x${videoHeight}, 目标尺寸: ${targetWidth}x${targetHeight}, 缩放: ${scale}`);
} else {
// 如果视频尺寸还未准备好,延迟重试
this.scheduleOnce(() => {
if (config.size && uiTransform) {
const videoWidth = uiTransform.contentSize.width;
const videoHeight = uiTransform.contentSize.height;
if (videoWidth > 0 && videoHeight > 0) {
const targetWidth = config.size instanceof Size ? config.size.width : config.size.width;
const targetHeight = config.size instanceof Size ? config.size.height : config.size.height;
const scaleX = targetWidth / videoWidth;
const scaleY = targetHeight / videoHeight;
const scale = Math.max(scaleX, scaleY);
this.videoPlayer.node.setScale(new Vec3(scale, scale, 1));
console.log(`SceneBgVideoLayer: (延迟) 视频原始尺寸: ${videoWidth}x${videoHeight}, 目标尺寸: ${targetWidth}x${targetHeight}, 缩放: ${scale}`);
}
}
}, 0.1);
}
}
// 如果显式传入了 scale 参数,覆盖自动计算的缩放
else if (config.scale !== undefined) {
this.setVideoScale(config.scale);
}
this.videoPlayer.play();
this.isPlaying = true;
console.log(`SceneBgVideoLayer: 播放视频 ${path}, 循环: ${loop}`);
console.log(`SceneBgVideoLayer: 播放视频 ${path}, 配置:`, config);
}
);
}
/**
* 切换视频(停止当前视频并播放新视频)
* @param path 视频路径
* @param loop 是否循环播放
*/
switchVideo(path: string, loop: boolean = false) {
this.stop();
this.playVideo(path, loop);
}
/**
* 暂停视频
*/
@@ -128,62 +205,6 @@ export class SceneBgVideoLayer extends li_BaseView {
}
}
/**
* 设置视频尺寸
* @param width 宽度
* @param height 高度
*/
setVideoSize(width: number, height: number) {
if (this.videoPlayer) {
const uiTransform = this.videoPlayer.node.getComponent(UITransform);
if (uiTransform) {
uiTransform.setContentSize(width, height);
console.log(`SceneBgVideoLayer: 设置视频尺寸 ${width}x${height}`);
}
}
}
/**
* 设置视频位置
* @param x X坐标
* @param y Y坐标
* @param z Z坐标
*/
setVideoPosition(x: number, y: number, z: number = 0) {
if (this.videoPlayer) {
this.videoPlayer.node.setPosition(x, y, z);
console.log(`SceneBgVideoLayer: 设置视频位置 (${x}, ${y}, ${z})`);
}
}
/**
* 设置视频世界位置
* @param x X坐标
* @param y Y坐标
* @param z Z坐标
*/
setVideoWorldPosition(x: number, y: number, z: number = 0) {
if (this.videoPlayer) {
this.videoPlayer.node.setWorldPosition(x, y, z);
console.log(`SceneBgVideoLayer: 设置视频世界位置 (${x}, ${y}, ${z})`);
}
}
/**
* 设置视频锚点
* @param anchorX X轴锚点 (0-1)
* @param anchorY Y轴锚点 (0-1)
*/
setVideoAnchor(anchorX: number, anchorY: number) {
if (this.videoPlayer) {
const uiTransform = this.videoPlayer.node.getComponent(UITransform);
if (uiTransform) {
uiTransform.setAnchorPoint(anchorX, anchorY);
console.log(`SceneBgVideoLayer: 设置视频锚点 (${anchorX}, ${anchorY})`);
}
}
}
/**
* 设置视频缩放
* @param scale 缩放值(数字或Vec3
@@ -227,7 +248,7 @@ export class SceneBgVideoLayer extends li_BaseView {
this.videoPlayer.node.setScale(new Vec3(scale, scale, 1));
if (position) {
this.videoPlayer.node.setPosition(position);
this.videoPlayer.node.setWorldPosition(position);
}
console.log(`SceneBgVideoLayer: 自适应填充区域,缩放: ${scale}`);
@@ -292,38 +313,6 @@ export class SceneBgVideoLayer extends li_BaseView {
// 由子类重写或外部监听
}
//================== 兼容性方法 ==================
/**
* 播放本地循环视频(保留以保证兼容性)
* @deprecated 使用 playVideo(path, true) 替代
*/
playLocalLoopVideo(data: any) {
if (data?.path) {
this.playVideo(data.path, true);
// 保存当前数据供回调使用
this.currentVideoData = data;
// 如果有尺寸和位置信息,进行调整
if (data.size) {
this.adjustToFillArea(data.size, data.bgFrameNode?.position);
}
}
}
/**
* 调整视频填充框架(保留以保证兼容性)
* @deprecated 使用 adjustToFillArea 替代
*/
adjustVideoToFillFrame(targetSize: any, bgFrameNode?: Node) {
let position: Vec3 | undefined;
if (bgFrameNode && isValid(bgFrameNode) && bgFrameNode.position) {
position = bgFrameNode.position;
}
this.adjustToFillArea(targetSize, position);
}
//================== 其他方法 ==================
/**