mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: 视频补充帧跳转功能 (#3653)
This commit is contained in:
parent
b8123a92d0
commit
93fedfb4a4
@ -25,16 +25,56 @@ order: 71
|
||||
- `video/x-flv`,使用 [mpegts.js](https://github.com/xqq/mpegts.js) 播放 flv
|
||||
- `application/x-mpegURL`,使用 [hls.js](https://github.com/video-dev/hls.js/) 播放 hls 格式
|
||||
|
||||
## 视频帧切换功能
|
||||
|
||||
可以定义一组视频帧,渲染的时候会列出来这些帧,点击的时候会自动跳转到对应位置开始播放。
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "video",
|
||||
"src": "https://amis.bj.bcebos.com/amis/2019-12/1577157317579/trailer_hd.mp4",
|
||||
"poster": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png",
|
||||
"jumpFrame": true,
|
||||
"jumpBufferDuration": 0,
|
||||
frames: {
|
||||
'00:10': '',
|
||||
'00:20': '',
|
||||
'00:30': ''
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
可以设置帧图片如果有的话,这个示例偷懒直接用封面了。
|
||||
|
||||
```schema: scope="body"
|
||||
{
|
||||
"type": "video",
|
||||
"src": "https://amis.bj.bcebos.com/amis/2019-12/1577157317579/trailer_hd.mp4",
|
||||
"poster": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png",
|
||||
"jumpFrame": true,
|
||||
"jumpBufferDuration": 0,
|
||||
stopOnNextFrame: true,
|
||||
frames: {
|
||||
'00:10': 'https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png',
|
||||
'00:20': 'https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png',
|
||||
'00:30': 'https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png'
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## 属性表
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| --------- | --------- | --------- | -------------------------------------------------------- |
|
||||
| type | `string` | `"video"` | 指定为 video 渲染器 |
|
||||
| className | `string` | | 外层 Dom 的类名 |
|
||||
| src | `string` | | 视频地址 |
|
||||
| isLive | `boolean` | false | 是否为直播,视频为直播时需要添加上,支持`flv`和`hls`格式 |
|
||||
| videoType | `string` | | 指定直播视频格式 |
|
||||
| poster | `string` | | 视频封面地址 |
|
||||
| muted | `boolean` | | 是否静音 |
|
||||
| autoPlay | `boolean` | | 是否自动播放 |
|
||||
| rates | `array` | | 倍数,格式为`[1.0, 1.5, 2.0]` |
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ------------------ | --------- | --------- | ------------------------------------------------------------------------- |
|
||||
| type | `string` | `"video"` | 指定为 video 渲染器 |
|
||||
| className | `string` | | 外层 Dom 的类名 |
|
||||
| src | `string` | | 视频地址 |
|
||||
| isLive | `boolean` | false | 是否为直播,视频为直播时需要添加上,支持`flv`和`hls`格式 |
|
||||
| videoType | `string` | | 指定直播视频格式 |
|
||||
| poster | `string` | | 视频封面地址 |
|
||||
| muted | `boolean` | | 是否静音 |
|
||||
| autoPlay | `boolean` | | 是否自动播放 |
|
||||
| rates | `array` | | 倍数,格式为`[1.0, 1.5, 2.0]` |
|
||||
| frames | `object` | | key 是时刻信息,value 可以可以为空,可有设置为图片地址,请看上方示例 |
|
||||
| jumpBufferDuration | `boolean` | | 点击帧的时候默认是跳转到对应的时刻,如果想提前 3 秒钟,可以设置这个值为 3 |
|
||||
| stopOnNextFrame | `boolean` | | 到了下一帧默认是接着播放,配置这个会自动停止 |
|
||||
|
@ -113,6 +113,12 @@ export interface VideoSchema extends BaseSchema {
|
||||
* 跳转到帧时,往前多少秒。
|
||||
*/
|
||||
jumpBufferDuration?: number;
|
||||
|
||||
/**
|
||||
* 默认播放的时候到了下一帧会继续播放,同时高亮下一帧。
|
||||
* 如果配置这个则会停止播放,等待用户选择新的区间再播放。
|
||||
*/
|
||||
stopOnNextFrame?: boolean;
|
||||
}
|
||||
|
||||
const str2seconds: (str: string) => number = str =>
|
||||
@ -389,6 +395,7 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
||||
player: any;
|
||||
times: Array<number>;
|
||||
currentIndex: number;
|
||||
manualJump = false;
|
||||
constructor(props: VideoProps) {
|
||||
super(props);
|
||||
|
||||
@ -459,6 +466,7 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
||||
let index = 0;
|
||||
const times = this.times;
|
||||
const len = times.length;
|
||||
const stopOnNextFrame = this.props.stopOnNextFrame;
|
||||
while (index < len - 1) {
|
||||
if (
|
||||
times[index + 1] &&
|
||||
@ -472,6 +480,12 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
||||
|
||||
if (this.currentIndex !== index) {
|
||||
this.moveCursorToIndex(index);
|
||||
|
||||
stopOnNextFrame && !this.manualJump && player.pause();
|
||||
|
||||
if (this.manualJump) {
|
||||
this.manualJump = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -505,6 +519,7 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
||||
const times = this.times;
|
||||
const player = this.player;
|
||||
|
||||
this.manualJump = true;
|
||||
player.seek(times[index] - jumpBufferDuration);
|
||||
player.play();
|
||||
}
|
||||
@ -572,11 +587,11 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="pull-in-xxs" key={i}>
|
||||
<div className={`${ns}Hbox ${ns}Video-frameItem`}>
|
||||
<div className="pull-in-xs" key={i}>
|
||||
<div className={cx(`Hbox Video-frameItem`)}>
|
||||
{items.map((item, key) => (
|
||||
<div
|
||||
className={`${ns}Hbox-col Wrapper--xxs ${ns}Video-frame`}
|
||||
className={cx(`Hbox-col Wrapper--xs Video-frame`)}
|
||||
key={key}
|
||||
onClick={() =>
|
||||
this.jumpToIndex(i * (columnsCount as number) + key)
|
||||
@ -585,7 +600,7 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
||||
{item.src ? (
|
||||
<img className="w-full" alt="poster" src={item.src} />
|
||||
) : null}
|
||||
<div className={`${ns}Video-frameLabel`}>{item.time}</div>
|
||||
<div className={cx(`Video-frameLabel`)}>{item.time}</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@ -593,7 +608,7 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
||||
/* 补充空白 */ restCount
|
||||
? blankArray.map((_, index) => (
|
||||
<div
|
||||
className={`${ns}Hbox-col Wrapper--xxs`}
|
||||
className={cx(`Hbox-col Wrapper--xs`)}
|
||||
key={`blank_${index}`}
|
||||
/>
|
||||
))
|
||||
@ -604,7 +619,7 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
||||
);
|
||||
})}
|
||||
{jumpFrame ? (
|
||||
<span ref={this.cursorRef} className={`${ns}Video-cursor`} />
|
||||
<span ref={this.cursorRef} className={cx('Video-cursor')} />
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user