Sticker View: Fix several video emojis causing extreme CPU usage
This commit is contained in:
parent
faec0d1f57
commit
2e3c059333
@ -81,7 +81,8 @@ const StickerView: FC<OwnProps> = ({
|
||||
const {
|
||||
id, isLottie, stickerSetInfo, emoji,
|
||||
} = sticker;
|
||||
const isUnsupportedVideo = sticker.isVideo && !IS_WEBM_SUPPORTED;
|
||||
const [isVideoBroken, markVideoBroken] = useFlag();
|
||||
const isUnsupportedVideo = sticker.isVideo && (!IS_WEBM_SUPPORTED || isVideoBroken);
|
||||
const isVideo = sticker.isVideo && !isUnsupportedVideo;
|
||||
const isStatic = !isLottie && !isVideo;
|
||||
const previewMediaHash = getStickerPreviewHash(sticker.id);
|
||||
@ -184,6 +185,7 @@ const StickerView: FC<OwnProps> = ({
|
||||
isPriority={forceAlways}
|
||||
disablePictureInPicture
|
||||
onReady={markPlayerReady}
|
||||
onBroken={markVideoBroken}
|
||||
onEnded={onVideoEnded}
|
||||
style={filterStyle}
|
||||
/>
|
||||
|
||||
@ -15,6 +15,7 @@ type OwnProps =
|
||||
canPlay: boolean;
|
||||
children?: React.ReactNode;
|
||||
onReady?: NoneToVoidFunction;
|
||||
onBroken?: NoneToVoidFunction;
|
||||
}
|
||||
& VideoProps;
|
||||
|
||||
@ -24,6 +25,7 @@ function OptimizedVideo({
|
||||
canPlay,
|
||||
children,
|
||||
onReady,
|
||||
onBroken,
|
||||
onTimeUpdate,
|
||||
...restProps
|
||||
}: OwnProps) {
|
||||
@ -45,7 +47,7 @@ function OptimizedVideo({
|
||||
});
|
||||
|
||||
// This is only needed for browsers not allowing autoplay
|
||||
const { isBuffered, bufferingHandlers } = useBuffering(true, onTimeUpdate);
|
||||
const { isBuffered, bufferingHandlers } = useBuffering(true, onTimeUpdate, onBroken);
|
||||
const { onPlaying: handlePlayingForBuffering, ...otherBufferingHandlers } = bufferingHandlers;
|
||||
useSyncEffect(([prevIsBuffered]) => {
|
||||
if (prevIsBuffered === undefined) {
|
||||
|
||||
@ -11,13 +11,14 @@ type BufferingEvent = (e: Event | React.SyntheticEvent<HTMLMediaElement>) => voi
|
||||
const MIN_READY_STATE = 3;
|
||||
// Avoid flickering when re-mounting previously buffered video
|
||||
const DEBOUNCE = 200;
|
||||
const MIN_ALLOWED_MEDIA_DURATION = 0.1; // Some video emojis have weird duration of 0.04 causing extreme amount of events
|
||||
|
||||
/**
|
||||
* Time range relative to the duration [0, 1]
|
||||
*/
|
||||
export type BufferedRange = { start: number; end: number };
|
||||
|
||||
const useBuffering = (noInitiallyBuffered = false, onTimeUpdate?: AnyToVoidFunction) => {
|
||||
const useBuffering = (noInitiallyBuffered = false, onTimeUpdate?: AnyToVoidFunction, onBroken?: AnyToVoidFunction) => {
|
||||
const [isBuffered, setIsBuffered] = useState(!noInitiallyBuffered);
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
const [bufferedProgress, setBufferedProgress] = useState(0);
|
||||
@ -28,12 +29,17 @@ const useBuffering = (noInitiallyBuffered = false, onTimeUpdate?: AnyToVoidFunct
|
||||
}, []);
|
||||
|
||||
const handleBuffering = useLastCallback<BufferingEvent>((e) => {
|
||||
const media = e.currentTarget as HTMLMediaElement;
|
||||
|
||||
if (media.duration < MIN_ALLOWED_MEDIA_DURATION) {
|
||||
onBroken?.();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.type === 'timeupdate') {
|
||||
onTimeUpdate?.(e);
|
||||
}
|
||||
|
||||
const media = e.currentTarget as HTMLMediaElement;
|
||||
|
||||
if (!isSafariPatchInProgress(media)) {
|
||||
if (media.buffered.length) {
|
||||
const ranges = getTimeRanges(media.buffered, media.duration);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user