Skip to content

Commit 8f33aae

Browse files
authored
Merge pull request #1776 from internxt/fix/progress-bar-while-loading-video-stream
[_]: fix/progress bar while loading video stream
2 parents eb63d07 + 140ab9d commit 8f33aae

File tree

5 files changed

+44
-16
lines changed

5 files changed

+44
-16
lines changed

public/video-streaming.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const MESSAGE_TYPES = {
1313
CLEAR_SESSIONS: 'CLEAR_SESSIONS',
1414
};
1515
const DEFAULT_CHUNK_SIZE = 5 * 1024 * 1024;
16-
const CHUNK_REQUEST_TIMEOUT = 2 * 60 * 1000; // 2 minutes for slow connections
16+
const CHUNK_REQUEST_TIMEOUT = 10000;
1717

1818
/**
1919
* Waiting until the Service Worker is installed

src/app/drive/components/FileViewer/FileViewer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ const FileViewer = ({
100100
const isLastItemOrShareView = (totalFolderIndex && fileIndex === totalFolderIndex - 1) || isShareView;
101101
const isItemValidToPreview = isTypeAllowed && isPreviewAvailable;
102102
const isVideo = fileExtensionGroup === FileExtensionGroup['Video'];
103-
const isVideoStreaming = isVideo && !disableVideoStream;
103+
const isSafari = navigator.userAgent.includes('Safari') && !navigator.userAgent.includes('Chrome');
104+
const isVideoStreaming = isVideo && !disableVideoStream && (!isSafari || isFileSizePreviewable(file.size));
104105

105106
const shouldRenderThePreview = isTypeAllowed && (isVideoStreaming || isFileSizePreviewable(file.size));
106107

src/app/drive/components/FileViewer/viewers/FileVideoViewer/FileVideoViewer.tsx

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { localStorageService } from 'services';
33
import { VideoStreamingSession } from 'app/drive/services/video-streaming.service/VideoStreamingSession';
44
import { FormatFileViewerProps } from '../../FileViewer';
55

6+
const PROGRESS_INCREMENT = 0.2;
7+
const PROGRESS_INTERVAL_MS = 500;
8+
const MAX_SIMULATED_PROGRESS = 0.95;
9+
610
const FileVideoViewer = ({
711
file,
812
blob,
@@ -12,9 +16,42 @@ const FileVideoViewer = ({
1216
}: FormatFileViewerProps): JSX.Element => {
1317
const videoRef = useRef<HTMLVideoElement>(null);
1418
const sessionRef = useRef<VideoStreamingSession | null>(null);
19+
const progressIntervalRef = useRef<NodeJS.Timeout | null>(null);
1520
const [canPlay, setCanPlay] = useState(false);
21+
const [simulatedProgress, setSimulatedProgress] = useState(0);
22+
23+
useEffect(() => {
24+
if (disableVideoStream || canPlay) return;
25+
26+
progressIntervalRef.current = setInterval(() => {
27+
setSimulatedProgress((prev) => {
28+
const next = prev + PROGRESS_INCREMENT;
29+
if (next >= MAX_SIMULATED_PROGRESS) {
30+
if (progressIntervalRef.current) {
31+
clearInterval(progressIntervalRef.current);
32+
progressIntervalRef.current = null;
33+
}
34+
return MAX_SIMULATED_PROGRESS;
35+
}
36+
return next;
37+
});
38+
}, PROGRESS_INTERVAL_MS);
39+
40+
return () => {
41+
if (progressIntervalRef.current) {
42+
clearInterval(progressIntervalRef.current);
43+
progressIntervalRef.current = null;
44+
}
45+
};
46+
}, [disableVideoStream, canPlay]);
47+
48+
useEffect(() => {
49+
if (!disableVideoStream && !canPlay && simulatedProgress > 0) {
50+
handlersForSpecialItems?.handleUpdateProgress(simulatedProgress);
51+
}
52+
}, [simulatedProgress, canPlay, disableVideoStream, handlersForSpecialItems]);
1653

17-
// Handle shared items (blob-based playback)
54+
// Handle shared items
1855
useEffect(() => {
1956
if (!disableVideoStream || !videoRef.current || !blob) return;
2057

@@ -27,7 +64,7 @@ const FileVideoViewer = ({
2764
};
2865
}, [disableVideoStream, blob]);
2966

30-
// Handle streaming playback (non-shared items)
67+
// Handle streaming playback
3168
useEffect(() => {
3269
if (disableVideoStream) return;
3370

@@ -50,9 +87,6 @@ const FileVideoViewer = ({
5087
credentials: file.credentials
5188
? { user: file.credentials?.user, pass: file.credentials?.pass }
5289
: { user: bridgeUser, pass: userId },
53-
onProgress: (progress) => {
54-
handlersForSpecialItems?.handleUpdateProgress(progress);
55-
},
5690
});
5791

5892
sessionRef.current = session;
@@ -118,6 +152,7 @@ const FileVideoViewer = ({
118152
ref={videoRef}
119153
controls
120154
autoPlay
155+
preload="metadata"
121156
style={{ width: '100%', maxHeight: '80vh', backgroundColor: '#000' }}
122157
className={canPlay ? 'flex' : 'hidden'}
123158
>

src/app/drive/services/video-streaming.service/VideoStreamingSession.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ const createMockConfig = (overrides?: Partial<VideoStreamingSessionConfig>): Vid
2727
fileType: 'mp4',
2828
mnemonic: 'test-mnemonic',
2929
credentials: { user: 'test-user', pass: 'test-pass' },
30-
onProgress: vi.fn(),
3130
...overrides,
3231
});
3332

src/app/drive/services/video-streaming.service/VideoStreamingSession.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export interface VideoStreamingSessionConfig {
1313
user: string;
1414
pass: string;
1515
};
16-
onProgress?: (progress: number) => void;
1716
}
1817

1918
const CACHE_SIZE_LIMIT = 20;
@@ -116,13 +115,7 @@ export class VideoStreamingSession {
116115
},
117116
});
118117

119-
const result = await binaryStreamToUint8Array(stream, (bytes) => {
120-
const progress = bytes / (end - start);
121-
if (this.chunkCache.size === 0 && this.config.onProgress) {
122-
const currentProgress = progress >= 1 ? 0.95 : progress;
123-
this.config.onProgress(currentProgress);
124-
}
125-
});
118+
const result = await binaryStreamToUint8Array(stream);
126119

127120
if (this.isDestroyed) {
128121
throw new Error('Session destroyed during download');

0 commit comments

Comments
 (0)