useVideo
视频操作, 如保存、选择等.
何时使用
当需要对视频进行操作时
API
const [
videoContext,
{
choose,
chooseMedia,
open,
save,
compress,
get,
},
] = useVideo(id, option?);
参数说明
提示
id为必传的参数. 因为会在初始阶段创建和id条件相符的全局video唯一上下文!
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
id | video 组件的 id | string | - |
option | 初始选择视频配置(若指定后面可与新的配置合并) | ExcludeOption<Taro.chooseVideo.Option> | - |
返回值说明
返回值 | 说明 | 类型 |
---|---|---|
videoContext | video 上下文 | VideoContext |
choose | 拍摄视频或从手机相册中选视频 | PromiseOptionalAction<ChooseOption, Taro.chooseVideo.SuccessCallbackResult> |
chooseMedia | 拍摄或从手机相册中选择图片或视频 | PromiseOptionalAction<ExcludeOption<Taro.chooseMedia.Option>, Taro.chooseMedia.SuccessCallbackResult> |
open | 打开视频编辑器 | PromiseAction<string, Taro.openVideoEditor.SuccessCallbackResult> |
save | 保存视频到系统相册。支持 mp4 视频格式 | PromiseAction<string> |
compress | 压缩视频接口 | PromiseAction<ExcludeOption<Taro.compressVideo.Option>, Taro.compressVideo.SuccessCallbackResult> |
get | 获取视频详细信息 | PromiseAction<string, Taro.getVideoInfo.SuccessCallbackResult> |
代码演示
- React
- Vue
media/useVideo/index
import React from 'react';
import { ENV_TYPE } from '@tarojs/taro';
import { useState } from '@taro-hooks/core';
import { Video } from '@tarojs/components';
import { escapeState } from '@taro-hooks/shared';
import { useToast, useVideo, useEnv } from 'taro-hooks';
import DemoContent from '@src/components/DemoContent';
import { Button, Cell } from '@taroify/core';
import './index.less';
export default () => {
const videoId = 'demo-video-id';
const env = useEnv();
const [videoInfo, setVideoInfo] =
useState<Taro.chooseVideo.SuccessCallbackResult>();
const [videoSummary, setVideoSummary] =
useState<Taro.getVideoInfo.SuccessCallbackResult>();
const [videoContext, { choose, chooseMedia, open, save, compress, get }] =
useVideo(videoId, {
camera: 'back',
sourceType: ['camera', 'album'],
});
const { show } = useToast({
title: 'initial title',
duration: 500,
mask: true,
});
const handleChoose = async () => {
try {
const result = await choose();
setVideoInfo(result);
if (env === ENV_TYPE.WEAPP) {
const summary = await get(result.tempFilePath);
setVideoSummary(summary);
}
} catch (e) {
show({ title: '获取视频或信息失败', icon: 'error' });
}
};
const handleVideoAction = (action) => {
console.log(videoContext);
escapeState(videoContext)?.[action]?.();
};
const handleCompress = async () => {
try {
const { size } = await compress({ src: videoInfo?.tempFilePath });
show({ title: '压缩: ${size}/${videoInfo?.size}' });
} catch (e) {
show({ title: '压缩失败', icon: 'error' });
}
};
return (
<DemoContent>
<Video id={videoId} src={videoInfo?.tempFilePath ?? ''} />
<Button
block
color="primary"
className="gap"
onClick={() => handleChoose()}
shape="square"
>
选择视频
</Button>
<Button
block
color="primary"
className="gap"
onClick={() => handleVideoAction('play')}
shape="square"
>
播放视频
</Button>
<Button
block
color="primary"
className="gap"
onClick={() => handleVideoAction('pause')}
shape="square"
>
暂停视频
</Button>
<Button
block
color="primary"
className="gap"
onClick={() => handleCompress()}
shape="square"
>
压缩视频(小程序独有)
</Button>
<Button
block
color="primary"
className="gap"
onClick={() => open(videoInfo?.tempFilePath)}
shape="square"
>
打开视频编辑器(小程序独有)
</Button>
<Button
block
color="primary"
className="gap"
onClick={() => save(videoInfo?.tempFilePath)}
shape="square"
>
保存视频
</Button>
<Cell.Group title="视频信息">
{Object.entries(videoSummary ?? {}).map(([key, value]) => (
<Cell key={key} title={key} brief={JSON.stringify(value)}></Cell>
))}
</Cell.Group>
</DemoContent>
);
};
media/useVideo/index
<template>
<demo-content>
<video :id="videoId" :src="videoInfo?.tempFilePath"></video>
<nut-button
shape="square"
type="primary"
class="gap"
block
@click="handleChoose()"
>选择视频</nut-button
>
<nut-button
shape="square"
type="primary"
class="gap"
block
@click="handleVideoAction('play')"
>播放视频</nut-button
>
<nut-button
shape="square"
type="primary"
class="gap"
block
@click="handleVideoAction('pause')"
>暂停视频</nut-button
>
<nut-button
shape="square"
type="primary"
class="gap"
block
@click="handleCompress()"
>压缩视频(小程序独有)</nut-button
>
<nut-button
shape="square"
type="primary"
class="gap"
block
@click="open(videoInfo?.tempFilePath)"
>打开视频编辑器(小程序独有)</nut-button
>
<nut-button
shape="square"
type="primary"
class="gap"
block
@click="save(videoInfo?.tempFilePath)"
>保存视频</nut-button
>
<nut-cell-group title="视频信息">
<nut-cell
v-for="(value, key) in videoSummary ?? {}"
:key="key"
:title="key"
:sub-title="$filters.stringify(value)"
></nut-cell>
</nut-cell-group>
</demo-content>
</template>
<script setup lang="ts">
import { ENV_TYPE } from '@tarojs/taro';
import { useState } from '@taro-hooks/core';
import { escapeState } from '@taro-hooks/shared';
import { useToast, useVideo, useEnv } from 'taro-hooks';
const videoId = 'demo-video-id';
const env = useEnv();
const [videoInfo, setVideoInfo] =
useState<Taro.chooseVideo.SuccessCallbackResult>();
const [videoSummary, setVideoSummary] =
useState<Taro.getVideoInfo.SuccessCallbackResult>();
const [videoContext, { choose, chooseMedia, open, save, compress, get }] =
useVideo(videoId, {
camera: 'back',
sourceType: ['camera', 'album'],
});
const { show } = useToast({
title: 'initial title',
duration: 500,
mask: true,
});
const handleChoose = async () => {
try {
const result = await choose();
setVideoInfo(result);
if (env === ENV_TYPE.WEAPP) {
const summary = await get(result.tempFilePath);
setVideoSummary(summary);
}
} catch (e) {
show({ title: '获取视频或信息失败', icon: 'error' });
}
};
const handleVideoAction = (action) => {
console.log(videoContext);
escapeState(videoContext)?.[action]?.();
};
const handleCompress = async () => {
try {
const { size } = await compress({ src: videoInfo?.tempFilePath });
show({ title: '压缩: ${size}/${videoInfo?.size}' });
} catch (e) {
show({ title: '压缩失败', icon: 'error' });
}
};
</script>
<style>
#demo-video-id {
position: relative;
left: auto;
top: auto;
width: 100%;
height: 200px;
}
</style>
Hook 支持度
微信小程序 | H5 | ReactNative |
---|---|---|
✔️ | ✔️(部分) | ✔️ |