generated from VLADIMIR/template_frontend
up
This commit is contained in:
@@ -38,6 +38,7 @@ const timerSyncedAt = ref(Date.now())
|
||||
const timerStateAtSync = ref<string>()
|
||||
const pollingReady = ref(false)
|
||||
const introAudioElement = ref<HTMLAudioElement>()
|
||||
const musicAudioElement = ref<HTMLAudioElement>()
|
||||
const conclusionVideoElement = ref<HTMLVideoElement>()
|
||||
let appliedCommandVersion = 0
|
||||
let timerTick: number | null = null
|
||||
@@ -68,6 +69,11 @@ const timerDisplay = computed(() => {
|
||||
})
|
||||
const introAudio = computed(() => applicationFileURL(state.value?.introAudio))
|
||||
const conclusionVideo = computed(() => applicationFileURL(state.value?.conclusionVideo))
|
||||
const musicTrack = computed(() => {
|
||||
const tracks = state.value?.music?.playlist?.tracks || []
|
||||
const index = state.value?.music?.trackIndex || 0
|
||||
return applicationFileURL(tracks[index]?.filename)
|
||||
})
|
||||
const screenBackground = computed(() => {
|
||||
const image = state.value?.backgroundImage || state.value?.coverImage
|
||||
return image ? { backgroundImage: `linear-gradient(rgb(0 0 0 / 55%), rgb(0 0 0 / 55%)), url("${image}")` } : {}
|
||||
@@ -188,6 +194,35 @@ watch(state, async (value) => {
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => state.value?.music,
|
||||
async (value) => {
|
||||
const media = musicAudioElement.value
|
||||
if (!media || !value || !value.playlist?.tracks?.length) return
|
||||
await nextTick()
|
||||
media.volume = Math.max(0, Math.min(1, (value.volume ?? 100) / 100))
|
||||
media.muted = !state.value?.soundEnabled
|
||||
media.currentTime = (value.positionMs || 0) / 1000
|
||||
if (value.playback === 'MUSIC_PLAYBACK_PLAYING') {
|
||||
void media.play().catch(() => {
|
||||
mediaError.value = 'Браузер заблокировал воспроизведение музыки. Нажмите «Подготовить экран».'
|
||||
})
|
||||
} else {
|
||||
media.pause()
|
||||
}
|
||||
},
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
async function advanceMusic() {
|
||||
if (!screenId.value || !accessToken.value) return
|
||||
try {
|
||||
await screenClient.AdvanceScreenMusic({ screenID: screenId.value, accessToken: accessToken.value })
|
||||
} catch {
|
||||
mediaError.value = 'Не удалось синхронизировать музыку. Повторная попытка выполняется автоматически.'
|
||||
}
|
||||
}
|
||||
|
||||
async function bind() {
|
||||
if (!selectedGameId.value || !route.query.screenID || !route.query.accessToken) return
|
||||
binding.value = true
|
||||
@@ -213,7 +248,7 @@ async function prepareScreen() {
|
||||
}
|
||||
prepared.value = true
|
||||
await nextTick()
|
||||
for (const media of [introAudioElement.value, conclusionVideoElement.value]) {
|
||||
for (const media of [introAudioElement.value, conclusionVideoElement.value, musicAudioElement.value]) {
|
||||
if (!media) continue
|
||||
media.muted = true
|
||||
try {
|
||||
@@ -288,6 +323,13 @@ onUnmounted(() => {
|
||||
<div v-if="state.introAudio" v-show="screenMode === 'SCREEN_MODE_INTRO'" class="screen-media">
|
||||
<audio ref="introAudioElement" :src="introAudio" :muted="!state.soundEnabled" controls />
|
||||
</div>
|
||||
<audio
|
||||
v-if="state.music?.playlist?.tracks?.length"
|
||||
ref="musicAudioElement"
|
||||
:src="musicTrack"
|
||||
:muted="!state.soundEnabled"
|
||||
@ended="advanceMusic"
|
||||
/>
|
||||
<div v-if="state.conclusionVideo" v-show="screenMode === 'SCREEN_MODE_CONCLUSION'" class="conclusion-screen">
|
||||
<video ref="conclusionVideoElement" :src="conclusionVideo" :muted="!state.soundEnabled" playsinline />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user