[Human] chore(project): 初始化导入 91dj H5 客户端项目代码
从本地工程首次入库;.npmrc(含私有 npm 源 token)与 tsbuildinfo 已加入 .gitignore,不随仓库提交。
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
<template>
|
||||
<div
|
||||
class="vertical_video_warp"
|
||||
:class="{
|
||||
'vertical_video_warp--hide-progress': props.hideProgress,
|
||||
'vertical_video_warp--hide-fullscreen': props.hideFullscreen,
|
||||
'vertical_video_warp--hide-background': props.hideBackground,
|
||||
}"
|
||||
>
|
||||
<div id="video">
|
||||
<div class="avoid_sliding" @click="pause"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeUnmount, onMounted } from 'vue';
|
||||
import { useConfigStore } from '@/stores/config';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import HlsJSPlayer from 'xgplayer-hls.js';
|
||||
import { bindH265PlaybackFallback, resolvePlayResourceKey } from '@/utils/h265Playback';
|
||||
|
||||
const props = defineProps<{
|
||||
sourceURL: string;
|
||||
/** H.265 资源 key;有值且设备支持时优先播放 */
|
||||
h265Url?: string | null;
|
||||
hideProgress?: boolean;
|
||||
hideFullscreen?: boolean;
|
||||
hideBackground?: boolean;
|
||||
}>();
|
||||
let player: any = null; //播放器实例
|
||||
let playResourceKey = '';
|
||||
let isPlayingH265 = false;
|
||||
let forceH264 = false;
|
||||
let pendingResumeAt = 0;
|
||||
let unbindH265Fallback: (() => void) | null = null;
|
||||
|
||||
onMounted(() => {
|
||||
//初始化播放器
|
||||
initVideo();
|
||||
});
|
||||
/**
|
||||
* @description 暂停
|
||||
*/
|
||||
const pause = () => {
|
||||
player.pause();
|
||||
};
|
||||
|
||||
const resolveCurrentResourceKey = () => {
|
||||
const resolved = resolvePlayResourceKey({
|
||||
h264Key: props.sourceURL,
|
||||
h265Key: props.h265Url,
|
||||
forceH264,
|
||||
});
|
||||
playResourceKey = resolved.resourceKey;
|
||||
isPlayingH265 = resolved.isH265;
|
||||
};
|
||||
|
||||
const destroyPlayer = () => {
|
||||
unbindH265Fallback?.();
|
||||
unbindH265Fallback = null;
|
||||
if (!player) return;
|
||||
try {
|
||||
player.src = '';
|
||||
player.destroy(true);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
player = null;
|
||||
};
|
||||
|
||||
const fallbackH265ToH264 = (resumeAt: number) => {
|
||||
if (forceH264 || !isPlayingH265) return;
|
||||
forceH264 = true;
|
||||
isPlayingH265 = false;
|
||||
pendingResumeAt = resumeAt;
|
||||
destroyPlayer();
|
||||
initVideo();
|
||||
};
|
||||
|
||||
/**
|
||||
* @description 初始化播放器
|
||||
*/
|
||||
const initVideo = () => {
|
||||
if (player) destroyPlayer();
|
||||
resolveCurrentResourceKey();
|
||||
player = new HlsJSPlayer({
|
||||
id: 'video',
|
||||
url: getPath(),
|
||||
fluid: true,
|
||||
playsinline: true,
|
||||
videoInit: true,
|
||||
loop: true,
|
||||
autoplay: true,
|
||||
controls: true,
|
||||
lang: 'zh-cn',
|
||||
ignores: ['i18n', 'play', 'volume', 'definition'],
|
||||
allowPlayAfterEnded: true,
|
||||
allowSeekAfterEnded: true,
|
||||
closeVideoPreventDefault: true,
|
||||
closeVideoStopPropagation: true,
|
||||
closeInactive: true,
|
||||
enableVideoDbltouch: true,
|
||||
});
|
||||
unbindH265Fallback = bindH265PlaybackFallback(player, {
|
||||
shouldFallback: () => isPlayingH265 && !forceH264,
|
||||
onFallback: fallbackH265ToH264,
|
||||
});
|
||||
player.on('loadedmetadata', () => {
|
||||
if (pendingResumeAt > 0) {
|
||||
const resumeAt = pendingResumeAt;
|
||||
pendingResumeAt = 0;
|
||||
try {
|
||||
player.currentTime = resumeAt;
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @description 获取播放链接
|
||||
*/
|
||||
const getPath = () => {
|
||||
const { baseUrl } = useConfigStore();
|
||||
return `${baseUrl}/api/app/vid/h5/m3u8/${playResourceKey || props.sourceURL}?token=${getToken()}`;
|
||||
};
|
||||
/**
|
||||
* @description 获取token
|
||||
*/
|
||||
const getToken = () => {
|
||||
const { token } = useUserStore();
|
||||
return token;
|
||||
};
|
||||
onBeforeUnmount(() => {
|
||||
destroyPlayer();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.vertical_video_warp {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
background: #000000;
|
||||
align-items: center;
|
||||
:deep(.xgplayer-progress-played) {
|
||||
background: rgb(39, 213, 236);
|
||||
}
|
||||
:deep(.xgplayer-progress) {
|
||||
top: 10px;
|
||||
}
|
||||
:deep(.xgplayer-start),
|
||||
:deep(.xgplayer-controls) {
|
||||
transform: translate3d(0, 0, 0);
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
}
|
||||
:deep(.xgplayer-progress-btn) {
|
||||
display: none !important;
|
||||
}
|
||||
:deep(.xgplayer-time-current:after) {
|
||||
content: ' ';
|
||||
}
|
||||
:deep(.xgplayer-progress) {
|
||||
left: 43%;
|
||||
right: 0;
|
||||
width: 60%;
|
||||
transform: translate(-50%, 0);
|
||||
}
|
||||
:deep(.xgplayer-time) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
// margin-top: 10px;
|
||||
font-size: 11px;
|
||||
}
|
||||
:deep(.xgplayer-time-current)::after {
|
||||
display: none;
|
||||
}
|
||||
&.vertical_video_warp--hide-progress {
|
||||
:deep(.xgplayer-progress),
|
||||
:deep(.xgplayer-time) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
&.vertical_video_warp--hide-fullscreen {
|
||||
:deep(.xgplayer-fullscreen) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
&.vertical_video_warp--hide-background {
|
||||
background: transparent;
|
||||
}
|
||||
// :deep(.xgplayer-icon-play) {
|
||||
// > svg {
|
||||
// height: 40px;
|
||||
// width: 40px;
|
||||
// }
|
||||
// }
|
||||
// :deep(.xgplayer-skin-default .xgplayer-start) {
|
||||
// height: 40px;
|
||||
// width: 40px;
|
||||
// margin: -20px;
|
||||
// }
|
||||
#video {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: relative;
|
||||
:deep(.xgplayer-enter-spinner) {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.avoid_sliding {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user