Files
taimed-international-app/components/video-player/composables/useVideoProgress.ts

132 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// components/video-player/composables/useVideoProgress.ts
import { ref } from 'vue'
import { videoStorage } from '@/utils/videoStorage'
import { videoApi } from '@/api/modules/video'
import type { IVideoInfo } from '@/types/video'
/**
* 视频播放进度管理
*/
export function useVideoProgress() {
const currentTime = ref(0)
const isSaving = ref(false)
let saveTimer: any = null
/**
* 获取初始播放位置
* 合并本地和服务器的播放位置,取较大值
* 如果视频已经看完(播放位置 >= 总时长 - 5秒则从头开始
*/
const getInitialPosition = (videoInfo: IVideoInfo): number => {
// 从服务器获取播放位置
const serverPosition = videoInfo.userCourseVideoPositionEntity?.position || 0
// 从本地存储获取播放位置
const localPosition = videoStorage.getVideoPosition(videoInfo.id) || 0
// 返回较大的值
let position = Math.max(serverPosition, localPosition)
// 如果播放位置接近视频结尾最后5秒内则从头开始
const videoDuration = videoInfo.duration || 0
if (videoDuration > 0 && position >= videoDuration - 5) {
position = 0
console.log('Video already finished, reset to start')
}
console.log('Initial position:', {
server: serverPosition,
local: localPosition,
duration: videoDuration,
final: position
})
return position
}
/**
* 开始保存进度
* 每秒保存到本地
*/
const startSaving = (videoInfo: IVideoInfo) => {
// 清除之前的定时器
stopSaving()
// 每秒保存到本地
saveTimer = setInterval(() => {
if (currentTime.value > 0) {
videoStorage.saveVideoPosition(
videoInfo.id,
Math.floor(currentTime.value),
videoInfo
)
}
}, 1000)
}
/**
* 停止保存进度
*/
const stopSaving = () => {
if (saveTimer) {
clearInterval(saveTimer)
saveTimer = null
}
}
/**
* 保存进度到服务器
*/
const saveToServer = async (videoId: number, position: number) => {
if (isSaving.value) return
try {
isSaving.value = true
await videoApi.saveCoursePosition({
videoId,
position
})
console.log('Progress saved to server:', { videoId, position })
} catch (error) {
console.error('Failed to save progress to server:', error)
} finally {
isSaving.value = false
}
}
/**
* 立即保存当前进度
*/
const saveNow = async (videoInfo: IVideoInfo) => {
if (currentTime.value > 0) {
// 保存到本地
videoStorage.saveVideoPosition(
videoInfo.id,
Math.floor(currentTime.value),
videoInfo
)
// 保存到服务器
await saveToServer(videoInfo.id, Math.floor(currentTime.value))
}
}
/**
* 更新当前播放时间
*/
const updateCurrentTime = (time: number) => {
currentTime.value = time
}
return {
currentTime,
isSaving,
getInitialPosition,
startSaving,
stopSaving,
saveToServer,
saveNow,
updateCurrentTime
}
}