mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-28 13:31:32 +08:00
feat(video): add video download functionality
implement video download feature with progress tracking and error handling update video status and thumbnail types to support null values add download error message to i18n
This commit is contained in:
parent
b68a0ffaba
commit
1c89262929
@ -144,6 +144,7 @@ export const useVideos = (providerId: string) => {
|
||||
addVideo,
|
||||
updateVideo,
|
||||
setVideos,
|
||||
setVideo,
|
||||
removeVideo
|
||||
}
|
||||
}
|
||||
|
||||
@ -4651,6 +4651,7 @@
|
||||
"video": {
|
||||
"error": {
|
||||
"create": "Failed to create video",
|
||||
"download": "Failed to download video.",
|
||||
"invalid": "Invalid video",
|
||||
"load": {
|
||||
"message": "Failed to load the video",
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { Button, cn, Image, Skeleton, Textarea, Tooltip } from '@heroui/react'
|
||||
import { loggerService } from '@logger'
|
||||
import { useAddOpenAIVideo } from '@renderer/hooks/video/useAddOpenAIVideo'
|
||||
import { createVideo } from '@renderer/services/ApiService'
|
||||
import { useVideos } from '@renderer/hooks/video/useVideos'
|
||||
import { createVideo, retrieveVideoContent } from '@renderer/services/ApiService'
|
||||
import { Provider } from '@renderer/types'
|
||||
import { CreateVideoParams, Video } from '@renderer/types/video'
|
||||
import { getErrorMessage } from '@renderer/utils'
|
||||
@ -26,14 +27,20 @@ const logger = loggerService.withContext('VideoPanel')
|
||||
export const VideoPanel = ({ provider, video, params, updateParams }: VideoPanelProps) => {
|
||||
const { t } = useTranslation()
|
||||
const addOpenAIVideo = useAddOpenAIVideo(provider.id)
|
||||
const { setVideo } = useVideos(provider.id)
|
||||
|
||||
const [isProcessing, setIsProcessing] = useState(false)
|
||||
const fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const inputReference = params.params.input_reference
|
||||
|
||||
const couldCreateVideo = useMemo(
|
||||
() => !isProcessing && !isEmpty(params.params.prompt),
|
||||
[isProcessing, params.params.prompt]
|
||||
() =>
|
||||
!isProcessing &&
|
||||
!isEmpty(params.params.prompt) &&
|
||||
video?.status !== 'queued' &&
|
||||
video?.status !== 'downloading' &&
|
||||
video?.status !== 'in_progress',
|
||||
[isProcessing, params.params.prompt, video?.status]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
@ -69,8 +76,28 @@ export const VideoPanel = ({ provider, video, params, updateParams }: VideoPanel
|
||||
}
|
||||
}, [addOpenAIVideo, couldCreateVideo, params, t, video])
|
||||
|
||||
const handleDownloadVideo = (videoId: string) => {
|
||||
window.toast.info('Not implemented')
|
||||
const handleDownloadVideo = async () => {
|
||||
if (!video) return
|
||||
if (video.status === 'completed' || video.status === 'downloaded') {
|
||||
setVideo({
|
||||
...video,
|
||||
status: 'downloading',
|
||||
progress: 0
|
||||
})
|
||||
const promise = retrieveVideoContent({ type: 'openai', videoId: video.id, provider })
|
||||
promise
|
||||
.then((result) => result.response)
|
||||
.then((response) => {
|
||||
// TODO: implement download
|
||||
logger.debug('download response', response)
|
||||
})
|
||||
promise.catch((e) => {
|
||||
logger.error(`Failed to download video ${video.id}.`, e as Error)
|
||||
window.toast.error(t('video.error.download'))
|
||||
// rollback
|
||||
setVideo(video)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleUploadFile = useCallback(() => {
|
||||
|
||||
@ -21,7 +21,7 @@ export type VideoViewerProps =
|
||||
}
|
||||
| {
|
||||
video: Video
|
||||
onDownload: (videoId: string) => void
|
||||
onDownload: () => void
|
||||
}
|
||||
|
||||
export const VideoViewer = ({ video, onDownload }: VideoViewerProps) => {
|
||||
@ -33,7 +33,7 @@ export const VideoViewer = ({ video, onDownload }: VideoViewerProps) => {
|
||||
{video === undefined && t('video.undefined')}
|
||||
{video && video.status === 'queued' && <QueuedVideo />}
|
||||
{video && video.status === 'in_progress' && <InProgressVideo progress={video.progress} />}
|
||||
{video && video.status === 'completed' && <CompletedVideo onDownload={() => onDownload(video.id)} />}
|
||||
{video && video.status === 'completed' && <CompletedVideo onDownload={onDownload} />}
|
||||
{video && video.status === 'downloading' && <DownloadingVideo progress={video.progress} />}
|
||||
{video && video.status === 'downloaded' && loadSuccess !== false && (
|
||||
<video
|
||||
|
||||
@ -47,13 +47,13 @@ export interface VideoCompleted extends VideoBase {
|
||||
|
||||
export interface VideoDownloading extends VideoBase {
|
||||
readonly status: 'downloading'
|
||||
thumbnail: string
|
||||
thumbnail: string | null
|
||||
/** integer percent */
|
||||
progress: number
|
||||
}
|
||||
export interface VideoDownloaded extends VideoBase {
|
||||
readonly status: 'downloaded'
|
||||
thumbnail: string
|
||||
thumbnail: string | null
|
||||
/** Managed by fileManager */
|
||||
fileId: string
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user