Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
731fab2
fix: FIT-31: Ensure media buffers are syncable events that keep audio…
bmartel May 26, 2025
eb01cba
put all changes behind FF
bmartel May 27, 2025
cd9a9e4
fixing FF usage, aligning buffer styling with all media types, fix co…
bmartel May 27, 2025
55b67f0
tweaking the media buffering animations
bmartel May 27, 2025
c427c49
tweaking the media buffering animations
bmartel May 27, 2025
6184cd5
update Audio loader and error colors to use design tokens
bmartel May 27, 2025
e437ef4
debounce updates to smooth out the handling of buffering
bmartel May 27, 2025
bcc319f
Merge remote-tracking branch 'origin/develop' into fb-fit-31
bmartel May 27, 2025
a9b22e5
Sync Follow Merge dependencies
bmartel May 28, 2025
502df27
Merge branch 'develop' into 'fb-fit-31'
bmartel May 28, 2025
0719edd
video should not progress until buffering is over
bmartel May 29, 2025
9f431b8
Merge remote-tracking branch 'origin/develop' into fb-fit-31
bmartel May 29, 2025
5d7d248
use synced buffering
bmartel May 30, 2025
2f3ba48
don't over report buffering, only report when all buffering elements …
bmartel May 30, 2025
7756fbf
Merge remote-tracking branch 'origin/develop' into fb-fit-31
bmartel May 30, 2025
50a7d02
cleanup and waveform buffer sync to player instance
bmartel May 30, 2025
c7e3fd5
fix syncing A/V + Paragraphs
bmartel May 30, 2025
a06a9c4
don't allow video to seek while buffering it causes a loop
bmartel May 30, 2025
0987411
linting
bmartel May 30, 2025
4c47690
debounce the audio player buffering updates so it does not preemptive…
bmartel May 30, 2025
a193b81
linting
bmartel May 30, 2025
0800f74
ff all the audio synced buffering changes
bmartel May 30, 2025
69f0855
linting
bmartel May 30, 2025
b4972a6
Apply suggestions from code review
bmartel May 30, 2025
046fd93
linting
bmartel May 30, 2025
5b2f918
Merge remote-tracking branch 'origin/develop' into fb-fit-31
bmartel May 30, 2025
f2a0631
improve animation of buffering loader
bmartel May 30, 2025
174a8c4
Merge branch 'develop' into fb-fit-31
bmartel May 30, 2025
5b0bb84
fix: replace buffering hook with unified syncable mixin logic
Gondragos Jun 30, 2025
8c2be3d
Merge branch 'develop' into fb-fit-31
Gondragos Jun 30, 2025
b05d74f
Lint fixes
Gondragos Jun 30, 2025
fc558d7
fix: improve buffering logic and syncing
Gondragos Jul 2, 2025
c023215
fix: add paragraphs buffering logic
Gondragos Jul 2, 2025
6dacf0e
fix: re-enable flaky visibility toggle test
Gondragos Jul 2, 2025
c2bc4c9
fix: unify buffering logic with reusable hook
Gondragos Jul 3, 2025
cf7137a
fix: update sync pause handling in paragraphs
Gondragos Jul 3, 2025
d60c6e3
Linting
Gondragos Jul 3, 2025
5caefe8
fix: handle unhandled promise rejections in play/pause
Gondragos Jul 6, 2025
b0bbb68
Merge branch 'develop' into fb-fit-31
Gondragos Jul 7, 2025
9c94e4a
fix: Apply isSyncedBuffering flag and refactoring
Gondragos Jul 7, 2025
cd22358
fix: update isBuffering logic with flag check
Gondragos Jul 7, 2025
1aaf9fa
Merge branch 'refs/heads/develop' into fb-fit-31
Gondragos Jul 7, 2025
337cba7
test: Add tests and helpers
Gondragos Jul 9, 2025
dade7c2
Tests based small fixes
Gondragos Jul 9, 2025
7844f9f
Cleaning
Gondragos Jul 9, 2025
685bc1c
Merge branch 'refs/heads/develop' into fb-fit-31
Gondragos Jul 9, 2025
f9eb5a9
fix: Fix applying ff
Gondragos Jul 9, 2025
c20797e
Merge branch 'develop' into fb-fit-31
Gondragos Jul 9, 2025
66d5ba3
test: Switch on buffering ff in all tests
Gondragos Jul 9, 2025
435f619
test: Add buffering playback sync tests
Gondragos Jul 14, 2025
b58b9d2
fix: Update media syncing during buffering
Gondragos Jul 14, 2025
6d736db
Fix tests
Gondragos Jul 14, 2025
a12cb8d
fix: Handle browser closure errors in error collector
Gondragos Jul 14, 2025
d5fb34b
Merge branch 'develop' into 'fb-fit-31'
Gondragos Jul 14, 2025
999ac2b
Fix phrases playing display, optimize rendering, increase stability
Gondragos Jul 17, 2025
c57f9a0
fix: Simplify draw handling in Visualizer
Gondragos Jul 24, 2025
e2e5a96
Merge branch 'develop' into fb-fit-31
Gondragos Jul 29, 2025
8f6015e
Accept suggestions
Jul 29, 2025
edf1d9f
ci: Build tag docs
robot-ci-heartex Jul 29, 2025
05ec5bf
Merge branch 'develop' into fb-fit-31
Gondragos Aug 1, 2025
0269740
Merge branch 'develop' into fb-fit-31
Gondragos Aug 4, 2025
27f8cdb
Merge branch 'develop' into 'fb-fit-31'
niklub Aug 5, 2025
7903945
Merge branch 'develop' into fb-fit-31
Aug 5, 2025
635c635
Merge branch 'develop' into 'fb-fit-31'
niklub Aug 10, 2025
5bd4d35
Merge branch 'develop' into 'fb-fit-31'
niklub Aug 11, 2025
e66999b
Merge branch 'develop' into 'fb-fit-31'
niklub Aug 14, 2025
6ee9f51
Merge branch 'develop' into 'fb-fit-31'
Gondragos Aug 18, 2025
8321855
fix: Make Sync buffering playback test more stable
Gondragos Aug 18, 2025
3ff1760
Fix types
Gondragos Aug 18, 2025
3dfdc6b
Fix pausing before load
Gondragos Aug 18, 2025
53e5a72
Merge branch 'develop' into 'fb-fit-31'
Gondragos Aug 18, 2025
4a4ed26
Fix auto merge consequences
Gondragos Aug 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions web/libs/core/src/hooks/useRefCallback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { useValueRef } from "@humansignal/core/hooks/useValueRef";
import { useCallback } from "react";

export function useRefCallback<T extends (...args: any[]) => any>(callback: T) {
const ref = useValueRef<T>(callback);

return useCallback((...args: Parameters<T>): ReturnType<T> => {
return ref.current(...args);
}, []);
}
7 changes: 7 additions & 0 deletions web/libs/core/src/hooks/useValueRef.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useRef } from "react";

export function useValueRef<T>(value: T) {
const ref = useRef<T>(value);
ref.current = value;
return ref;
}
5 changes: 5 additions & 0 deletions web/libs/core/src/lib/utils/feature-flags/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ export const FF_ADJUSTABLE_SPANS = "fflag_feat_front_leap_1973_adjustable_spans_
*/
export const FF_THEME_TOGGLE = "fflag_feat_front_optic_1217_theme_toggle_short";

/**
* Fixes synced audio/video buffering
*/
export const FF_SYNCED_BUFFERING = "fflag_fix_front_fit_31_synced_media_buffering";

/**
* Enables the summary view for annotations
*/
Expand Down
2 changes: 1 addition & 1 deletion web/libs/core/src/lib/utils/schema/tags.json
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@
},
"Video": {
"name": "Video",
"description": "Video tag plays a simple video file. Use for video annotation tasks such as classification and transcription.\n\nUse with the following data types: video\n\n### Video format\n\nLabel Studio relies on your web browser to play videos and evaluate the total frame number. So, it's essential that your videos use a format and codecs that are universally supported. To ensure maximum compatibility, we recommend using an MP4 container with video encoded using the H.264 (AVC) codec and audio encoded with AAC. This combination is widely supported across all modern browsers and minimizes issues like incorrect total duration detection or problems with playback. In addition, it's important to convert your videos to a constant frame rate (CFR), ideally around 30 fps, to avoid discrepancies in frame counts and issues with duplicated or missing frames. All audio and video streams from your file must have the same durations; otherwise, you will have extra total frames.\n\nConverting your videos to this recommended format will help ensure that they play smoothly in Label Studio and that the frame rate and duration are correctly recognized for accurate annotations. To convert any video to this format, you can use FFmpeg. For example, the following commands convert an input video to MP4 with H.264 video, AAC audio, and a constant frame rate of 30 fps:\n\n```bash\n# Extract the exact video stream duration in seconds\nDUR=$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=nokey=1:noprint_wrappers=1 input.mp4)\n# Re-encode media file to recommended format\nffmpeg -i input_video.mp4 -c:v libx264 -profile:v high -level 4.0 -pix_fmt yuv420p -r 30 -c:a aac -b:a 128k -to $DUR output_video.mp4\n```\n\nIn this command:\n- `-i input_video.mp4` specifies your source video.\n- `-c:v libx264` uses the H.264 codec for video encoding.\n- `-profile:v high -level 4.0` sets compatibility parameters for a broad range of devices.\n- `-pix_fmt yuv420p` ensures the pixel format is compatible with most browsers.\n- `-r 30` forces a constant frame rate of 30 fps. You can also omit the -r option, ffmpeg will save your current frame rate. This is fine if you are 100% certain that your video has a constant frame rate.\n- `-c:a aac -b:a 128k` encodes the audio in AAC at 128 kbps.\n- `-to` stops writing output as soon as the container clock hits your video’s end timestamp, so any extra audio tail is automatically dropped.\n- `output_video.mp4` is the converted video file ready for use in Label Studio.\n\nUsing this FFmpeg command to re-encode your videos will help eliminate playback issues and ensure that Label Studio detects the total video duration accurately, providing a smooth annotation experience.\n\nIt is a good idea to check all parameters of your video using this command:\n```bash\nffprobe -v error -show_format -show_streams -print_format json input.mp4\n```",
"description": "Video tag plays a simple video file. Use for video annotation tasks such as classification and transcription.\n\nUse with the following data types: video\n\n### Video format\n\nLabel Studio relies on your web browser to play videos and evaluate the total frame number. So, it's essential that your videos use a format and codecs that are universally supported. To ensure maximum compatibility, we recommend using an MP4 container with video encoded using the H.264 (AVC) codec and audio encoded with AAC. This combination is widely supported across all modern browsers and minimizes issues like incorrect total duration detection or problems with playback. In addition, it's important to convert your videos to a constant frame rate (CFR), ideally around 30 fps, to avoid discrepancies in frame counts and issues with duplicated or missing frames. All audio and video streams from your file must have the same durations; otherwise, you will have extra total frames.\n\nConverting your videos to this recommended format will help ensure that they play smoothly in Label Studio and that the frame rate and duration are correctly recognized for accurate annotations. To convert any video to this format, you can use FFmpeg. For example, the following commands convert an input video to MP4 with H.264 video, AAC audio, and a constant frame rate of 30 fps:\n\n```bash\n# Extract the exact video stream duration in seconds\nDUR=$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=nokey=1:noprint_wrappers=1 input.mp4)\n# Re-encode media file to recommended format\nffmpeg -i input_video.mp4 -c:v libx264 -profile:v high -level 4.0 -pix_fmt yuv420p -r 30 -c:a aac -b:a 128k -to $DUR output_video.mp4\n```\n\nIn this command:\n- `-i input_video.mp4` specifies your source video.\n- `-c:v libx264` uses the H.264 codec for video encoding.\n- `-profile:v high -level 4.0` sets compatibility parameters for a broad range of devices.\n- `-pix_fmt yuv420p` ensures the pixel format is compatible with most browsers.\n- `-r 30` forces a constant frame rate of 30 fps. You can also omit the -r option, ffmpeg will save your current frame rate. This is fine if you are 100% certain that your video has a constant frame rate.\n- `-c:a aac -b:a 128k` encodes the audio in AAC at 128 kbps.\n- `-to` stops writing output as soon as the container clock hits your video's end timestamp, so any extra audio tail is automatically dropped.\n- `output_video.mp4` is the converted video file ready for use in Label Studio.\n\nUsing this FFmpeg command to re-encode your videos will help eliminate playback issues and ensure that Label Studio detects the total video duration accurately, providing a smooth annotation experience.\n\nIt is a good idea to check all parameters of your video using this command:\n```bash\nffprobe -v error -show_format -show_streams -print_format json input.mp4\n```",
"attrs": {
"name": {
"name": "name",
Expand Down
35 changes: 34 additions & 1 deletion web/libs/editor/src/components/Timeline/Controls.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
.timeline-controls {
position: relative;
background: var(--color-neutral-background-bold);
padding: 4px;

&__buffering {
left: 0;
right: 0;
top: 0;
height: 4px;
position: absolute;
background-color: var(--color-primary-content);
overflow: hidden;

&::after {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 25%;
height: 100%;
will-change: left;
background-color: var(--color-primary-content-subtle);
animation: buffering-media 800ms ease-out infinite;
}
}

&__counter {
height: 36px;
min-width: 115px;
Expand Down Expand Up @@ -86,7 +109,7 @@
}
}

& + & {
&+& {
border-left: 1px solid var(--color-neutral-border);
}
}
Expand All @@ -111,3 +134,13 @@
background: var(--color-neutral-surface);
}
}

@keyframes buffering-media {
0% {
left: -100%;
}

100% {
left: 100%;
}
}
2 changes: 2 additions & 0 deletions web/libs/editor/src/components/Timeline/Controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const Controls: FC<TimelineControlsProps> = memo(
position,
frameRate = 1024,
playing,
buffering = false,
collapsed,
duration,
extraControls,
Expand Down Expand Up @@ -174,6 +175,7 @@ export const Controls: FC<TimelineControlsProps> = memo(

return (
<Block name="timeline-controls" tag={Space} spread style={{ gridAutoColumns: "auto" }}>
{buffering && <Elem name="buffering" aria-label="Buffering Media Source" />}
{mediaType === "audio" ? (
renderControls()
) : (
Expand Down
4 changes: 1 addition & 3 deletions web/libs/editor/src/components/Timeline/Timeline.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
background-color: var(--color-neutral-background);

&__topbar {
padding-bottom: var(--spacing-tight);
min-height: 48px;
padding: 6px;
display: grid;
grid-row-gap: 8px;
align-items: center;
grid-auto-rows: min-content;
grid-template-rows: 1fr;
border-top: 1px solid var(--color-neutral-border);
border-bottom: 1px solid var(--color-neutral-border);
}
}

Expand Down
2 changes: 2 additions & 0 deletions web/libs/editor/src/components/Timeline/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const TimelineComponent: FC<TimelineProps> = ({
altHopSize = 1,
hopSize = altHopSize,
playing = false,
buffering = false,
fullscreen = false,
disableView = false,
defaultStepSize = 10,
Expand Down Expand Up @@ -129,6 +130,7 @@ const TimelineComponent: FC<TimelineProps> = ({
position={currentPosition}
frameRate={framerate}
playing={playing}
buffering={buffering}
volume={props.volume}
controls={props.controls}
altHopSize={altHopSize}
Expand Down
2 changes: 2 additions & 0 deletions web/libs/editor/src/components/Timeline/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface TimelineProps<D extends ViewTypes = "frames"> {
mode: D;
framerate: number;
playing: boolean;
buffering?: boolean;
zoom?: number;
volume?: number;
speed?: number;
Expand Down Expand Up @@ -184,6 +185,7 @@ export interface TimelineControlsProps {
playing: boolean;
collapsed: boolean;
fullscreen: boolean;
buffering?: boolean;
volume?: number;
speed?: number;
zoom?: number;
Expand Down
4 changes: 2 additions & 2 deletions web/libs/editor/src/components/VideoCanvas/VideoCanvas.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
padding: 2px 7px;
text-align: center;
background-color: var(--color-neutral-background);
background-image: repeating-linear-gradient(90deg, var(--grape_500) 0, var(--grape_400) 120px, var(--grape_500) 240px);
background-image: repeating-linear-gradient(90deg, var(--color-primary-content) 0, var(--color-primary-content-subtle) 120px, var(--color-primary-content) 240px);
animation: buffering 1.2s linear infinite;
}
}
Expand Down Expand Up @@ -72,4 +72,4 @@
100% {
background-position: 240px 0;
}
}
}
Loading
Loading