83 lines
2.1 KiB
TypeScript
83 lines
2.1 KiB
TypeScript
import { Image } from 'expo-image'
|
|
import { memo, useEffect, useMemo, useState } from 'react'
|
|
import { ViewStyle } from 'react-native'
|
|
import Video from 'react-native-video'
|
|
|
|
type Props = {
|
|
url?: string
|
|
poster?: string
|
|
style?: ViewStyle
|
|
width?: number
|
|
} & React.ComponentProps<typeof Video>
|
|
|
|
const VideoBox = ({ url, poster, width = 120, style, ...videoProps }: Props) => {
|
|
const [urlFinal, setUrlFinal] = useState('')
|
|
|
|
const createUrl = (url: string) => {
|
|
return `https://modal-dev.bowong.cc/api/custom/video/converter/${encodeURI(url)}?options=compression_level=3,quality=70,loop=true,resolution=${width}x${width},fps=24`
|
|
}
|
|
|
|
const isImg = (url: any) => {
|
|
if (!url) return false
|
|
const lowerUrl = url.toLowerCase()
|
|
return lowerUrl?.match(/\.(jpg|jpeg|png|gif|webp|bmp|tiff|svg)(\?.*)?$/i)
|
|
}
|
|
|
|
async function resolveRedirect(url: string) {
|
|
const res = await fetch(url, {
|
|
method: 'GET',
|
|
headers: {
|
|
Range: 'bytes=0-0',
|
|
},
|
|
})
|
|
return res.url
|
|
}
|
|
|
|
const setRedirectUrl = async (url?: string) => {
|
|
const isImg2 = isImg(url)
|
|
if (isImg2) {
|
|
setUrlFinal(url!)
|
|
return
|
|
}
|
|
|
|
const webpUrl = createUrl(url!)
|
|
const finalUrl = await resolveRedirect(webpUrl)
|
|
// console.log('finalUrl-----------', finalUrl)
|
|
setUrlFinal(finalUrl!)
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (!url) return
|
|
setRedirectUrl(url!)
|
|
// const finalUrl = createUrl(url)
|
|
// console.log('finalUrl-----------', finalUrl)
|
|
|
|
// setUrlFinal(finalUrl)
|
|
return
|
|
}, [url])
|
|
|
|
// console.log('urlFinal--------- ', urlFinal, url)
|
|
|
|
if (!url) return null
|
|
return (
|
|
// 当 url 变化时通过 key 强制重载,确保自动播放生效
|
|
// <Video
|
|
// key={url ?? 'no-url'}
|
|
// source={{ uri: url }}
|
|
// poster={poster}
|
|
// repeat
|
|
// viewType={0}
|
|
// controls={false}
|
|
// resizeMode="cover"
|
|
// volume={0}
|
|
// muted
|
|
// paused={paused}
|
|
// style={style as any}
|
|
// {...videoProps}
|
|
// />
|
|
<Image key={urlFinal} cachePolicy="memory-disk" source={{ uri: urlFinal }} style={style as any} />
|
|
)
|
|
}
|
|
|
|
export default memo(VideoBox)
|