index.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { Image, Video, VideoProps, ImageProps, View } from "@tarojs/components";
  2. import { useEffect, useRef } from "react";
  3. import Taro from "@tarojs/taro";
  4. import { DEFAULT_AVATAR } from '@/config'
  5. import { addOssProcessLowQualityParam } from '@/utils'
  6. interface Props {
  7. source?: string;
  8. className: string;
  9. mode?: keyof ImageProps.Mode | undefined
  10. roundedFull?: boolean
  11. }
  12. export const AvatarMedia = ({ source, className, roundedFull = true, mode = 'widthFix' }: Props) => {
  13. const videoRef = useRef<React.ComponentType<VideoProps>|null>(null);
  14. const videoContext = useRef<Taro.VideoContext|null>(null);
  15. const videoId = useRef(`video-${Math.random().toString(36).substr(2, 9)}`);
  16. const videoErrorCallback = (e) => {
  17. console.log('Video error info:')
  18. console.log(e.detail)
  19. }
  20. // 处理 ios 上无法循环播放的 bug
  21. const handleOnEnded = () => {
  22. if(videoContext.current){
  23. videoContext.current.seek(0)
  24. videoContext.current.play()
  25. }
  26. }
  27. useEffect(() => {
  28. if (videoRef.current) {
  29. videoContext.current = Taro.createVideoContext(videoId.current, this);
  30. }
  31. }, []);
  32. // 以 .mp4 结尾则认为是 视频
  33. if (source && source.slice(-4) === '.mp4') {
  34. return (
  35. <Video
  36. id={videoId.current}
  37. ref={videoRef}
  38. controls={false}
  39. showCenterPlayBtn={false}
  40. loop={true}
  41. muted={true}
  42. autoplay
  43. onEnded={handleOnEnded}
  44. objectFit="cover"
  45. className={`overflow-hidden shrink-0 ${roundedFull ? 'rounded-full': ''} ${className}`}
  46. onError={videoErrorCallback}
  47. // src="https://cdn.wehome.cn/cmn/mp4/3/META-H8UKWHWU-YAUTZH7ECGRDC57FD3NI3-CUGVCS8M-CD.mp4"
  48. src={source}
  49. />
  50. );
  51. }
  52. const _source = source?.length ? `${addOssProcessLowQualityParam(source)}` : DEFAULT_AVATAR
  53. return (
  54. <View className={`overflow-hidden shrink-0 ${roundedFull ? 'rounded-full': ''} ${className}`}>
  55. <Image
  56. mode={mode}
  57. className={`${className}`}
  58. src={_source}
  59. lazyLoad
  60. />
  61. </View>
  62. );
  63. };