Skip to content

Commit

Permalink
feat(usevideo): add useVideo hook
Browse files Browse the repository at this point in the history
  • Loading branch information
innocces committed Aug 1, 2021
1 parent 5ddfcac commit 585e18b
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/app/src/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export default {
'pages/useBrightness/index',
// media
'pages/useImage/index',
'pages/useVideo/index',
],
window: {
backgroundTextStyle: 'light',
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/pages/useVideo/index.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
navigationBarTitleText: 'useVideo',
};
86 changes: 86 additions & 0 deletions packages/app/src/pages/useVideo/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, { useCallback, useState } from 'react';
import { AtNoticebar, AtButton } from 'taro-ui';
import { Video } from '@tarojs/components';

import DocPage from '@components/DocPage';

import { useVideo, useEnv, useToast } from 'taro-hooks';
import { chooseVideo, ENV_TYPE, useReady } from '@tarojs/taro';

export default () => {
const env = useEnv();
const [show] = useToast({ mask: true });
const [videoContext, { choose, save, create }] = useVideo({
camera: 'back',
sourceType: ['camera', 'album'],
});
const [videoResult, setVideoResult] =
useState<chooseVideo.SuccessCallbackResult>();

useReady(() => {
if (env && env !== ENV_TYPE.WEB) {
create('useVideoContext');
}
});

const handleChooseVideo = useCallback(() => {
choose({ maxDuration: 10 }).then(setVideoResult);
}, [choose]);

const handleSaveVideo = useCallback(
(filePath) => {
save(filePath)
.then(() => {
show({
title: '保存成功',
});
})
.catch(() => {
show({
icon: 'none',
title: '保存失败',
});
});
},
[save, show],
);

return (
<>
<AtNoticebar marquee>当前hook不支持h5, 请移步小程序体验</AtNoticebar>
<DocPage title="useVideo 视频" panelTitle="useVideo">
<Video
id="useVideoContext"
className="demo"
src={videoResult?.tempFilePath || ''}
/>
<AtButton
disabled={env === ENV_TYPE.WEB}
className="gap"
onClick={handleChooseVideo}
>
选择视频
</AtButton>
<AtButton
disabled={!videoContext || !videoResult?.tempFilePath}
onClick={() => videoContext.play()}
>
播放视频
</AtButton>
<AtButton
className="gap"
disabled={!videoContext || !videoResult?.tempFilePath}
onClick={() => videoContext.pause()}
>
暂停视频
</AtButton>
<AtButton
disabled={env === ENV_TYPE.WEB || !videoResult?.tempFilePath}
onClick={() => handleSaveVideo(videoResult?.tempFilePath)}
>
保存视频
</AtButton>
</DocPage>
</>
);
};
2 changes: 2 additions & 0 deletions packages/hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import useBrightness from './useBrightness';

// media
import useImage from './useImage';
import useVideo from './useVideo';

export {
useEnv,
Expand Down Expand Up @@ -67,4 +68,5 @@ export {
useMotion,
useBrightness,
useImage,
useVideo,
};
49 changes: 49 additions & 0 deletions packages/hooks/src/useVideo/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: useVideo
nav:
title: Hooks
path: /hooks
order: 2
group:
title: 媒体
path: /media
---

# useVideo

视频操作, 如保存、选择等.

## 何时使用

当需要对视频进行操作时

## API

```jsx | pure
const [videoContext, { choose, save, create }] = useVideo(initialOption?);
```
## 参数说明
| 参数 | 说明 | 类型 | 默认值 |
| ------------- | -------------------------------------------- | ----------------------------------------------------------------------------- | ------ |
| initialOption | 初始选择视频配置(若指定后面可与新的配置合并) | `Pick<chooseVideo.Option, 'camera' &#124; 'sourceType' &#124; 'maxDuration'>` | - |
## 返回值说明
| 返回值 | 说明 | 类型 |
| ------------ | ----------------- | -------------------------------------------------------------------- |
| videoContext | video 上下文 | `VideoContext &#124; undefined` |
| choose | 选择视频 | `(option?: IOptions) => Promise<chooseVideo。SuccessCallbackResult>` |
| save | 保存视频 | `(filePath: string,) => Promise<General.CallbackResult>` |
| create | 创建 Video 上下文 | `(id: string, component?: Record<string, any>,) => IVideoContext` |
## 代码演示
<code src="@pages/useVideo" />
## Hook 支持度
| 微信小程序 | H5 | ReactNative |
| :--------: | :-: | :---------: |
| ✔️ | | ✔️ |
110 changes: 110 additions & 0 deletions packages/hooks/src/useVideo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import {
chooseVideo,
saveVideoToPhotosAlbum,
createVideoContext,
VideoContext,
General,
ENV_TYPE,
} from '@tarojs/taro';
import { useCallback, useState } from 'react';
import { useEnv } from '..';

import { saveImageForH5 } from '../useImage/utils';

export type IOptions = Pick<
chooseVideo.Option,
'camera' | 'sourceType' | 'maxDuration'
>;

export type IVideoContext = VideoContext | undefined;

export type ChooseVideoAction = (
option?: IOptions,
) => Promise<chooseVideo.SuccessCallbackResult>;

export type CreateContextAction = (
id: string,
component?: Record<string, any>,
) => IVideoContext;

export type SaveVideoAction = (
filePath: string,
) => Promise<General.CallbackResult>;

export interface IAction {
choose: ChooseVideoAction;
create: CreateContextAction;
save: SaveVideoAction;
}

function useVideo(options?: IOptions): [IVideoContext, IAction] {
const [videoContext, setVideoContext] = useState<IVideoContext>();
const env = useEnv();

const chooseVideoAsync = useCallback<ChooseVideoAction>(
(option) => {
const payload = Object.assign({}, options || {}, option);
return new Promise((resolve, reject) => {
if (env === ENV_TYPE.WEB) {
reject({ errMsg: 'not support for web' });
} else {
chooseVideo({
...payload,
success: resolve,
fail: reject,
}).catch(reject);
}
});
},
[env],
);

const createVideoContextAsync = useCallback<CreateContextAction>(
(id, component) => {
if (env !== ENV_TYPE.WEB) {
const videoContext = createVideoContext(id, component);
if (videoContext) setVideoContext(videoContext);
return videoContext;
}
},
[env],
);

const saveVideoAsync = useCallback<SaveVideoAction>(
(filePath) => {
return new Promise((resolve, reject) => {
if (!filePath) {
reject('please input a filepath to save');
} else {
if (env === ENV_TYPE.WEB) {
saveImageForH5(filePath)
.then((saveResult) => {
resolve({
errMsg: saveResult ? '保存成功' : '保存失败',
});
})
.catch(reject);
} else {
saveVideoToPhotosAlbum({
filePath,
success: resolve,
fail: reject,
}).catch(reject);
}
}
});
},
[env],
);

return [
videoContext,
{
choose: chooseVideoAsync,
create: createVideoContextAsync,
save: saveVideoAsync,
},
];
}

export default useVideo;

0 comments on commit 585e18b

Please # to comment.