parent
9178e7ba47
commit
1df2db15b0
@ -0,0 +1,4 @@ |
|||||||
|
.container{ |
||||||
|
width:750rpx; |
||||||
|
height:600rpx; |
||||||
|
} |
@ -0,0 +1,200 @@ |
|||||||
|
import React, {FC, useEffect, useRef, useState, useImperativeHandle} from "react"; |
||||||
|
import {Image, Text, Video, View} from "@tarojs/components"; |
||||||
|
import "./index.module.scss" |
||||||
|
import Icon from "@/components/icon"; |
||||||
|
import {AtSlider} from "taro-ui"; |
||||||
|
import Taro from "@tarojs/taro"; |
||||||
|
import full from "@/static/img/fullscreen.png" |
||||||
|
import unfull from "@/static/img/exitFullscreen.png" |
||||||
|
|
||||||
|
type Props = { |
||||||
|
src: string |
||||||
|
onRef: any |
||||||
|
} |
||||||
|
|
||||||
|
const VideoPro:FC<Props> = ({src,onRef}) => { |
||||||
|
const globalData = Taro.getApp().globalData |
||||||
|
//用useImperativeHandle暴露一些外部ref能访问的属性
|
||||||
|
useImperativeHandle(onRef, () => { |
||||||
|
return { |
||||||
|
func: pause, |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
// 视频ui控制需要的响应式数据
|
||||||
|
const videoContext = useRef<any>() |
||||||
|
const [isPlay, setIsPlay] = useState(false) |
||||||
|
const [duration,setDuration] = useState(0) // 视频长度 单位秒
|
||||||
|
const updateState = useRef(false) |
||||||
|
const [sliderValue,setSlidervalue] = useState(0) |
||||||
|
const [process_duration, set_process_duration] = useState('00:00') |
||||||
|
const [total_duration, set_total_duration] = useState('00:00') |
||||||
|
const [showMenu,setShowMenu] = useState(true) |
||||||
|
const [isFull,setIsFull] = useState(false) |
||||||
|
const time = useRef<any>() |
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log('组件加载') |
||||||
|
videoContext.current = Taro.createVideoContext('video') |
||||||
|
updateState.current = true |
||||||
|
}, []); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function onTouchStart(){ |
||||||
|
if(!showMenu) { |
||||||
|
setShowMenu(true) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function onTouchEnd(){ |
||||||
|
if(time.current) { |
||||||
|
clearTimeout(time.current) |
||||||
|
time.current = null |
||||||
|
} |
||||||
|
time.current = setTimeout(() => { |
||||||
|
setShowMenu(false) |
||||||
|
},5000) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function bindTimeupdateFun(e) { |
||||||
|
if (updateState.current) { |
||||||
|
let sliderValue = e.detail.currentTime / e.detail.duration * 100; |
||||||
|
setSlidervalue(sliderValue) |
||||||
|
setDuration(e.detail.duration) |
||||||
|
set_total_duration(formatSeconds(e.detail.duration)) |
||||||
|
set_process_duration(formatSeconds(e.detail.currentTime)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function addZero(i){ |
||||||
|
i = typeof i === 'string' ? Number(i) : i; |
||||||
|
return i < 10 ? "0" + i : "" + i; |
||||||
|
} |
||||||
|
|
||||||
|
function formatSeconds(value){ |
||||||
|
if (value == undefined) { |
||||||
|
value = 0; |
||||||
|
} |
||||||
|
let second = parseInt(value); |
||||||
|
let min = 0; |
||||||
|
let secondStr = '' |
||||||
|
let minStr = '' |
||||||
|
let result = '' |
||||||
|
if (second > 60) { |
||||||
|
min = parseInt(String(second / 60)); |
||||||
|
second = parseInt(String(second % 60)); |
||||||
|
if (min > 60) { |
||||||
|
// hour = parseInt(String(min / 60));
|
||||||
|
min = parseInt(String(min % 60)); |
||||||
|
} |
||||||
|
} |
||||||
|
if (min > 0) { |
||||||
|
minStr = addZero(parseInt(String(min))); |
||||||
|
result = minStr + ":"; |
||||||
|
}else{ |
||||||
|
result = "00:"; |
||||||
|
} |
||||||
|
if(second > 0){ |
||||||
|
secondStr = addZero(parseInt(String(second))); |
||||||
|
result = result + secondStr; |
||||||
|
}else{ |
||||||
|
result = result + '00'; |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
function bindEnded(){ |
||||||
|
setIsPlay(false) |
||||||
|
if(!showMenu){ |
||||||
|
setShowMenu(true) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function onFullScreenChange(e){ |
||||||
|
console.log(e.detail.fullScreen) |
||||||
|
if(e.detail.fullScreen){ |
||||||
|
setIsFull(true) |
||||||
|
}else{ |
||||||
|
setIsFull(false) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function play(e){ |
||||||
|
e.stopPropagation(); |
||||||
|
videoContext.current.play() |
||||||
|
setIsPlay(true) |
||||||
|
} |
||||||
|
|
||||||
|
function pause(){ |
||||||
|
setIsPlay(false) |
||||||
|
videoContext.current.pause() |
||||||
|
} |
||||||
|
function sliderOnChange(e){ |
||||||
|
if (duration) { |
||||||
|
// 视频跳转到指定位置
|
||||||
|
videoContext.current.seek(e / 100 * duration); |
||||||
|
updateState.current = true |
||||||
|
setSlidervalue(e) |
||||||
|
} |
||||||
|
} |
||||||
|
function sliderOnChanging(){ |
||||||
|
updateState.current = false |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<View className="container"> |
||||||
|
<Video |
||||||
|
style={{width: '750rpx', height: '600rpx'}} |
||||||
|
id='video' |
||||||
|
// src={brandInfo?.introductory_video_resource?.url}
|
||||||
|
src={src} |
||||||
|
controls={false} |
||||||
|
showPlayBtn={false} |
||||||
|
showCenterPlayBtn={false} |
||||||
|
showProgress={false} |
||||||
|
showFullscreenBtn={false} |
||||||
|
enableProgressGesture={false} |
||||||
|
onTimeUpdate={bindTimeupdateFun} |
||||||
|
onEnded={bindEnded} |
||||||
|
onFullScreenChange={onFullScreenChange} |
||||||
|
> |
||||||
|
<View onTouchStart={onTouchStart} onTouchEnd={onTouchEnd} style={{width:isFull?`${globalData.screenHeight}px`:'750rpx',height:isFull?'750rpx':'600rpx',display:'flex',flexDirection:'column',boxSizing:'border-box',paddingLeft:isFull?`${globalData.statusBarHeight}px`:'0',paddingRight:isFull?`${globalData.statusBarHeight}px`:'0'}}> |
||||||
|
<View onClick={pause} className="justify-center align-center flex pt-5" style={{flex:'1',boxSizing:'border-box'}}> |
||||||
|
{ !isPlay && showMenu && |
||||||
|
<View className="flex justify-center align-center rounded-50 pl-1" style={{width:'50px',height:'50px',backgroundColor:'rgba(0,0,0,0.5)',boxSizing:'border-box'}}> |
||||||
|
<Icon onClick={play} name="play" color="#fff" size="35px"></Icon> |
||||||
|
</View> |
||||||
|
} |
||||||
|
</View> |
||||||
|
<View className="flex align-center px-3" style={{height:'40px',boxSizing:'border-box'}}> |
||||||
|
{ duration && showMenu && |
||||||
|
<> |
||||||
|
{ |
||||||
|
isPlay ? |
||||||
|
<Icon name="pause" color="#fff" size="23px" onClick={() => {videoContext.current.pause();setIsPlay(false)}} /> : |
||||||
|
<Icon name="play" color="#fff" size="23px" onClick={() => {videoContext.current.play();setIsPlay(true)}} /> |
||||||
|
} |
||||||
|
<Text className="text-white pl-1 font-26">{process_duration}</Text> |
||||||
|
<View style={{flex:'1'}}> |
||||||
|
<AtSlider onChange={sliderOnChange} onChanging={sliderOnChanging} step={1} value={sliderValue} activeColor='#fff' backgroundColor='#BDBDBD' blockColor='#fff' blockSize={10}></AtSlider> |
||||||
|
</View> |
||||||
|
<Text onClick={() => { |
||||||
|
isFull?videoContext.current.exitFullScreen():videoContext.current.requestFullScreen({direction:90}) |
||||||
|
}} className="text-white font-26 pr-1">{total_duration}</Text> |
||||||
|
{ |
||||||
|
isFull? <Image style={{width:'25px',height:'25px'}} onClick={() => {videoContext.current.exitFullScreen()}} src={unfull} /> |
||||||
|
: <Image style={{width:'23px',height:'23px'}} src={full} onClick={() => {videoContext.current.requestFullScreen({direction:90})}} /> |
||||||
|
} |
||||||
|
</> |
||||||
|
} |
||||||
|
</View> |
||||||
|
</View> |
||||||
|
</Video> |
||||||
|
</View> |
||||||
|
) |
||||||
|
} |
||||||
|
export default VideoPro |
@ -1,3 +1,5 @@ |
|||||||
export default definePageConfig({ |
export default definePageConfig({ |
||||||
navigationStyle: 'custom', |
navigationStyle: 'custom', |
||||||
|
enableShareTimeline: true, |
||||||
|
enableShareAppMessage: true |
||||||
}) |
}) |
||||||
|
@ -1,3 +1,5 @@ |
|||||||
export default definePageConfig({ |
export default definePageConfig({ |
||||||
navigationStyle: 'custom' |
navigationStyle: 'custom', |
||||||
|
enableShareTimeline: true, |
||||||
|
enableShareAppMessage: true, |
||||||
}) |
}) |
||||||
|
@ -1,4 +1,6 @@ |
|||||||
export default definePageConfig({ |
export default definePageConfig({ |
||||||
navigationBarTitleText: '', |
navigationBarTitleText: '', |
||||||
onReachBottomDistance: 30 |
onReachBottomDistance: 30, |
||||||
|
enableShareTimeline: true, |
||||||
|
enableShareAppMessage: true |
||||||
}) |
}) |
||||||
|
@ -1,3 +1,5 @@ |
|||||||
export default definePageConfig({ |
export default definePageConfig({ |
||||||
navigationStyle: 'custom' |
navigationStyle: 'custom', |
||||||
|
enableShareTimeline: true, |
||||||
|
enableShareAppMessage: true |
||||||
}) |
}) |
||||||
|
Loading…
Reference in new issue