node文件资源管理器读取视频信息从零实现
前置准备
需要 ffmpeg 与配套的 ffprobe
- ffprobe 用于获取视频的媒体信息。视频流,音频流,字幕等信息
- ffmpeg 用于获取视频播放更多信息。对视频某个时间段进行截图等操作
需要开发机安装 ffmpeg 或 docker 容器内安装 ffmpeg 开发。全环境的 ffmpeg 较大,对最终生成的 docker 镜像的大小影响较大。
dockerfiel 添加一条安装 ffmpeg 的方法
RUN apk add --no-cache ffmpeg
开发
这次主要使用 ffprobe 获取视频的媒体信息。
安装依赖
explorer-manage
pnpm i ffprobe pnpm i @types/ffprobe -D
ffprobe 依赖主要用于将 ffprobe 命令输出的信息进行格式化成 node 可以直接消费的结构。
explorer-manage 创建一个文件 src/ffmpeg/main.mjs,内容如下
import ff_probe from 'ffprobe' import { formatPath, resetPath } from '../../lib/format-path.mjs' // npm install ffprobe-static // import ff_probe_static from 'ffprobe-static' export const getVideoInfo = (path = '') => { return ff_probe(formatPath(path), { path: 'ffprobe', }).catch((err) => { console.log({ err }) }) }
其中可以使用 npm install ffprobe-static 安装 ffprobe 的静态文件,供 ffprobe 依赖提供的 path: ff\_probe\_static.path 方法注入路径。由于开发机上已安装 ffmpeg,所以这里仅供参考。
explorer 客户端
客户端依旧使用 Next.js 的 server action 调用 getVideoInfo 方法实现。
常规套路
- 使用上下文控制侧边抽屉弹窗显示
- 侧边抽屉弹窗内的视频流、音频流、字幕等信息使用 Tab 组件区分
server action
'use server' import { getVideoInfo } from '@/explorer-manager/src/ffmpeg/main.mjs' export const getVideoInfoAction: typeof getVideoInfo = (path) => { return getVideoInfo(path) }
这里偷懒了,直接使用 typeof getVideoInfo 给 getVideoInfoAction 进行状态声明。
modal
'use client' import React from 'react' import { Card, Descriptions, Drawer, Space, Tabs } from 'antd' import { map, isEmpty, isObject } from 'lodash' import { useRequest } from 'ahooks' import { VideoInfoContext } from '@/components/video-info-modal/video-info-context' import { getVideoInfoAction } from '@/components/video-info-modal/action' const VideoInfoItem: React.FC = () => { const video_path = VideoInfoContext.useStore() const { data, loading, run } = useRequest(() => getVideoInfoAction(video_path)) return ( <Card loading={loading}> <Tabs items={data?.streams.map((item) => { return { key: [item.codec_type, item.index].join('-'), label: ( <Space> {item.codec_type} {item.index > 0 ? item.index : ''} </Space> ), children: ( <> <Descriptions column={1} labelStyle={{ width: '15em', textAlign: 'right' }} style={{ maxHeight: '85vh', overflow: 'scroll', overscrollBehavior: 'contain' }} > {map(item, (value, key) => ( <Descriptions.Item key={key} label={key}> {isObject(value) ? <pre>{JSON.stringify(value, null, 2)}</pre> : value?.toString()} </Descriptions.Item> ))} </Descriptions> </> ), } })} /> </Card> ) } const VideoInfoModal: React.FC = () => { const video_path = VideoInfoContext.useStore() const dispatch = VideoInfoContext.useDispatch() return ( <Drawer title="视频信息" placement="right" open={!isEmpty(video_path)} width={1000} onClose={() => dispatch('')} footer={false} destroyOnClose={true} > <VideoInfoItem /> </Drawer> ) } export default VideoInfoModal
- 使用 ahooks 的 useRequest 封装 server action 方法。内置 loading、 data 等状态。
- 当组件首次被装载时,useRequest 调用 getVideoInfoAction 获取数据
- 内部使用 Antd 提供的 Card 组件用于 loading 状态。 Tab 对数据的视频、音频等信息进行区分显示。
效果
git-repo
以上就是node文件资源管理器读取视频信息从零实现的详细内容,更多关于node文件资源读取视频的资料请关注脚本之家其它相关文章!
相关文章
nodejs express配置自签名https服务器的方法
这篇文章主要介绍了nodejs express配置自签名https服务器的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-05-05
最新评论