feat: 历史视频详情查看
This commit is contained in:
parent
a2770765d8
commit
661b6f38da
@ -19,6 +19,7 @@ type StateUpdate = Partial<State> | ((prev: State) => Partial<State>)
|
||||
|
||||
type Props = {
|
||||
url?: string; cover?: string; showControls?: boolean; className?: string;
|
||||
poster?: string;
|
||||
onChange?: (state: State) => void;
|
||||
muted?: boolean;
|
||||
}
|
||||
@ -47,6 +48,13 @@ export const Player = React.forwardRef<PlayerInstance, Props>((props, ref) => {
|
||||
return _state
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
if(props.url && tcPlayer){
|
||||
tcPlayer.src(props.url)
|
||||
}
|
||||
},[props.url, tcPlayer])
|
||||
|
||||
useEffect(() => {
|
||||
const playerVideo = document.createElement('video');
|
||||
const playerId = `player-container-${Date.now().toString(16)}`;
|
||||
@ -61,6 +69,7 @@ export const Player = React.forwardRef<PlayerInstance, Props>((props, ref) => {
|
||||
//sources: [{src: props.url}],
|
||||
controls: props.showControls,
|
||||
// muted:props.muted,
|
||||
poster: props.poster,
|
||||
autoplay: true,
|
||||
licenseUrl: 'https://license.vod2.myqcloud.com/license/v2/1328581896_1/v_cube.license'
|
||||
}
|
||||
|
@ -1,42 +1,88 @@
|
||||
import {Button, Modal} from "antd";
|
||||
|
||||
import {Button, Input, Modal} from "antd";
|
||||
import {saveAs} from "file-saver";
|
||||
import {useEffect, useState} from "react";
|
||||
import {useSetState} from "ahooks";
|
||||
import {Player} from "@/components/video/player.tsx";
|
||||
|
||||
import ArticleGroup from "@/components/article/group";
|
||||
import * as article from "@/service/api/article.ts";
|
||||
import {push2room} from "@/service/api/video.ts";
|
||||
import {showErrorToast, showToast} from "@/components/message.ts";
|
||||
|
||||
type Props = {
|
||||
video?: VideoInfo;
|
||||
onClose?: () => void
|
||||
}
|
||||
export default function VideoDetail({video, onClose}: Props) {
|
||||
const startStream = () => {
|
||||
const [groups, setGroups] = useState<BlockContent[][]>([]);
|
||||
|
||||
const [state, setState] = useSetState({
|
||||
exporting: false,
|
||||
pushing: false,
|
||||
})
|
||||
// 将视频推送到数字人直播间
|
||||
const pushToRoom = () => {
|
||||
if (video) {
|
||||
if (state.pushing) return
|
||||
setState({pushing: true})
|
||||
push2room([video.id]).then(() => {
|
||||
showToast('一键推流成功,已推流至数字人直播间,请查看!', 'success')
|
||||
}).catch(showErrorToast).finally(() => {
|
||||
setState({pushing: false})
|
||||
})
|
||||
}
|
||||
}
|
||||
// 下载视频
|
||||
const downloadVideo = () => {
|
||||
if (video?.oss_video_url) {
|
||||
const filename = video.oss_video_url.split('/').pop() || `${video.id}.flv`
|
||||
saveAs(video.oss_video_url, filename)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (video) {
|
||||
if (video.id > 0) {
|
||||
article.getById(video.id).then(res => {
|
||||
setGroups(res.content_group)
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [video])
|
||||
|
||||
return (<>
|
||||
<Modal open={!!video} title="新闻视频详情" width={1000} footer={null} onCancel={onClose}>
|
||||
<div className="flex gap-2 my-5">
|
||||
<div className="news-video w-[350px]">
|
||||
<div className="video-container bg-gray-100 rounded overflow-hidden h-[400px]">
|
||||
<Player url={'https://file.wx.wm-app.xyz/os/media/ymca.mp4'} simple showControls />
|
||||
<div className="video-container bg-gray-100 rounded overflow-hidden h-[640px]">
|
||||
<Player url={video?.oss_video_url} poster={video?.cover} showControls={true}
|
||||
className="w-[360px] h-[640px] bg-white"/>
|
||||
</div>
|
||||
<div className="video-info text-right text-sm text-gray-600 mt-3">
|
||||
<span>创建时间: 5小时前</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail flex-1 ml-5">
|
||||
<div className="title">
|
||||
<span>标题: xxxxxxxx</span>
|
||||
<div className="text-lg">新闻内容</div>
|
||||
<div className="article-title mt-5 items-center flex">
|
||||
<span className="text text-base">标题</span>
|
||||
<span className="ml-4 flex-1">
|
||||
<Input value={video?.title}/>
|
||||
</span>
|
||||
</div>
|
||||
<div className="content-container max-h-[500px] overflow-auto pr-1 mt-4">
|
||||
<ArticleGroup groups={[]}/>
|
||||
<div className="aricle-body mt-3">
|
||||
<div className="title">
|
||||
<span className="text text-base">正文</span>
|
||||
</div>
|
||||
<div className="box mt-1">
|
||||
<ArticleGroup groups={groups}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="footer flex justify-between">
|
||||
<div className="action flex gap-2">
|
||||
<Button type="primary" onClick={startStream}>一键推流</Button>
|
||||
<Button loading={state.pushing} type="primary" onClick={pushToRoom}>一键推流</Button>
|
||||
<Button onClick={downloadVideo}>下载视频</Button>
|
||||
</div>
|
||||
<div className="close">
|
||||
|
@ -86,6 +86,6 @@ export default function LibraryIndex() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<VideoDetail video={detailVideo} onClose={() => setDetailVideo(undefined)}/>
|
||||
{detailVideo && <VideoDetail video={detailVideo} onClose={() => setDetailVideo(undefined)}/>}
|
||||
</>)
|
||||
}
|
@ -4,12 +4,13 @@ import {showErrorToast, showToast} from "@/components/message.ts";
|
||||
import {push2video} from "@/service/api/article.ts";
|
||||
|
||||
|
||||
export default function ButtonPush2Video(props: { ids: Id[] }) {
|
||||
export default function ButtonPush2Video(props: { ids: Id[];onSuccess?:()=>void; }) {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const handlePush = () => {
|
||||
setLoading(true)
|
||||
push2video(props.ids).then(() => {
|
||||
showToast('一键推流成功,已成功推入数字人视频生成,请前往数字人视频生成页面查看!', 'success')
|
||||
props.onSuccess?.()
|
||||
}).catch(showErrorToast).finally(() => {
|
||||
setLoading(false)
|
||||
})
|
||||
|
@ -89,7 +89,7 @@ export default function NewEdit() {
|
||||
pagination: {page, limit: 10}
|
||||
}))}
|
||||
/>
|
||||
<ButtonPush2Video ids={selectedRowKeys}/>
|
||||
<ButtonPush2Video ids={selectedRowKeys} onSuccess={refresh}/>
|
||||
</div>}
|
||||
</div>
|
||||
<ArticleEditModal
|
||||
|
@ -111,7 +111,7 @@ export default function NewsIndex() {
|
||||
<div className="info text-gray-300 flex items-center justify-between gap-3 text-sm">
|
||||
<div>来源: <span>{item.media_name}</span></div>
|
||||
{/*<Divider type="vertical" />*/}
|
||||
<div>发布时间: <span>{item.publish_time}</span></div>
|
||||
<div>发布时间: <span>{formatTime(item.publish_time)}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,9 +45,9 @@ export default function VideoIndex() {
|
||||
|
||||
// 播放视频
|
||||
const playVideo = (video: VideoInfo, playingIndex: number) => {
|
||||
if (video.status !== 1) { // video.oss_video_url &&
|
||||
if (video.oss_video_url && video.status !== 1) {
|
||||
setState({playingIndex})
|
||||
player.current?.play(video.oss_video_url||'https://staticplus.gachafun.com/ai-collect/composite_video/2024-12-14/1185251497659736064.flv', 0)
|
||||
player.current?.play(video.oss_video_url, 0)
|
||||
}
|
||||
}
|
||||
// 处理全选
|
||||
|
Loading…
x
Reference in New Issue
Block a user