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