├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── compositions ├── daily-baseline │ ├── .eslintrc.json │ ├── components │ │ ├── Banner.js │ │ ├── CustomOverlay.js │ │ ├── CustomOverlay_bounce.js │ │ ├── EmojiReactions.js │ │ ├── HighlightRowText.js │ │ ├── ImageOverlay.js │ │ ├── ParticipantLabelPipStyle.js │ │ ├── PausedPlaceholder.js │ │ ├── RoomDebug.js │ │ ├── Sidebar.js │ │ ├── Slate.js │ │ ├── TextOverlay.js │ │ ├── Toast.js │ │ ├── VideoDominant.js │ │ ├── VideoGrid.js │ │ ├── VideoPip.js │ │ ├── VideoSingle.js │ │ ├── VideoSplit.js │ │ ├── WebFrameOverlay.js │ │ ├── overrides │ │ │ ├── decorateVideoDominantItem.js │ │ │ ├── decorateVideoGridItem.js │ │ │ ├── decorateVideoPipItem.js │ │ │ ├── decorateVideoSingleItem.js │ │ │ └── decorateVideoSplitItem.js │ │ └── useFade.js │ ├── constants.js │ ├── images │ │ ├── overlay.png │ │ ├── overlay.png.json │ │ ├── party-popper_1f389.png │ │ ├── party-popper_1f389.png.json │ │ ├── user_white_64.png │ │ └── user_white_64.png.json │ ├── index.jsx │ ├── layouts.js │ ├── params.js │ ├── participants.js │ ├── preferred-video-ids.js │ └── preloads.js ├── daily-roomdebug │ ├── constants.js │ ├── index.jsx │ └── layouts.js └── daily-rundown │ ├── components │ ├── HostGuestVideo.js │ ├── LogoSidebar.js │ ├── ParticipantLabel.js │ ├── PollResult.js │ ├── RundownSidebar.js │ └── VideoContainer.js │ ├── images │ ├── header.png │ ├── header.png.json │ ├── logo.png │ └── logo.png.json │ ├── index.jsx │ ├── layouts.js │ ├── params.js │ └── preloads.js ├── cut-transcript-tools ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── README.md ├── gen-cut-from-raw-tracks.js ├── gen-cut-from-single-video-text-extracts.js ├── gen-transcript.js ├── gui │ └── transcript-extract.html ├── package-lock.json ├── package.json ├── prepare-raw-tracks-for-cut.zx.mjs ├── vcscut-render.zx.mjs └── visual-template-plugins │ └── social-interview.js ├── js ├── .gitignore ├── .yarnrc.yml ├── README.md ├── comp-namespace-util.js ├── devrig │ ├── example-assets │ │ ├── atari_vcs_woodgrain_texture.png │ │ ├── demoperson_missfury.png │ │ ├── demoperson_missfury_square.png │ │ ├── demoperson_moongirl.png │ │ ├── demoperson_moongirl_square.png │ │ ├── demoperson_yellowkid.png │ │ ├── screenshare_standin2_1600x1000.png │ │ ├── screenshare_standin_1600x900.png │ │ ├── test_square_320px.png │ │ └── user_white_64.png │ ├── ui-assets │ │ ├── checkboxOff.png │ │ ├── checkboxOn.png │ │ └── randomize.png │ └── vcs-rig.html ├── example │ ├── batch │ │ └── baseline1.json │ ├── graphics-test.jsx │ ├── hello.jsx │ ├── stretchbox.jsx │ └── webvtt │ │ └── transcript1.vtt ├── lib-browser │ ├── font-loader.js │ └── vcs-browser.js ├── lib-node │ ├── batch-util.js │ ├── font-loader.js │ ├── jsx-builder.js │ └── log.js ├── package.json ├── src │ ├── .eslintrc.json │ ├── comp-backing-model.js │ ├── index.js │ ├── loader-base.js │ ├── react-reconciler.js │ ├── react │ │ ├── components │ │ │ ├── Box.js │ │ │ ├── Emoji.js │ │ │ ├── Image.js │ │ │ ├── Text.js │ │ │ ├── Video.js │ │ │ ├── WebFrame.js │ │ │ └── index.js │ │ ├── contexts │ │ │ ├── CompositionDataContext.js │ │ │ ├── MediaInputContext.js │ │ │ ├── RoomContext.js │ │ │ ├── TimeContext.js │ │ │ └── index.js │ │ └── hooks │ │ │ ├── compositionData.js │ │ │ ├── index.js │ │ │ ├── mediaInput.js │ │ │ ├── room.js │ │ │ └── time.js │ ├── render │ │ ├── canvas-display-list.js │ │ ├── canvas-utils.js │ │ ├── canvas.js │ │ ├── video-dom.js │ │ └── video-scenedesc.js │ ├── stdlib │ │ ├── components │ │ │ ├── debug │ │ │ │ ├── MediaInputPrintout.js │ │ │ │ └── RoomPrintout.js │ │ │ └── index.js │ │ └── layouts │ │ │ ├── grid.js │ │ │ ├── index.js │ │ │ ├── split.js │ │ │ └── transform.js │ └── text │ │ ├── attributed-string.js │ │ ├── emoji.js │ │ ├── font-setup.js │ │ ├── font.js │ │ ├── standard-fonts.js │ │ └── text-layout.js ├── swc.config.json ├── vcs-batch-runner.js ├── vcs-test-runner.js ├── webpack.config.js └── yarn.lock ├── package.json ├── res ├── fonts │ ├── Anton-Regular.ttf │ ├── Bangers-Regular.ttf │ ├── Bitter-Black.ttf │ ├── Bitter-BlackItalic.ttf │ ├── Bitter-Bold.ttf │ ├── Bitter-BoldItalic.ttf │ ├── Bitter-Italic.ttf │ ├── Bitter-Light.ttf │ ├── Bitter-LightItalic.ttf │ ├── Bitter-Medium.ttf │ ├── Bitter-MediumItalic.ttf │ ├── Bitter-Regular.ttf │ ├── Bitter-Thin.ttf │ ├── Bitter-ThinItalic.ttf │ ├── DMSans-Black.ttf │ ├── DMSans-BlackItalic.ttf │ ├── DMSans-Bold.ttf │ ├── DMSans-BoldItalic.ttf │ ├── DMSans-ExtraBold.ttf │ ├── DMSans-ExtraBoldItalic.ttf │ ├── DMSans-ExtraLight.ttf │ ├── DMSans-ExtraLightItalic.ttf │ ├── DMSans-Italic.ttf │ ├── DMSans-Light.ttf │ ├── DMSans-LightItalic.ttf │ ├── DMSans-Medium.ttf │ ├── DMSans-MediumItalic.ttf │ ├── DMSans-Regular.ttf │ ├── DMSans-SemiBold.ttf │ ├── DMSans-SemiBoldItalic.ttf │ ├── DMSans-Thin.ttf │ ├── DMSans-ThinItalic.ttf │ ├── Exo-Black.ttf │ ├── Exo-BlackItalic.ttf │ ├── Exo-Bold.ttf │ ├── Exo-BoldItalic.ttf │ ├── Exo-Italic.ttf │ ├── Exo-Light.ttf │ ├── Exo-LightItalic.ttf │ ├── Exo-Medium.ttf │ ├── Exo-MediumItalic.ttf │ ├── Exo-Regular.ttf │ ├── Exo-Thin.ttf │ ├── Exo-ThinItalic.ttf │ ├── Magra-Bold.ttf │ ├── Magra-Regular.ttf │ ├── NotoColorEmoji-Regular.ttf │ ├── PermanentMarker-Regular.ttf │ ├── Roboto-Black.ttf │ ├── Roboto-BlackItalic.ttf │ ├── Roboto-Bold.ttf │ ├── Roboto-BoldItalic.ttf │ ├── Roboto-Italic.ttf │ ├── Roboto-Light.ttf │ ├── Roboto-LightItalic.ttf │ ├── Roboto-Medium.ttf │ ├── Roboto-MediumItalic.ttf │ ├── Roboto-Regular.ttf │ ├── Roboto-Thin.ttf │ ├── Roboto-ThinItalic.ttf │ ├── RobotoCondensed-Bold.ttf │ ├── RobotoCondensed-BoldItalic.ttf │ ├── RobotoCondensed-Italic.ttf │ ├── RobotoCondensed-Light.ttf │ ├── RobotoCondensed-LightItalic.ttf │ ├── RobotoCondensed-Medium.ttf │ ├── RobotoCondensed-MediumItalic.ttf │ ├── RobotoCondensed-Regular.ttf │ ├── SuezOne-Regular.ttf │ ├── Teko-Bold.ttf │ ├── Teko-Light.ttf │ ├── Teko-Medium.ttf │ ├── Teko-Regular.ttf │ └── Teko-SemiBold.ttf └── test-assets │ ├── daily-logo-primary-darkground.png │ ├── daily-logo-primary-darkground.png.json │ ├── daily-logo-small-lightground.png │ ├── daily-logo-small-lightground.png.json │ ├── landscape-j3CjZYckM88-unsplash.json │ ├── landscape-j3CjZYckM88-unsplash.png │ ├── raised-hand_270b.png │ ├── raised-hand_270b.png.json │ ├── test_square_320px.png │ ├── test_square_320px.png.json │ ├── user_white_64.png │ └── user_white_64.png.json └── server-render ├── canvex ├── .gitignore ├── .vscode │ ├── c_cpp_properties.json │ ├── settings.json │ └── tasks.json ├── example-data │ ├── background-clip.json │ ├── basic-labels.json │ ├── basic-lowerthird.json │ ├── graphics-test-random-50.json │ ├── rounded-sidebar.json │ └── rundown.json ├── include │ └── canvex_c_api.h ├── init_build_linux.sh ├── meson.build ├── meson_linux.ini ├── rapidjson │ ├── allocators.h │ ├── cursorstreamwrapper.h │ ├── document.h │ ├── encodedstream.h │ ├── encodings.h │ ├── error │ │ ├── en.h │ │ └── error.h │ ├── filereadstream.h │ ├── filewritestream.h │ ├── fwd.h │ ├── internal │ │ ├── biginteger.h │ │ ├── clzll.h │ │ ├── diyfp.h │ │ ├── dtoa.h │ │ ├── ieee754.h │ │ ├── itoa.h │ │ ├── meta.h │ │ ├── pow10.h │ │ ├── regex.h │ │ ├── stack.h │ │ ├── strfunc.h │ │ ├── strtod.h │ │ └── swap.h │ ├── istreamwrapper.h │ ├── memorybuffer.h │ ├── memorystream.h │ ├── msinttypes │ │ ├── inttypes.h │ │ └── stdint.h │ ├── ostreamwrapper.h │ ├── pointer.h │ ├── prettywriter.h │ ├── rapidjson.h │ ├── reader.h │ ├── schema.h │ ├── stream.h │ ├── stringbuffer.h │ ├── uri.h │ └── writer.h └── src │ ├── canvas_display_list.cpp │ ├── canvas_display_list.h │ ├── canvex_c_api.cpp │ ├── canvex_demo_main.cpp │ ├── canvex_render_frame_main.c │ ├── canvex_skia_context.cpp │ ├── canvex_skia_context.h │ ├── canvex_skia_executor.cpp │ ├── canvex_skia_executor.h │ ├── canvex_skia_resource_context.cpp │ ├── canvex_skia_resource_context.h │ ├── file_util.cpp │ ├── file_util.h │ ├── lib.rs │ ├── meson.build │ ├── skia_includes.h │ ├── style_util.cpp │ ├── style_util.h │ └── time_util.h ├── test ├── .gitignore ├── canvex-render-frame-util.js ├── run_all_tests.sh ├── run_clean_and_copy_to_repo.sh ├── run_scenario.sh ├── run_vcsrender_base_test.sh ├── scenarios │ ├── baseline-modes │ │ ├── vcs-output_0_fgdisplaylist.canvex.json │ │ ├── vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_0_videolayers.json │ │ ├── vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_10_fgdisplaylist.canvex.json │ │ ├── vcs-output_10_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_10_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_10_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_10_videolayers.json │ │ ├── vcs-output_10_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_10_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_10_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_20_fgdisplaylist.canvex.json │ │ ├── vcs-output_20_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_20_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_20_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_20_videolayers.json │ │ ├── vcs-output_20_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_20_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_20_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_30_fgdisplaylist.canvex.json │ │ ├── vcs-output_30_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_30_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_30_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_30_videolayers.json │ │ ├── vcs-output_30_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_30_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_30_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_40_fgdisplaylist.canvex.json │ │ ├── vcs-output_40_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_40_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_40_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_40_videolayers.json │ │ ├── vcs-output_40_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_40_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_40_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_50_fgdisplaylist.canvex.json │ │ ├── vcs-output_50_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_50_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_50_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_50_videolayers.json │ │ ├── vcs-output_50_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_50_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_50_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_60_fgdisplaylist.canvex.json │ │ ├── vcs-output_60_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_60_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_60_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_60_videolayers.json │ │ ├── vcs-output_60_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_60_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_60_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_70_fgdisplaylist.canvex.json │ │ ├── vcs-output_70_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_70_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_70_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_70_videolayers.json │ │ ├── vcs-output_70_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_70_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_70_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_80_fgdisplaylist.canvex.json │ │ ├── vcs-output_80_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_80_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_80_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_80_videolayers.json │ │ ├── vcs-output_80_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_80_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_80_videolayerspreview.canvex.macos_skia_x86_64.png │ │ └── vcs-scenario.js │ ├── baseline-toast │ │ ├── vcs-output_10_fgdisplaylist.canvex.json │ │ ├── vcs-output_10_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_10_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_10_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_10_videolayers.json │ │ ├── vcs-output_10_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_10_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_10_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_110_fgdisplaylist.canvex.json │ │ ├── vcs-output_110_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_110_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_110_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_110_videolayers.json │ │ ├── vcs-output_110_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_110_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_110_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_130_fgdisplaylist.canvex.json │ │ ├── vcs-output_130_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_130_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_130_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_130_videolayers.json │ │ ├── vcs-output_130_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_130_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_130_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_180_fgdisplaylist.canvex.json │ │ ├── vcs-output_180_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_180_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_180_videolayers.json │ │ ├── vcs-output_180_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_180_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_20_fgdisplaylist.canvex.json │ │ ├── vcs-output_20_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_20_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_20_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_20_videolayers.json │ │ ├── vcs-output_20_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_20_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_20_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_60_fgdisplaylist.canvex.json │ │ ├── vcs-output_60_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_60_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_60_videolayers.json │ │ ├── vcs-output_60_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_60_videolayerspreview.canvex.macos_skia_arm64.png │ │ └── vcs-scenario.js │ ├── graphics-test │ │ ├── vcs-output_49_fgdisplaylist.canvex.json │ │ ├── vcs-output_49_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_49_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_49_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_49_videolayers.json │ │ ├── vcs-output_49_videolayerspreview.canvex.json │ │ ├── vcs-output_49_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_49_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_49_videolayerspreview.canvex.macos_skia_x86_64.png │ │ └── vcs-scenario.js │ ├── hello-landscape-1080 │ │ ├── vcs-output_0_fgdisplaylist.canvex.json │ │ ├── vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_0_videolayers.json │ │ ├── vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png │ │ └── vcs-scenario.js │ ├── hello-portrait │ │ ├── vcs-output_0_fgdisplaylist.canvex.json │ │ ├── vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_0_videolayers.json │ │ ├── vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png │ │ └── vcs-scenario.js │ └── hello │ │ ├── vcs-output_0_fgdisplaylist.canvex.json │ │ ├── vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_0_videolayers.json │ │ ├── vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_180_fgdisplaylist.canvex.json │ │ ├── vcs-output_180_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_180_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_180_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_180_videolayers.json │ │ ├── vcs-output_180_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_180_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_180_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_190_fgdisplaylist.canvex.json │ │ ├── vcs-output_190_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_190_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_190_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_190_videolayers.json │ │ ├── vcs-output_190_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_190_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_190_videolayerspreview.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_200_fgdisplaylist.canvex.json │ │ ├── vcs-output_200_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_200_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_200_videolayers.json │ │ ├── vcs-output_200_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_200_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_340_fgdisplaylist.canvex.json │ │ ├── vcs-output_340_fgdisplaylist.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_340_fgdisplaylist.canvex.macos_skia_arm64.png │ │ ├── vcs-output_340_fgdisplaylist.canvex.macos_skia_x86_64.png │ │ ├── vcs-output_340_videolayers.json │ │ ├── vcs-output_340_videolayerspreview.canvex.linux_skia_x86_64.png │ │ ├── vcs-output_340_videolayerspreview.canvex.macos_skia_arm64.png │ │ ├── vcs-output_340_videolayerspreview.canvex.macos_skia_x86_64.png │ │ └── vcs-scenario.js └── vcsrender │ └── expected_basetest_render_yuv │ ├── vcsrenderout_0100.linux_skia_x86_64.yuv │ ├── vcsrenderout_0100.macos_skia_arm64.yuv │ ├── vcsrenderout_0200.linux_skia_x86_64.yuv │ └── vcsrenderout_0200.macos_skia_arm64.yuv ├── vcscut ├── .eslintrc.json ├── .gitignore ├── README.md ├── cut.js ├── example-data │ └── wasteland_ponies_reel.vcscut.json ├── ffexec.js ├── ffinput.js ├── ffmetadata.js ├── ffoutput.js ├── package.json └── timeutil.js └── vcsrender ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── build.rs ├── convert_movie_to_yuvseq.sh ├── convert_png_to_yuv.sh ├── convert_yuv_to_png.sh ├── convert_yuvseq_to_movie.sh ├── cxx_argp ├── cxx_argp_application.h └── cxx_argp_parser.h ├── example-data ├── batchtest1 │ ├── batchtest1_fg_000000.json │ ├── batchtest1_fg_000030.json │ ├── batchtest1_fg_000080.json │ ├── batchtest1_vl_000000.json │ ├── batchtest1_vl_000050.json │ └── batchtest1_vl_000080.json ├── big-buck-bunny_trim_38s_1m.mp4 ├── pauli_webcam_example_720.m4v ├── testpattern_956x602.png ├── testpattern_956x602.yuv └── vl_16inputs_720.json ├── include └── vcsrender_c_api.h ├── libyuv ├── include │ ├── libyuv.h │ └── libyuv │ │ ├── basic_types.h │ │ ├── compare.h │ │ ├── compare_row.h │ │ ├── convert.h │ │ ├── convert_argb.h │ │ ├── convert_from.h │ │ ├── convert_from_argb.h │ │ ├── cpu_id.h │ │ ├── loongson_intrinsics.h │ │ ├── macros_msa.h │ │ ├── mjpeg_decoder.h │ │ ├── planar_functions.h │ │ ├── rotate.h │ │ ├── rotate_argb.h │ │ ├── rotate_row.h │ │ ├── row.h │ │ ├── scale.h │ │ ├── scale_argb.h │ │ ├── scale_rgb.h │ │ ├── scale_row.h │ │ ├── scale_uv.h │ │ ├── version.h │ │ └── video_common.h └── lib-static │ ├── linux-x64 │ └── libyuv_internal.a │ └── mac-arm64 │ ├── libyuv_internal.a │ └── libyuv_neon.a ├── meson.build ├── src ├── demo_main.cpp ├── file_util.cpp ├── file_util.h ├── fileseq_util.cpp ├── fileseq_util.h ├── imageseq.cpp ├── imageseq.h ├── inputloader.cpp ├── inputloader.h ├── inputtimings.h ├── lib.rs ├── mask.cpp ├── mask.h ├── meson.build ├── parse │ ├── parse_inputtimings.cpp │ ├── parse_inputtimings.h │ ├── parse_scenedesc.cpp │ └── parse_scenedesc.h ├── scenedesc.h ├── sceneseq.cpp ├── sceneseq.h ├── thumbs.cpp ├── thumbs.h ├── time_util.h ├── vcsrender_c_api.cpp ├── vcsrender_main.cpp ├── yuv_compositor.cpp ├── yuv_compositor.h └── yuvbuf.h └── subprojects └── canvex /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .direnv -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "server-render/canvex/canvex-skia"] 2 | path = server-render/canvex/canvex-skia 3 | url = git@github.com:daily-co/canvex-skia.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2022, Daily 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Video Component System (VCS) 2 | 3 | A video-oriented JavaScript graphics framework based on React, created by [Daily](https://daily.co). 4 | 5 | This is a beta release of the VCS SDK so you can build custom components for use in live streaming and recording on Daily. 6 | 7 | The VCS development toolchain and core library is in the `js` subdirectory. 8 | 9 | Please see the [Daily Reference Docs](https://docs.daily.co/reference/vcs) for more information on VCS and its usage. Refer to the [installation guide](https://docs.daily.co/reference/vcs/installation) for instructions on running this project locally. 10 | 11 | In case you've got general questions about Daily or need technical assistance, please reach out via [help@daily.co](mailto:help@daily.co). 12 | -------------------------------------------------------------------------------- /compositions/daily-baseline/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["eslint:recommended"], 4 | "env": { 5 | "browser": true, 6 | "node": false, 7 | "es2020": true 8 | }, 9 | "parserOptions": { 10 | "ecmaVersion": "latest", 11 | "sourceType": "module", 12 | "ecmaFeatures": { 13 | "jsx": true 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/CustomOverlay.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /* 4 | This component is intentionally empty. 5 | 6 | You can override it by providing a replacement source file through the Daily API. 7 | */ 8 | 9 | export default function CustomOverlay() { 10 | return null; 11 | } 12 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/HighlightRowText.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Box, Image, Text } from '#vcs-react/components'; 3 | import { useVideoTime, useViewportSize } from '#vcs-react/hooks'; 4 | import * as layoutFuncs from '../layouts.js'; 5 | 6 | export default function HighlightRowText({ 7 | textLines = [], 8 | highlightIndex = 0, 9 | textStyle = {}, 10 | highlightStyle = {}, 11 | }) { 12 | const numItems = textLines.length; 13 | const items = []; 14 | 15 | for (let i = 0; i < textLines.length; i++) { 16 | const label = textLines[i]; 17 | const isHighlight = i === highlightIndex; 18 | const itemKey = `${i}_${label}_${isHighlight}`; 19 | items.push( 20 | 27 | 35 | {label} 36 | 37 | 38 | ); 39 | } 40 | 41 | return {items}; 42 | } 43 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/ImageOverlay.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Emoji, Image } from '#vcs-react/components'; 3 | import * as layoutFuncs from '../layouts.js'; 4 | import { useFade } from './useFade.js'; 5 | 6 | export default function ImageOverlay({ 7 | src = 'overlay.png', 8 | emoji = '', 9 | positionCorner, 10 | aspectRatio, 11 | height_gu, 12 | margin_gu, 13 | fullScreen, 14 | fullScreenScaleMode = 'fit', 15 | opacity = 1, 16 | enableFade = false, 17 | show = false, 18 | }) { 19 | opacity = useFade({ enableFade, show, opacity, fadeDuration: 0.35 }); 20 | if (!opacity) return null; 21 | 22 | let layout; 23 | let scaleMode = 'fit'; 24 | if (fullScreen) { 25 | scaleMode = fullScreenScaleMode; 26 | } else { 27 | const layoutProps = { 28 | positionCorner, 29 | aspectRatio, 30 | height_gu, 31 | margin_gu, 32 | }; 33 | layout = [layoutFuncs.pip, layoutProps]; 34 | } 35 | 36 | emoji = emoji?.trim() || ''; 37 | 38 | return emoji?.length > 0 ? ( 39 | 40 | ) : ( 41 | 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/ParticipantLabelPipStyle.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Box, Text } from '#vcs-react/components'; 3 | import * as layoutFuncs from '../layouts.js'; 4 | 5 | export function ParticipantLabelPipStyle({ 6 | label: labelStr, 7 | labelStyle, 8 | layout: outerLayout, 9 | labelsOffset_px, 10 | }) { 11 | if ( 12 | !labelsOffset_px || 13 | !Number.isFinite(labelsOffset_px.x) || 14 | !Number.isFinite(labelsOffset_px.y) 15 | ) { 16 | labelsOffset_px = { x: 0, y: 0 }; 17 | } 18 | // apply a default offset in this mode so the offset comp param 19 | // behaves more predictably when the mode param is switched 20 | const offsets = { 21 | x: 10 + labelsOffset_px.x, 22 | y: 10 + labelsOffset_px.y, 23 | }; 24 | 25 | const label = ( 26 | 33 | {labelStr || ''} 34 | 35 | ); 36 | 37 | if (outerLayout) { 38 | // wrap in a box 39 | return ( 40 | 41 | {label} 42 | 43 | ); 44 | } 45 | return label; 46 | } 47 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/PausedPlaceholder.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Box, Image } from '#vcs-react/components'; 3 | import * as layoutFuncs from '../layouts.js'; 4 | 5 | export function PausedPlaceholder({ placeholderStyle = {}, layout }) { 6 | return ( 7 | 8 | 12 | 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/RoomDebug.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Box } from '#vcs-react/components'; 3 | import { RoomContext } from '#vcs-react/contexts'; 4 | import { debug } from '#vcs-stdlib/components'; 5 | 6 | const textSize_gu = 1; 7 | const headerTextColor = 'rgba(255, 255, 255, 0.68)'; 8 | const headerH_gu = textSize_gu * 10; 9 | 10 | export default function RoomDebug({ bgOpacity = 1 }) { 11 | const room = React.useContext(RoomContext); 12 | 13 | const baseProps = { 14 | headerTextColor, 15 | textSize_gu, 16 | bgOpacity, 17 | }; 18 | 19 | return ( 20 | 21 | 26 | 27 | 28 | ); 29 | } 30 | 31 | function header(parentFrame, params, layoutCtx) { 32 | let { x, y, w, h } = parentFrame; 33 | const pxPerGu = layoutCtx.pixelsPerGridUnit; 34 | 35 | h = headerH_gu * pxPerGu; 36 | 37 | return { x, y, w, h }; 38 | } 39 | 40 | function body(parentFrame, params, layoutCtx) { 41 | let { x, y, w, h } = parentFrame; 42 | const pxPerGu = layoutCtx.pixelsPerGridUnit; 43 | 44 | const headerH_px = headerH_gu * pxPerGu; 45 | y += headerH_px; 46 | h -= headerH_px; 47 | 48 | return { x, y, w, h }; 49 | } 50 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/overrides/decorateVideoDominantItem.js: -------------------------------------------------------------------------------- 1 | /* 2 | This is an override point. 3 | 4 | You can replace this function to return a custom decorator component 5 | for video in the 'dominant' layout mode. 6 | 7 | The default rendering for labels can also be toggled off here. 8 | 9 | Input arguments: 10 | * `isDominant`: whether this item is the dominant item or a chiclet item. 11 | * `index`: for chiclet items, the index. (always 0 when isDominant == true.) 12 | * `participant`: participant description object to be displayed. 13 | May be null if there's no active video input. 14 | * `props`: props passed to the `VideoSingle` component. 15 | 16 | Return object props: 17 | * `enableDefaultLabels`: render the default participant labels. 18 | * `customComponent`: a custom VCS component to be rendered. 19 | * `clipItem`: if true, the custom component graphics are clipped inside 20 | the video item's frame. 21 | * `customLayoutForVideo`: a layout applied to the item's video element. 22 | 23 | If you return a custom component, it gets rendered last, 24 | on top of the default labels. 25 | */ 26 | 27 | export default function decorateVideoDominantItem( 28 | isDominant, 29 | index, 30 | participant, 31 | props 32 | ) { 33 | return { 34 | enableDefaultLabels: true, 35 | customComponent: null, 36 | clipItem: false, 37 | customLayoutForVideo: null, 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/overrides/decorateVideoGridItem.js: -------------------------------------------------------------------------------- 1 | /* 2 | This is an override point. 3 | 4 | You can replace this function to return custom decorator components 5 | for video grid items. The function gets called for each item. 6 | 7 | The default rendering for labels and highlight can also be toggled off here. 8 | 9 | Input arguments: 10 | * `itemIndex`: the index of the item being decorated. 11 | * `itemProps`: props passed to create this item (see VideoGrid.js). 12 | * `gridProps`: props passed to the grid itself (see VideoGrid.js). 13 | 14 | Return object props: 15 | * `enableDefaultLabels`: render the default participant labels. 16 | * `enableDefaultHighlight`: render the default highlighting. 17 | * `customComponent`: a custom VCS component to be rendered. 18 | * `clipItem`: if true, the custom component graphics are clipped inside 19 | the video item's frame. 20 | * `customLayoutForVideo`: a layout applied to the item's video element. 21 | 22 | If you return a custom component, it gets rendered last, 23 | on top of the default labels + highlight. 24 | */ 25 | 26 | export default function decorateVideoGridItem(itemIndex, itemProps, gridProps) { 27 | return { 28 | enableDefaultLabels: true, 29 | enableDefaultHighlight: true, 30 | customComponent: null, 31 | clipItem: false, 32 | customLayoutForVideo: null, 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/overrides/decorateVideoPipItem.js: -------------------------------------------------------------------------------- 1 | /* 2 | This is an override point. 3 | 4 | You can replace this function to return a custom decorator component 5 | for video in the 'pip' layout mode. 6 | 7 | The default rendering for labels can also be toggled off here. 8 | 9 | Input arguments: 10 | * `index`: value is 0 for the main video, 1 for the PiP video. 11 | * `participant`: participant description object to be displayed. 12 | May be null if there's no active video input. 13 | * `props`: props passed to the `VideoSingle` component. 14 | 15 | Return object props: 16 | * `enableDefaultLabels`: render the default participant labels. 17 | * `customComponent`: a custom VCS component to be rendered. 18 | * `clipItem`: if true, the custom component graphics are clipped inside 19 | the video item's frame. 20 | * `customLayoutForVideo`: a layout applied to the item's video element. 21 | 22 | If you return a custom component, it gets rendered last, 23 | on top of the default labels. 24 | */ 25 | 26 | export default function decorateVideoPipItem(index, participant, props) { 27 | return { 28 | enableDefaultLabels: true, 29 | customComponent: null, 30 | clipItem: false, 31 | customLayoutForVideo: null, 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/overrides/decorateVideoSingleItem.js: -------------------------------------------------------------------------------- 1 | /* 2 | This is an override point. 3 | 4 | You can replace this function to return a custom decorator component 5 | for video in the 'single' layout mode. 6 | 7 | The default rendering for labels can also be toggled off here. 8 | 9 | Input arguments: 10 | * `participant`: participant description object to be displayed. 11 | May be null if there's no active video input. 12 | * `props`: props passed to the `VideoSingle` component. 13 | 14 | Return object props: 15 | * `enableDefaultLabels`: render the default participant labels. 16 | * `customComponent`: a custom VCS component to be rendered. 17 | * `clipItem`: if true, the custom component graphics are clipped inside 18 | the video item's frame. 19 | * `customLayoutForVideo`: a layout applied to the item's video element. 20 | 21 | If you return a custom component, it gets rendered last, 22 | on top of the default labels. 23 | */ 24 | 25 | export default function decorateVideoSingleItem(participant, props) { 26 | return { 27 | enableDefaultLabels: true, 28 | customComponent: null, 29 | clipItem: false, 30 | customLayoutForVideo: null, 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/overrides/decorateVideoSplitItem.js: -------------------------------------------------------------------------------- 1 | /* 2 | This is an override point. 3 | 4 | You can replace this function to return a custom decorator component 5 | for video in the 'split' layout mode. 6 | 7 | The default rendering for labels can also be toggled off here. 8 | 9 | Input arguments: 10 | * `index`: value is the participant's index in split layout, 0 or 1. 11 | * `participant`: participant description object to be displayed. 12 | May be null if there's no active video input. 13 | * `props`: props passed to the `VideoSingle` component. 14 | 15 | Return object props: 16 | * `enableDefaultLabels`: render the default participant labels. 17 | * `customComponent`: a custom VCS component to be rendered. 18 | * `clipItem`: if true, the custom component graphics are clipped inside 19 | the video item's frame. 20 | * `customLayoutForVideo`: a layout applied to the item's video element. 21 | 22 | If you return a custom component, it gets rendered last, 23 | on top of the default labels. 24 | */ 25 | 26 | export default function decorateVideoSplitItem(index, participant, props) { 27 | return { 28 | enableDefaultLabels: true, 29 | customComponent: null, 30 | clipItem: false, 31 | customLayoutForVideo: null, 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /compositions/daily-baseline/components/useFade.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useVideoTime } from '#vcs-react/hooks'; 3 | 4 | export function useFade({ 5 | enableFade, 6 | show, 7 | opacity = 1, 8 | fadeDuration = 0.35, 9 | }) { 10 | const t = useVideoTime(); 11 | 12 | // the 'show' boolean is needed because we must keep track of 13 | // when a component using this hook was toggled on/off 14 | // so we can compute the opacity value for the fade in/out. 15 | // default value for "time last toggled" is negative infinity 16 | // so the fade transition logic works right. 17 | const lastToggledRef = React.useRef({ 18 | show, 19 | t: -Infinity, 20 | }); 21 | 22 | if (lastToggledRef.current.show !== show) { 23 | // component visibility has been toggled, record this time 24 | lastToggledRef.current = { show, t }; 25 | } 26 | 27 | if (!enableFade && !show) { 28 | // without fade, we can just bail if the component is toggled off 29 | return 0; 30 | } 31 | 32 | opacity = Math.max(0, Math.min(1, opacity)); 33 | 34 | if (enableFade) { 35 | const tInFade = t - lastToggledRef.current.t; 36 | const fadePos = Math.min(1, tInFade / fadeDuration); 37 | if (show) { 38 | // fade in 39 | opacity *= fadePos; 40 | } else { 41 | // fade out 42 | opacity *= 1 - fadePos; 43 | } 44 | } 45 | 46 | if (opacity < 1 / 255) return 0; 47 | 48 | return opacity; 49 | } 50 | -------------------------------------------------------------------------------- /compositions/daily-baseline/constants.js: -------------------------------------------------------------------------------- 1 | export const DEFAULT_FONT = 'Roboto'; 2 | export const DEFAULT_LABEL_FONT_SIZE_PX = 20; 3 | export const DEFAULT_TOAST_FONT_SIZE_PX = 22; 4 | 5 | export const DEFAULT_OFFSET_VIDEO_SINGLE_PX = 10; 6 | 7 | export const PositionEdge = { 8 | LEFT: 'left', 9 | RIGHT: 'right', 10 | TOP: 'top', 11 | BOTTOM: 'bottom', 12 | }; 13 | 14 | export const PositionCorner = { 15 | TOP_LEFT: 'top-left', 16 | TOP_RIGHT: 'top-right', 17 | BOTTOM_LEFT: 'bottom-left', 18 | BOTTOM_RIGHT: 'bottom-right', 19 | }; 20 | 21 | // request all standard fonts 22 | export const fontFamilies = [ 23 | 'Roboto', 24 | 'RobotoCondensed', 25 | 'Anton', 26 | 'Bangers', 27 | 'Bitter', 28 | 'DMSans', 29 | 'Exo', 30 | 'Magra', 31 | 'PermanentMarker', 32 | 'SuezOne', 33 | 'Teko', 34 | ]; 35 | // fonts that are legible at a small size (for participant labels) 36 | export const fontFamilies_smallSizeFriendly = [ 37 | 'Roboto', 38 | 'RobotoCondensed', 39 | 'Bitter', 40 | 'DMSans', 41 | 'Exo', 42 | 'Magra', 43 | 'SuezOne', 44 | 'Teko', 45 | ]; 46 | // not all fonts have every weight, 47 | // but we can't currently filter the UI based on the font name 48 | export const fontWeights = [ 49 | '100', 50 | '200', 51 | '300', 52 | '400', 53 | '500', 54 | '600', 55 | '700', 56 | '800', 57 | '900', 58 | ]; 59 | -------------------------------------------------------------------------------- /compositions/daily-baseline/images/overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/compositions/daily-baseline/images/overlay.png -------------------------------------------------------------------------------- /compositions/daily-baseline/images/overlay.png.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 640, 3 | "height": 360 4 | } 5 | -------------------------------------------------------------------------------- /compositions/daily-baseline/images/party-popper_1f389.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/compositions/daily-baseline/images/party-popper_1f389.png -------------------------------------------------------------------------------- /compositions/daily-baseline/images/party-popper_1f389.png.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 240, 3 | "height": 240 4 | } 5 | -------------------------------------------------------------------------------- /compositions/daily-baseline/images/user_white_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/compositions/daily-baseline/images/user_white_64.png -------------------------------------------------------------------------------- /compositions/daily-baseline/images/user_white_64.png.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 64, 3 | "height": 64 4 | } 5 | -------------------------------------------------------------------------------- /compositions/daily-baseline/preloads.js: -------------------------------------------------------------------------------- 1 | export const imagePreloads = [ 2 | 'user_white_64.png', 3 | 'overlay.png', 4 | 'party-popper_1f389.png', 5 | ]; 6 | -------------------------------------------------------------------------------- /compositions/daily-roomdebug/constants.js: -------------------------------------------------------------------------------- 1 | export const textSize_gu = 1; 2 | 3 | export const headerTextColor = 'rgba(255, 255, 255, 0.68)'; 4 | -------------------------------------------------------------------------------- /compositions/daily-roomdebug/index.jsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Box } from '#vcs-react/components'; 3 | import { RoomContext } from '#vcs-react/contexts'; 4 | import { debug } from '#vcs-stdlib/components'; 5 | 6 | import { header, body } from './layouts.js'; 7 | import { headerTextColor, textSize_gu } from './constants.js'; 8 | 9 | export const compositionInterface = { 10 | displayMeta: { 11 | name: 'Room Debug', 12 | description: 'Prints out room metadata', 13 | }, 14 | params: [], 15 | }; 16 | 17 | export default function RoomDebugComposition() { 18 | const room = React.useContext(RoomContext); 19 | 20 | const baseProps = { 21 | headerTextColor, 22 | textSize_gu, 23 | }; 24 | 25 | return ( 26 | 27 | 32 | 33 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /compositions/daily-roomdebug/layouts.js: -------------------------------------------------------------------------------- 1 | import { textSize_gu } from './constants.js'; 2 | const headerH_gu = textSize_gu * 10; 3 | 4 | export function header(parentFrame, params, layoutCtx) { 5 | let { x, y, w, h } = parentFrame; 6 | const pxPerGu = layoutCtx.pixelsPerGridUnit; 7 | 8 | h = headerH_gu * pxPerGu; 9 | 10 | return { x, y, w, h }; 11 | } 12 | 13 | export function body(parentFrame, params, layoutCtx) { 14 | let { x, y, w, h } = parentFrame; 15 | const pxPerGu = layoutCtx.pixelsPerGridUnit; 16 | 17 | const headerH_px = headerH_gu * pxPerGu; 18 | y += headerH_px; 19 | h -= headerH_px; 20 | 21 | return { x, y, w, h }; 22 | } 23 | -------------------------------------------------------------------------------- /compositions/daily-rundown/components/LogoSidebar.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Box, Image, Text } from '#vcs-react/components'; 3 | import { useVideoTime, useViewportSize } from '#vcs-react/hooks'; 4 | import * as layouts from '../layouts.js'; 5 | import PollResult from './PollResult.js'; 6 | 7 | export default function LogoSidebar({ 8 | logoAssetName, 9 | useTitle, 10 | title, 11 | titleStyle = {}, 12 | pollData = {}, 13 | }) { 14 | let logo, pollResult; 15 | let splitPos = 1; 16 | 17 | if (!useTitle) { 18 | logo = ( 19 | 0 ? logoAssetName : 'logo.png' 22 | } 23 | /> 24 | ); 25 | } else { 26 | logo = ( 27 | 31 | {title} 32 | 33 | ); 34 | } 35 | 36 | if (pollData.showResult) { 37 | splitPos = 0.5; 38 | const noVotes = parseInt(pollData.noVotes, 10) || 0; 39 | const yesVotes = parseInt(pollData.yesVotes, 10) || 0; 40 | pollResult = ( 41 | 48 | ); 49 | } 50 | 51 | return ( 52 | 53 | 54 | {logo} 55 | 56 | {pollResult} 57 | 58 | ); 59 | } 60 | -------------------------------------------------------------------------------- /compositions/daily-rundown/components/ParticipantLabel.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Box, Text } from '#vcs-react/components'; 3 | import * as layouts from '../layouts.js'; 4 | 5 | export default function ParticipantLabel({ name, style, layout }) { 6 | return ( 7 | 8 | 9 | {name} 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /compositions/daily-rundown/components/VideoContainer.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import HostGuestVideo from './HostGuestVideo.js'; 3 | 4 | /* 5 | This container component is provided as an override point. 6 | 7 | In case you want to replace the video rendering, 8 | replace this file with your own code using the Daily session assets API. 9 | 10 | You could e.g. render a grid using the layout available in VCS stdlib/layouts. 11 | */ 12 | 13 | export default function VideoContainer({ 14 | activeIds, 15 | participantLabelStyle, 16 | guestNameOverride, 17 | }) { 18 | return ( 19 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /compositions/daily-rundown/images/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/compositions/daily-rundown/images/header.png -------------------------------------------------------------------------------- /compositions/daily-rundown/images/header.png.json: -------------------------------------------------------------------------------- 1 | { "width": 274, "height": 154 } 2 | -------------------------------------------------------------------------------- /compositions/daily-rundown/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/compositions/daily-rundown/images/logo.png -------------------------------------------------------------------------------- /compositions/daily-rundown/images/logo.png.json: -------------------------------------------------------------------------------- 1 | { "width": 249, "height": 379 } 2 | -------------------------------------------------------------------------------- /compositions/daily-rundown/preloads.js: -------------------------------------------------------------------------------- 1 | export const imagePreloads = ['logo.png', 'header.png']; 2 | -------------------------------------------------------------------------------- /cut-transcript-tools/.eslintignore: -------------------------------------------------------------------------------- 1 | *.zx.mjs 2 | -------------------------------------------------------------------------------- /cut-transcript-tools/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["eslint:recommended"], 4 | "env": { 5 | "node": true, 6 | "es2020": true 7 | }, 8 | "parserOptions": { 9 | "ecmaVersion": "latest", 10 | "sourceType": "module", 11 | "ecmaFeatures": { 12 | "jsx": false 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cut-transcript-tools/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /dist 3 | -------------------------------------------------------------------------------- /cut-transcript-tools/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@daily-co/cut-transcript-tools", 3 | "version": "0.1.0", 4 | "author": "Daily (https://daily.co)", 5 | "type": "module", 6 | "engines": { 7 | "node": ">=18.19.0" 8 | }, 9 | "dependencies": { 10 | "@deepgram/sdk": "^3.1.9", 11 | "zx": "^7.2.3" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /js/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /render-output 3 | /dist 4 | 5 | # yarn 4.x 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/sdks 12 | !.yarn/versions -------------------------------------------------------------------------------- /js/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /js/README.md: -------------------------------------------------------------------------------- 1 | # Video Component System (VCS) - JS core 2 | 3 | A video-oriented JavaScript graphics framework based on React, created by [Daily](https://daily.co). 4 | 5 | This package contains the JavaScript-based core library and development toolchain for VCS. 6 | 7 | You can use this package to develop VCS compositions. 8 | -------------------------------------------------------------------------------- /js/devrig/example-assets/atari_vcs_woodgrain_texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/atari_vcs_woodgrain_texture.png -------------------------------------------------------------------------------- /js/devrig/example-assets/demoperson_missfury.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/demoperson_missfury.png -------------------------------------------------------------------------------- /js/devrig/example-assets/demoperson_missfury_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/demoperson_missfury_square.png -------------------------------------------------------------------------------- /js/devrig/example-assets/demoperson_moongirl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/demoperson_moongirl.png -------------------------------------------------------------------------------- /js/devrig/example-assets/demoperson_moongirl_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/demoperson_moongirl_square.png -------------------------------------------------------------------------------- /js/devrig/example-assets/demoperson_yellowkid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/demoperson_yellowkid.png -------------------------------------------------------------------------------- /js/devrig/example-assets/screenshare_standin2_1600x1000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/screenshare_standin2_1600x1000.png -------------------------------------------------------------------------------- /js/devrig/example-assets/screenshare_standin_1600x900.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/screenshare_standin_1600x900.png -------------------------------------------------------------------------------- /js/devrig/example-assets/test_square_320px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/test_square_320px.png -------------------------------------------------------------------------------- /js/devrig/example-assets/user_white_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/example-assets/user_white_64.png -------------------------------------------------------------------------------- /js/devrig/ui-assets/checkboxOff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/ui-assets/checkboxOff.png -------------------------------------------------------------------------------- /js/devrig/ui-assets/checkboxOn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/ui-assets/checkboxOn.png -------------------------------------------------------------------------------- /js/devrig/ui-assets/randomize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/js/devrig/ui-assets/randomize.png -------------------------------------------------------------------------------- /js/example/batch/baseline1.json: -------------------------------------------------------------------------------- 1 | { 2 | "compositionId": "daily:baseline", 3 | "durationInFrames": 100, 4 | "framesPerSecond": 30, 5 | "outputSize": { 6 | "w": 1280, 7 | "h": 720 8 | }, 9 | "eventsByFrame": { 10 | "0": { 11 | "activeVideoInputSlots": [true, true], 12 | "params": { 13 | "mode": "split" 14 | } 15 | }, 16 | "30": { 17 | "params": { 18 | "showTextOverlay": true 19 | } 20 | }, 21 | "50": { 22 | "activeVideoInputSlots": [true, true, true], 23 | "params": { 24 | "mode": "grid" 25 | } 26 | }, 27 | "80": { 28 | "activeVideoInputSlots": [true, true], 29 | "params": { 30 | "text.content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam a tellus vitae quam feugiat ullam." 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /js/example/webvtt/transcript1.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 00:00:04.029 --> 00:00:07.464 4 | Hello. Hello. Hello. One, two, 5 | 6 | 00:00:07.464 --> 00:00:10.869 7 | Three. 8 | 9 | 00:00:10.869 --> 00:00:15.834 10 | My app is working fine. 11 | 12 | 00:00:15.834 --> 00:00:20.199 13 | I am generating web files. 14 | 15 | 00:00:20.199 --> 00:00:23.214 16 | Okay. 17 | 18 | -------------------------------------------------------------------------------- /js/lib-node/log.js: -------------------------------------------------------------------------------- 1 | import * as util from 'util'; 2 | 3 | let g_logger; 4 | 5 | function makeLogger(logFn) { 6 | g_logger = function logToHostInfo() { 7 | let s = util.format.apply(util, arguments); 8 | const date = new Date(); 9 | s = date.toISOString() + ' | ' + s; 10 | logFn(s); 11 | } 12 | } 13 | 14 | export function logToHostInfo() { 15 | if (!g_logger) { 16 | makeLogger(console.log); 17 | } 18 | g_logger.apply(null, arguments); 19 | } 20 | 21 | export function setHostInfoFunc(logFn) { 22 | makeLogger(logFn); 23 | } 24 | -------------------------------------------------------------------------------- /js/src/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["eslint:recommended"], 4 | "env": { 5 | "browser": true, 6 | "node": true, 7 | "es2020": true 8 | }, 9 | "parserOptions": { 10 | "ecmaVersion": "latest", 11 | "sourceType": "module", 12 | "ecmaFeatures": { 13 | "jsx": false 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /js/src/index.js: -------------------------------------------------------------------------------- 1 | export { Composition } from './comp-backing-model.js'; 2 | 3 | export { render } from './react-reconciler.js'; 4 | -------------------------------------------------------------------------------- /js/src/react/components/Box.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export function Box(props) { 4 | // can't use JSX in VCS core because it needs to run on Node without transpiling 5 | return React.createElement( 6 | 'box', 7 | { 8 | id: props.id, 9 | layout: props.layout, 10 | style: props.style || {}, 11 | transform: props.transform || {}, 12 | clip: props.clip || false, 13 | blend: props.blend || {}, 14 | }, 15 | props.children 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /js/src/react/components/Emoji.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export function Emoji(props) { 4 | const { value = '' } = props; 5 | 6 | // can't use JSX in VCS core because it needs to run on Node without transpiling 7 | return React.createElement('emoji', { 8 | id: props.id, 9 | layout: props.layout, 10 | style: props.style || {}, 11 | transform: props.transform || {}, 12 | blend: props.blend || {}, 13 | value, 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /js/src/react/components/Image.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export function Image(props) { 4 | let { src } = props; 5 | 6 | if (typeof src === 'string' && src.indexOf('.') === -1) { 7 | // add default file extension 8 | src += '.png'; 9 | } 10 | 11 | // can't use JSX in VCS core because it needs to run on Node without transpiling 12 | return React.createElement('image', { 13 | id: props.id, 14 | layout: props.layout, 15 | style: props.style || {}, 16 | transform: props.transform || {}, 17 | src, 18 | scaleMode: props.scaleMode || 'fit', 19 | blend: props.blend || {}, 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /js/src/react/components/Text.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export function Text(props) { 4 | const text = Array.isArray(props.children) 5 | ? props.children.join(' ') 6 | : props.children || ''; 7 | 8 | // fontSize is mandatory, so add a default if not present 9 | let style = props.style || {}; 10 | if (!style.fontSize_gu && !style.fontSize_px && !style.fontSize_vh) { 11 | style = { 12 | ...style, 13 | fontSize_gu: 1, 14 | }; 15 | } 16 | 17 | // can't use JSX in VCS core because it needs to run on Node without transpiling 18 | return React.createElement('label', { 19 | id: props.id, 20 | layout: props.layout, 21 | style, 22 | transform: props.transform || {}, 23 | clip: props.clip || false, 24 | blend: props.blend || {}, 25 | text, 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /js/src/react/components/Video.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export function Video(props) { 4 | // can't use JSX in VCS core because it needs to run on Node without transpiling 5 | return React.createElement('video', { 6 | id: props.id, 7 | layout: props.layout, 8 | style: props.style || {}, 9 | src: props.src, 10 | scaleMode: props.scaleMode || 'fill', 11 | blend: props.blend || {}, 12 | zoom: Number.isFinite(props.zoom) && props.zoom > 0 ? props.zoom : 1, 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /js/src/react/components/WebFrame.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useVideoTime } from '../hooks/index.js'; 3 | 4 | const WEBFRAME_UPDATE_FPS = 2; 5 | 6 | export function WebFrame(props) { 7 | // currently we nudge a regular update of the webframe live asset by passing a frame index based on video time. 8 | // this triggers a re-render of the built-in component instance. 9 | const t = useVideoTime(); 10 | const frameIntv = 1 / WEBFRAME_UPDATE_FPS; // seconds 11 | const frameIdx = 1 + Math.floor(t / frameIntv); 12 | 13 | const keyPressActionIsValid = 14 | props.keyPressAction && 15 | props.keyPressAction.name && 16 | props.keyPressAction.key; 17 | const keyPressAction = { 18 | name: keyPressActionIsValid ? props.keyPressAction.name : '', 19 | key: keyPressActionIsValid ? '' + props.keyPressAction.key : '', 20 | modifiers: keyPressActionIsValid ? props.keyPressAction.modifiers : '', 21 | }; 22 | 23 | // can't use JSX in VCS core because it needs to run on Node without transpiling 24 | return React.createElement('webframe', { 25 | id: props.id, 26 | layout: props.layout, 27 | style: props.style || {}, 28 | transform: props.transform || {}, 29 | scaleMode: props.scaleMode || 'fit', 30 | blend: props.blend || {}, 31 | 32 | src: props.src || '', 33 | viewportSize: props.viewportSize, 34 | liveAssetUpdateKey: frameIdx, 35 | 36 | keyPressAction, 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /js/src/react/components/index.js: -------------------------------------------------------------------------------- 1 | export { Box } from './Box.js'; 2 | export { Emoji } from './Emoji.js'; 3 | export { Image } from './Image.js'; 4 | export { Text } from './Text.js'; 5 | export { Video } from './Video.js'; 6 | export { WebFrame } from './WebFrame.js'; 7 | -------------------------------------------------------------------------------- /js/src/react/contexts/MediaInputContext.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const MediaInputContext = React.createContext({ 4 | // the output viewport. 5 | // doesn't change during a rendering session. 6 | viewportSize: { 7 | w: 0, 8 | h: 0, 9 | }, 10 | 11 | // size of the grid unit. 12 | // will be set when composition is inited (by default based on viewport size). 13 | pixelsPerGridUnit: 20, 14 | 15 | // an array of truthy or falsy objects. 16 | // describes which video inputs are active. 17 | // depending on the application, these inputs may represent video call 18 | // participants, video files, or something else. 19 | // the array is expected to be filled out to match the maximum number of inputs 20 | // available on the host application. (e.g. if host supports 16 inputs but 21 | // none of them is connected, this array would contain 16 null/false values.) 22 | // NOTE: additional metadata may be provided by passing an object value for a slot. 23 | // in this case each non-null input is expected to provide at least an 'id' property. 24 | // (see hooks/mediaInput.js for a helper that reads this metadata.) 25 | // the reason for allowing non-object values here is to make the simple case 26 | // very simple: if a slot doesn't have the 'id' property, the video input ids 27 | // are assumed to be simply indexes into this slot array. this is useful for 28 | // offline compositing applications with a fixed set of inputs (e.g. test runners). 29 | activeVideoInputSlots: [], 30 | }); 31 | -------------------------------------------------------------------------------- /js/src/react/contexts/RoomContext.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | // the shape of the Peer object described as vanilla JS 4 | export function makeEmptyPeer() { 5 | return { 6 | id: '', 7 | displayName: null, 8 | video: { 9 | id: null, // if non-null, can be mapped to MediaInputContext.activeVideoInputSlots 10 | paused: false, 11 | }, 12 | screenshareVideo: { 13 | id: null, 14 | paused: false, 15 | }, 16 | audio: { 17 | id: null, 18 | paused: false, 19 | }, 20 | }; 21 | } 22 | 23 | export const RenderingEnvironmentType = { 24 | UNKNOWN: '', 25 | OFFLINE: 'offline', 26 | MEDIA_SERVER: 'media-server', 27 | PARTICIPANT_CLIENT: 'participant-client', 28 | PASSIVE_VIEWER_CLIENT: 'passive-viewer-client', 29 | }; 30 | 31 | export const RoomContext = React.createContext({ 32 | // our role within this room (e.g. "media server"). 33 | renderingEnvironment: RenderingEnvironmentType.UNKNOWN, 34 | 35 | // a list of Peer objects. 36 | // this may not be an exhaustive list of participants on a video call. 37 | // "available" simply means that these peers are known to the host app. 38 | // they probably have video and/or audio tracks, but both might be paused. 39 | // the ordering is also unspecified (host-dependent). 40 | // we can't give any more specific guarantees (at least for now) because VCS 41 | // doesn't have control over the peer selection logic used by the host app. 42 | availablePeers: [], 43 | }); 44 | -------------------------------------------------------------------------------- /js/src/react/contexts/TimeContext.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const PlaybackStateType = { 4 | PLAYING: 'playing', 5 | POSTROLL: 'postroll', 6 | }; 7 | 8 | export const TimeContext = React.createContext({ 9 | currentTime: 0, 10 | playbackState: PlaybackStateType.PLAYING, 11 | }); 12 | -------------------------------------------------------------------------------- /js/src/react/contexts/index.js: -------------------------------------------------------------------------------- 1 | export { CompositionDataContext } from './CompositionDataContext.js'; 2 | export { TimeContext, PlaybackStateType } from './TimeContext.js'; 3 | export { MediaInputContext } from './MediaInputContext.js'; 4 | export { RoomContext, RenderingEnvironmentType } from './RoomContext.js'; 5 | -------------------------------------------------------------------------------- /js/src/react/hooks/compositionData.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { CompositionDataContext } from '../contexts/index.js'; 3 | 4 | export function useParams() { 5 | const ctx = React.useContext(CompositionDataContext); 6 | return ctx.params; 7 | } 8 | 9 | export function useStandardSources() { 10 | const ctx = React.useContext(CompositionDataContext); 11 | return ctx.standardSources; 12 | } 13 | -------------------------------------------------------------------------------- /js/src/react/hooks/index.js: -------------------------------------------------------------------------------- 1 | export { useParams, useStandardSources } from './compositionData.js'; 2 | export { 3 | useVideoTime, 4 | useVideoPlaybackState, 5 | PlaybackStateType, 6 | } from './time.js'; 7 | export { 8 | useMediaInput, 9 | useViewportSize, 10 | useGrid, 11 | useActiveVideo, 12 | } from './mediaInput.js'; 13 | export { useAudioOnlyPeers, useUnpausedPeers } from './room.js'; 14 | -------------------------------------------------------------------------------- /js/src/react/hooks/time.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { 3 | TimeContext, 4 | PlaybackStateType as PlaybackStateType_, 5 | } from '../contexts/index.js'; 6 | 7 | export function useVideoTime() { 8 | const ctx = React.useContext(TimeContext); 9 | return ctx.currentTime; 10 | } 11 | 12 | export function useVideoPlaybackState() { 13 | const ctx = React.useContext(TimeContext); 14 | return ctx.playbackState; 15 | } 16 | 17 | export const PlaybackStateType = PlaybackStateType_; 18 | -------------------------------------------------------------------------------- /js/src/stdlib/components/index.js: -------------------------------------------------------------------------------- 1 | import { MediaInputPrintout } from './debug/MediaInputPrintout.js'; 2 | import { RoomPrintout } from './debug/RoomPrintout.js'; 3 | 4 | const debug = { 5 | MediaInputPrintout, 6 | RoomPrintout, 7 | }; 8 | 9 | export { debug }; 10 | -------------------------------------------------------------------------------- /js/src/stdlib/layouts/index.js: -------------------------------------------------------------------------------- 1 | import { pad, offset, fit } from './transform.js'; 2 | 3 | import { 4 | splitHorizontal, 5 | splitVertical, 6 | splitAcrossLongerDimension, 7 | } from './split.js'; 8 | 9 | import { column, grid, simpleLineGrid } from './grid.js'; 10 | 11 | export { 12 | pad, 13 | offset, 14 | fit, 15 | splitHorizontal, 16 | splitVertical, 17 | splitAcrossLongerDimension, 18 | column, 19 | grid, 20 | simpleLineGrid, 21 | }; 22 | -------------------------------------------------------------------------------- /js/src/stdlib/layouts/split.js: -------------------------------------------------------------------------------- 1 | export function splitVertical(parentFrame, params, layoutCtx) { 2 | const pxPerGu = layoutCtx.pixelsPerGridUnit; 3 | let { index, pos = 0.5, margin_gu = 0 } = params; 4 | let { x, y, w, h } = parentFrame; 5 | 6 | const margin_px = margin_gu * pxPerGu; 7 | const availableW = parentFrame.w - margin_px; 8 | 9 | if (index === 0) { 10 | w = availableW * pos; 11 | } else { 12 | w = availableW * (1 - pos); 13 | x += availableW * pos + margin_px; 14 | } 15 | 16 | return { x, y, w, h }; 17 | } 18 | 19 | export function splitHorizontal(parentFrame, params, layoutCtx) { 20 | const pxPerGu = layoutCtx.pixelsPerGridUnit; 21 | let { index, pos = 0.5, margin_gu = 0 } = params; 22 | let { x, y, w, h } = parentFrame; 23 | 24 | const margin_px = margin_gu * pxPerGu; 25 | const availableH = parentFrame.h - margin_px; 26 | 27 | if (index === 0) { 28 | h = availableH * pos; 29 | } else { 30 | h = availableH * (1 - pos); 31 | y += availableH * pos + margin_px; 32 | } 33 | 34 | return { x, y, w, h }; 35 | } 36 | 37 | export function splitAcrossLongerDimension(parentFrame, params, layoutCtx) { 38 | const { viewport } = layoutCtx; 39 | const asp = viewport.w / viewport.h; 40 | if (asp >= 1) { 41 | return splitVertical(parentFrame, params, layoutCtx); 42 | } else { 43 | return splitHorizontal(parentFrame, params, layoutCtx); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /js/swc.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "ecmascript", 5 | "jsx": true, 6 | "dynamicImport": false, 7 | "privateMethod": false, 8 | "functionBind": false, 9 | "exportDefaultFrom": false, 10 | "exportNamespaceFrom": false, 11 | "decorators": false, 12 | "decoratorsBeforeExport": false, 13 | "topLevelAwait": false, 14 | "importMeta": false 15 | }, 16 | "transform": null, 17 | "target": "es2018", 18 | "loose": false, 19 | "externalHelpers": false, 20 | "keepClassNames": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "daily-vcs-sdk", 3 | "version": "0.1.0", 4 | "author": "Daily.co", 5 | "license": "BSD-2-Clause", 6 | "type": "module" 7 | } 8 | -------------------------------------------------------------------------------- /res/fonts/Anton-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Anton-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/Bangers-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bangers-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-Black.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-BlackItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-Bold.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-BoldItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-Italic.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-Light.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-LightItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-Medium.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-MediumItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-Thin.ttf -------------------------------------------------------------------------------- /res/fonts/Bitter-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Bitter-ThinItalic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-Black.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-BlackItalic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-Bold.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-BoldItalic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-ExtraBold.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-ExtraLight.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-Italic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-Light.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-LightItalic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-Medium.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-MediumItalic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-SemiBold.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-Thin.ttf -------------------------------------------------------------------------------- /res/fonts/DMSans-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/DMSans-ThinItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-Black.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-BlackItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-Bold.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-BoldItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-Italic.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-Light.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-LightItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-Medium.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-MediumItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-Thin.ttf -------------------------------------------------------------------------------- /res/fonts/Exo-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Exo-ThinItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Magra-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Magra-Bold.ttf -------------------------------------------------------------------------------- /res/fonts/Magra-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Magra-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/NotoColorEmoji-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/NotoColorEmoji-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/PermanentMarker-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/PermanentMarker-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-Black.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-BlackItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-Italic.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-Light.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-Medium.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-MediumItalic.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-Thin.ttf -------------------------------------------------------------------------------- /res/fonts/Roboto-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Roboto-ThinItalic.ttf -------------------------------------------------------------------------------- /res/fonts/RobotoCondensed-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/RobotoCondensed-Bold.ttf -------------------------------------------------------------------------------- /res/fonts/RobotoCondensed-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/RobotoCondensed-BoldItalic.ttf -------------------------------------------------------------------------------- /res/fonts/RobotoCondensed-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/RobotoCondensed-Italic.ttf -------------------------------------------------------------------------------- /res/fonts/RobotoCondensed-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/RobotoCondensed-Light.ttf -------------------------------------------------------------------------------- /res/fonts/RobotoCondensed-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/RobotoCondensed-LightItalic.ttf -------------------------------------------------------------------------------- /res/fonts/RobotoCondensed-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/RobotoCondensed-Medium.ttf -------------------------------------------------------------------------------- /res/fonts/RobotoCondensed-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/RobotoCondensed-MediumItalic.ttf -------------------------------------------------------------------------------- /res/fonts/RobotoCondensed-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/RobotoCondensed-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/SuezOne-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/SuezOne-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/Teko-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Teko-Bold.ttf -------------------------------------------------------------------------------- /res/fonts/Teko-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Teko-Light.ttf -------------------------------------------------------------------------------- /res/fonts/Teko-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Teko-Medium.ttf -------------------------------------------------------------------------------- /res/fonts/Teko-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Teko-Regular.ttf -------------------------------------------------------------------------------- /res/fonts/Teko-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/fonts/Teko-SemiBold.ttf -------------------------------------------------------------------------------- /res/test-assets/daily-logo-primary-darkground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/test-assets/daily-logo-primary-darkground.png -------------------------------------------------------------------------------- /res/test-assets/daily-logo-primary-darkground.png.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 800, 3 | "height": 320 4 | } 5 | -------------------------------------------------------------------------------- /res/test-assets/daily-logo-small-lightground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/test-assets/daily-logo-small-lightground.png -------------------------------------------------------------------------------- /res/test-assets/daily-logo-small-lightground.png.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 80, 3 | "height": 32 4 | } 5 | -------------------------------------------------------------------------------- /res/test-assets/landscape-j3CjZYckM88-unsplash.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 1600, 3 | "height": 1200, 4 | "copyright": "Emma Harper / via Unsplash (emarieharp015), Free to use under the Unsplash License", 5 | "webPage": "https://unsplash.com/photos/j3CjZYckM88" 6 | } 7 | -------------------------------------------------------------------------------- /res/test-assets/landscape-j3CjZYckM88-unsplash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/test-assets/landscape-j3CjZYckM88-unsplash.png -------------------------------------------------------------------------------- /res/test-assets/raised-hand_270b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/test-assets/raised-hand_270b.png -------------------------------------------------------------------------------- /res/test-assets/raised-hand_270b.png.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 240, 3 | "height": 240 4 | } 5 | -------------------------------------------------------------------------------- /res/test-assets/test_square_320px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/test-assets/test_square_320px.png -------------------------------------------------------------------------------- /res/test-assets/test_square_320px.png.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 320, 3 | "height": 320 4 | } 5 | -------------------------------------------------------------------------------- /res/test-assets/user_white_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/res/test-assets/user_white_64.png -------------------------------------------------------------------------------- /res/test-assets/user_white_64.png.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 64, 3 | "height": 64 4 | } 5 | -------------------------------------------------------------------------------- /server-render/canvex/.gitignore: -------------------------------------------------------------------------------- 1 | build/** 2 | target/** 3 | -------------------------------------------------------------------------------- /server-render/canvex/.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Mac", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [], 9 | "macFrameworkPath": [ 10 | "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks" 11 | ], 12 | "compilerPath": "/usr/bin/clang", 13 | "cStandard": "c17", 14 | "cppStandard": "gnu++17", 15 | "intelliSenseMode": "macos-clang-arm64", 16 | "compileCommands": "${workspaceFolder}/build/compile_commands.json" 17 | }, 18 | { 19 | "name": "Linux", 20 | "includePath": [ 21 | "${workspaceFolder}/**" 22 | ], 23 | "defines": [], 24 | "compilerPath": "/usr/bin/clang", 25 | "cStandard": "c11", 26 | "cppStandard": "gnu++17", 27 | "intelliSenseMode": "linux-clang-x64" 28 | } 29 | ], 30 | "version": 4 31 | } -------------------------------------------------------------------------------- /server-render/canvex/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "ninja build", 8 | "type": "shell", 9 | "command": "ninja -C build", 10 | "group": "build", 11 | "presentation": { 12 | "reveal": "always", 13 | "panel": "dedicated", 14 | "clear": true 15 | } 16 | }, 17 | { 18 | "label": "run canvex demo", 19 | "type": "shell", 20 | "command": "build/canvex_demo", 21 | "group": "build", 22 | "presentation": { 23 | "reveal": "always", 24 | "panel": "dedicated", 25 | "clear": true 26 | } 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /server-render/canvex/example-data/background-clip.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 1280, 3 | "height": 720, 4 | "commands": [ 5 | ["save"], 6 | ["beginPath"], 7 | ["rect", [0, 0, 1280, 720]], 8 | ["roundRect", [58, 25, 564, 317, 50, 50, 50, 50]], 9 | ["roundRect", [658, 25, 564, 317, 50, 50, 50, 50]], 10 | ["roundRect", [358, 378, 564, 317, 50, 50, 50, 50]], 11 | ["clip", ["evenodd"]], 12 | ["save"], 13 | ["save"], 14 | ["save"], 15 | ["save"], 16 | ["save"], 17 | ["globalAlpha", 1], 18 | [ 19 | "drawImage", 20 | [ 21 | { 22 | "type": "defaultAsset", 23 | "id": "landscape-j3CjZYckM88-unsplash.png" 24 | }, 25 | 0, 26 | 0, 27 | 1600, 28 | 1200, 29 | 0, 30 | 0, 31 | 1280, 32 | 720 33 | ] 34 | ], 35 | ["restore"], 36 | ["restore"], 37 | ["restore"], 38 | ["restore"], 39 | ["restore"], 40 | ["restore"] 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /server-render/canvex/example-data/basic-labels.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 1280, 3 | "height": 720, 4 | "commands": [ 5 | ["save"], 6 | ["save"], 7 | ["save"], 8 | ["save"], 9 | ["save"], 10 | ["save"], 11 | ["save"], 12 | ["rect", [0, 537, 622, 350]], 13 | ["clip"], 14 | ["fillStyle", "#ffffff"], 15 | ["font", ["600", "", 20, "Roboto"]], 16 | ["strokeStyle", "rgba(0, 0, 0, 0.9)"], 17 | ["lineWidth", 4], 18 | ["lineJoin", "round"], 19 | ["strokeText", ["Participant 5", 0, 553]], 20 | ["fillText", ["Participant 5", 0, 553]], 21 | ["restore"], 22 | ["restore"], 23 | ["restore"], 24 | ["save"], 25 | ["save"], 26 | ["save"], 27 | ["rect", [658, 537, 622, 350]], 28 | ["clip"], 29 | ["fillStyle", "#ffffff"], 30 | ["font", ["600", "", 20, "Roboto"]], 31 | ["strokeStyle", "rgba(0, 0, 0, 0.9)"], 32 | ["lineWidth", 4], 33 | ["lineJoin", "round"], 34 | ["strokeText", ["Participant 9", 658, 553]], 35 | ["fillText", ["Participant 9", 658, 553]], 36 | ["restore"], 37 | ["restore"], 38 | ["restore"], 39 | ["restore"], 40 | ["restore"], 41 | ["restore"], 42 | ["restore"] 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /server-render/canvex/example-data/basic-lowerthird.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 1280, 3 | "height": 720, 4 | "commands": [ 5 | ["save"], 6 | ["save"], 7 | ["save"], 8 | ["save"], 9 | ["fillStyle", "rgba(50, 70, 255, 0.7)"], 10 | ["fillRect", [0, 482, 1280, 238]], 11 | ["save"], 12 | ["fillStyle", "rgba(255, 250, 200, 0.95)"], 13 | ["font", ["300", "", 50, "Roboto"]], 14 | ["fillText", ["Hello from VCS", 20, 542]], 15 | ["restore"], 16 | ["save"], 17 | [ 18 | "drawImage", 19 | [ 20 | { "type": "defaultAsset", "id": "test_square_320px.png" }, 21 | 1172, 22 | 518, 23 | 72, 24 | 72 25 | ] 26 | ], 27 | ["restore"], 28 | ["restore"], 29 | ["restore"], 30 | ["restore"], 31 | ["restore"] 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /server-render/canvex/init_build_linux.sh: -------------------------------------------------------------------------------- 1 | # Init the build on Linux. 2 | # You only need to run this once, unless global build settings in meson.build are changed. 3 | # 4 | # To do a regular build, just run: 5 | # ninja -C build 6 | # (Also available in VS Code tasks.) 7 | 8 | meson build --native-file meson_linux.ini 9 | ninja -C build 10 | -------------------------------------------------------------------------------- /server-render/canvex/meson_linux.ini: -------------------------------------------------------------------------------- 1 | [binaries] 2 | cpp = 'clang++' 3 | -------------------------------------------------------------------------------- /server-render/canvex/rapidjson/internal/swap.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_ 16 | #define RAPIDJSON_INTERNAL_SWAP_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(__clang__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(c++98-compat) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | //! Custom swap() to avoid dependency on C++ header 29 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. 30 | \note This has the same semantics as std::swap(). 31 | */ 32 | template 33 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { 34 | T tmp = a; 35 | a = b; 36 | b = tmp; 37 | } 38 | 39 | } // namespace internal 40 | RAPIDJSON_NAMESPACE_END 41 | 42 | #if defined(__clang__) 43 | RAPIDJSON_DIAG_POP 44 | #endif 45 | 46 | #endif // RAPIDJSON_INTERNAL_SWAP_H_ 47 | -------------------------------------------------------------------------------- /server-render/canvex/src/canvex_skia_executor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/canvex_c_api.h" 3 | #include "canvas_display_list.h" 4 | #include "canvex_skia_resource_context.h" 5 | #include 6 | 7 | namespace canvex { 8 | 9 | enum RenderFormat { 10 | Rgba, 11 | Bgra, 12 | }; 13 | 14 | bool RenderDisplayListToPNG( 15 | const VCSCanvasDisplayList& dl, 16 | const std::filesystem::path& dstFile, 17 | const std::filesystem::path& resourceDir, 18 | CanvexSkiaResourceContext* skiaResCtx, // optional cache between calls 19 | CanvexExecutionStats* stats // optional stats 20 | ); 21 | 22 | bool RenderDisplayListToRawBuffer( 23 | const VCSCanvasDisplayList& dl, 24 | RenderFormat format, 25 | uint8_t *imageBuffer, 26 | uint32_t w, 27 | uint32_t h, 28 | uint32_t rowBytes, 29 | CanvexAlphaMode alphaMode, 30 | const std::filesystem::path& resourceDir, 31 | CanvexSkiaResourceContext* skiaResCtx, // optional cache between calls 32 | CanvexExecutionStats* stats // optional stats 33 | ); 34 | 35 | } // namespace canvex 36 | -------------------------------------------------------------------------------- /server-render/canvex/src/file_util.cpp: -------------------------------------------------------------------------------- 1 | #include "file_util.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | std::string readTextFile(const std::string& path) { 8 | struct stat sb{}; 9 | std::string str; 10 | 11 | FILE* f = fopen(path.c_str(), "r"); 12 | if (!f) { 13 | throw std::runtime_error("Unable to open file"); 14 | } 15 | 16 | stat(path.c_str(), &sb); 17 | str.resize(sb.st_size); 18 | 19 | const size_t readResult = fread(const_cast(str.data()), sb.st_size, 1, f); 20 | fclose(f); 21 | 22 | if (readResult != 1) { 23 | throw std::runtime_error("Could not read all data from file"); 24 | } 25 | 26 | return str; 27 | } 28 | -------------------------------------------------------------------------------- /server-render/canvex/src/file_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // Read text file in one operation using 'stat' for file size. 5 | // Throws on error. 6 | std::string readTextFile(const std::string& path); 7 | -------------------------------------------------------------------------------- /server-render/canvex/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_upper_case_globals)] 2 | #![allow(non_camel_case_types)] 3 | include!(concat!(env!("OUT_DIR"), "/canvex_bindings.rs")); 4 | -------------------------------------------------------------------------------- /server-render/canvex/src/meson.build: -------------------------------------------------------------------------------- 1 | canvex_lib_sources = files( 2 | 'canvas_display_list.cpp', 3 | 'canvex_c_api.cpp', 4 | 'canvex_skia_context.cpp', 5 | 'canvex_skia_executor.cpp', 6 | 'canvex_skia_resource_context.cpp', 7 | 'file_util.cpp', 8 | 'style_util.cpp', 9 | ) 10 | 11 | canvex_standalone_demo_sources = files( 12 | 'canvex_demo_main.cpp', 13 | ) 14 | 15 | canvex_render_frame_util_sources = files( 16 | 'canvex_render_frame_main.c', 17 | ) 18 | -------------------------------------------------------------------------------- /server-render/canvex/src/skia_includes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SK_RELEASE 1 4 | #include "include/core/SkBitmap.h" 5 | #include "include/core/SkCanvas.h" 6 | #include "include/core/SkColor.h" 7 | #include "include/core/SkData.h" 8 | #include "include/core/SkEncodedImageFormat.h" 9 | #include "include/core/SkImage.h" 10 | #include "include/core/SkPath.h" 11 | #include "include/core/SkTextBlob.h" 12 | #include "include/core/SkTypeface.h" 13 | -------------------------------------------------------------------------------- /server-render/canvex/src/style_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | bool getRGBAColorFromCSSStyleString(const std::string& str, float* outColor); 5 | -------------------------------------------------------------------------------- /server-render/canvex/src/time_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | static inline double getMonotonicTime() noexcept { 5 | auto now = std::chrono::steady_clock::now(); 6 | int64_t now_usec = std::chrono::time_point_cast(now) 7 | .time_since_epoch().count(); 8 | return now_usec / 1.0e6; 9 | } 10 | -------------------------------------------------------------------------------- /server-render/test/.gitignore: -------------------------------------------------------------------------------- 1 | output/** 2 | -------------------------------------------------------------------------------- /server-render/test/canvex-render-frame-util.js: -------------------------------------------------------------------------------- 1 | import { execFileSync } from 'child_process'; 2 | import * as fs from 'fs'; 3 | import * as Path from 'path'; 4 | 5 | /* 6 | Utility that calls canvex_render_frame with the image size parsed from the input canvex JSON. 7 | */ 8 | 9 | let argn = 2; 10 | const canvexPath = process.argv[argn++]; 11 | const jsonPath = process.argv[argn++]; 12 | const outputPath = process.argv[argn++]; 13 | 14 | if (!canvexPath || !jsonPath || !outputPath) { 15 | console.error( 16 | '** Invalid arguments: expected 1) canvex dir, 2) json path, 3) output path' 17 | ); 18 | process.exit(1); 19 | } 20 | 21 | const json = fs.readFileSync(jsonPath, { encoding: 'utf8' }); 22 | const obj = JSON.parse(json); 23 | const w = obj.width; 24 | const h = obj.height; 25 | 26 | if (!w || !h || w < 1 || h < 1) { 27 | console.error( 28 | "** Invalid JSON input: doesn't have valid width/height: ", 29 | jsonPath 30 | ); 31 | process.exit(2); 32 | } 33 | 34 | const binPath = Path.resolve(canvexPath, 'build', 'canvex_render_frame'); 35 | 36 | execFileSync( 37 | binPath, 38 | [w, h, Path.resolve(jsonPath), Path.resolve(outputPath)], 39 | { 40 | cwd: canvexPath, 41 | } 42 | ); 43 | -------------------------------------------------------------------------------- /server-render/test/run_all_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | scenarios="scenarios/*" 4 | 5 | failed=false 6 | for scenarioName in $scenarios 7 | do 8 | ./run_scenario.sh $(basename "$scenarioName") 9 | if [ $? -ne 0 ]; then 10 | echo "** " 11 | echo "** Test failed for scenario: $scenarioName" 12 | echo "** Will continue with other tests." 13 | echo "** " 14 | failed=true 15 | fi 16 | done 17 | 18 | if [ $failed = true ]; then 19 | echo "** Couldn't complete all test scenarios. See log for detail of failed test(s)." 20 | exit 1 21 | fi 22 | echo "All test scenarios passed." 23 | -------------------------------------------------------------------------------- /server-render/test/run_clean_and_copy_to_repo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ $# -ne 1 ]]; then 4 | echo "First argument must be scenario name." 5 | exit 2 6 | fi 7 | 8 | name=$1 9 | 10 | echo "This will run scenario '$name' and copy the output into the repo," 11 | echo "replacing any previous files." 12 | echo "After running this script, the scenario will pass because the" 13 | echo "golden frames have been replaced." 14 | echo "So, you should make sure to inspect the golden frames in the repo" 15 | echo "and make sure they look right before you commit these changes." 16 | echo 17 | read -p "Are you sure? " -n 1 -r 18 | echo 19 | if [[ ! $REPLY =~ ^[Yy]$ ]]; then 20 | exit 1 21 | fi 22 | 23 | # clean the output folder first 24 | outputDir="output/$name" 25 | rm -rf "$outputDir" 26 | 27 | ./run_scenario.sh "$name" > /dev/null 28 | 29 | # copy new output to repo 30 | dstDir="scenarios/$name" 31 | cp "$outputDir"/*.png "$dstDir" 32 | cp "$outputDir"/*_videolayers.json "$dstDir" 33 | cp "$outputDir"/*_fgdisplaylist.canvex.json "$dstDir" 34 | -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_0_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[58,25,564,317]],["rect",[658,25,564,317]],["rect",[58,378,564,317]],["rect",[658,378,564,317]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_0_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":58,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":58,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":658,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_10_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[0,0,1024,720]],["rect",[1034,10,236,129]],["rect",[1034,152,236,129]],["rect",[1034,295,236,129]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_10_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_10_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_10_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_10_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_10_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_10_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_10_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":0,"y":0,"w":1024,"h":720},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":1034,"y":10,"w":236,"h":129},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":1034,"y":152,"w":236,"h":129},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":1034,"y":295,"w":236,"h":129},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_10_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_10_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_10_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_10_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_10_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_10_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_20_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[0,0,193,140]],["rect",[0,145,193,140]],["rect",[0,290,193,140]],["rect",[192,0,1088,720]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_20_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_20_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_20_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_20_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_20_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_20_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_20_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":0,"y":0,"w":193,"h":140},"attrs":{"scaleMode":"fit","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":0,"y":145,"w":193,"h":140},"attrs":{"scaleMode":"fit","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":0,"y":290,"w":193,"h":140},"attrs":{"scaleMode":"fit","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":192,"y":0,"w":1088,"h":720},"attrs":{"scaleMode":"fit","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_20_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_20_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_20_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_20_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_20_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_20_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_30_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[0,0,1280,720]],["rect",[1010,30,240,240]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_30_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_30_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_30_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_30_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_30_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_30_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_30_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":0,"y":0,"w":1280,"h":720},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":1010,"y":30,"w":240,"h":240},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_30_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_30_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_30_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_30_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_30_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_30_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_40_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[0,0,1280,720]],["rect",[40,340,408,340]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_40_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_40_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_40_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_40_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_40_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_40_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_40_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":1,"frame":{"x":0,"y":0,"w":1280,"h":720},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":0,"frame":{"x":40,"y":340,"w":408,"h":340},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_40_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_40_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_40_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_40_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_40_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_40_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_50_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[0,0,640,720]],["rect",[640,0,640,720]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_50_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_50_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_50_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_50_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_50_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_50_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_50_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":2,"frame":{"x":0,"y":0,"w":640,"h":720},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":640,"y":0,"w":640,"h":720},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_50_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_50_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_50_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_50_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_50_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_50_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_60_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[0,0,1280,720]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_60_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_60_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_60_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_60_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_60_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_60_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_60_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":2,"frame":{"x":0,"y":0,"w":1280,"h":720},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_60_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_60_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_60_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_60_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_60_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_60_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_70_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[0,0,1280,720]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_70_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_70_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_70_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_70_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_70_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_70_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_70_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":3,"frame":{"x":0,"y":0,"w":1280,"h":720},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_70_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_70_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_70_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_70_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_70_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_70_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_80_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[86,25,250,141]],["rect",[372,25,250,141]],["rect",[658,25,250,141]],["rect",[943,25,250,141]],["rect",[86,201,250,141]],["rect",[372,201,250,141]],["rect",[658,201,250,141]],["rect",[943,201,250,141]],["rect",[86,378,250,141]],["rect",[372,378,250,141]],["rect",[658,378,250,141]],["rect",[943,378,250,141]],["rect",[515,554,250,141]],["clip",["evenodd"]],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_80_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_80_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_80_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_80_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_80_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_80_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_80_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":3,"frame":{"x":86,"y":25,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":4,"frame":{"x":372,"y":25,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":5,"frame":{"x":658,"y":25,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":6,"frame":{"x":943,"y":25,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":7,"frame":{"x":86,"y":201,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":8,"frame":{"x":372,"y":201,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":9,"frame":{"x":658,"y":201,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":10,"frame":{"x":943,"y":201,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":11,"frame":{"x":86,"y":378,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":12,"frame":{"x":372,"y":378,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":13,"frame":{"x":658,"y":378,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":14,"frame":{"x":943,"y":378,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":15,"frame":{"x":515,"y":554,"w":250,"h":141},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_80_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_80_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_80_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_80_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-modes/vcs-output_80_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-modes/vcs-output_80_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_10_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[58,25,564,317]],["rect",[658,25,564,317]],["rect",[58,378,564,317]],["rect",[658,378,564,317]],["clip",["evenodd"]],["restore"],["save"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[1027,20,233,90,24,24,24,24]],["closePath"],["clip",[]],["save"],["globalAlpha",0],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_10_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_10_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_10_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_10_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_10_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_10_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_10_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":58,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":58,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":658,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_10_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_10_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_10_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_10_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_10_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_10_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_110_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[58,25,564,317]],["rect",[658,25,564,317]],["rect",[58,378,564,317]],["rect",[658,378,564,317]],["clip",["evenodd"]],["restore"],["save"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[1027,20,233,90,24,24,24,24]],["closePath"],["clip",[]],["save"],["globalAlpha",0.3333333333333339],["fillStyle","rgba(215, 50, 110, 0.8)"],["fillRect",[1027,20,233,90]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",2],["save"],["beginPath"],["roundRect",[1027,20,233,90,24,24,24,24]],["closePath"],["stroke"],["restore"],["save"],["save"],["save"],["save"],["fillStyle","#ffffff"],["font",["400","",33,"Bitter"]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",4],["lineJoin","round"],["strokeText",["First toast",1067,75]],["fillText",["First toast",1067,75]],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_110_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_110_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_110_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_110_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_110_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_110_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_110_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":58,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":58,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":658,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_110_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_110_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_110_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_110_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_110_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_110_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_130_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[58,25,564,317]],["rect",[658,25,564,317]],["rect",[58,378,564,317]],["rect",[658,378,564,317]],["clip",["evenodd"]],["restore"],["save"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[781,20,479,90,24,24,24,24]],["closePath"],["clip",[]],["save"],["globalAlpha",0.05555555555555536],["fillStyle","rgba(215, 50, 110, 0.8)"],["fillRect",[781,20,479,90]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",2],["save"],["beginPath"],["roundRect",[781,20,479,90,24,24,24,24]],["closePath"],["stroke"],["restore"],["save"],["save"],["save"],["save"],["fillStyle","#ffffff"],["font",["400","",33,"Bitter"]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",4],["lineJoin","round"],["strokeText",["Second toast lorem ipsum",821,75]],["fillText",["Second toast lorem ipsum",821,75]],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_130_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_130_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_130_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_130_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_130_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_130_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_130_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":58,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":58,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":658,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_130_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_130_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_130_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_130_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_130_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_130_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_180_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[58,25,564,317]],["rect",[658,25,564,317]],["rect",[58,378,564,317]],["rect",[658,378,564,317]],["clip",["evenodd"]],["restore"],["save"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[781,20,479,90,24,24,24,24]],["closePath"],["clip",[]],["save"],["globalAlpha",1],["fillStyle","rgba(215, 50, 110, 0.8)"],["fillRect",[781,20,479,90]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",2],["save"],["beginPath"],["roundRect",[781,20,479,90,24,24,24,24]],["closePath"],["stroke"],["restore"],["save"],["save"],["save"],["save"],["fillStyle","#ffffff"],["font",["400","",33,"Bitter"]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",4],["lineJoin","round"],["strokeText",["Second toast lorem ipsum",821,75]],["fillText",["Second toast lorem ipsum",821,75]],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_180_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_180_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_180_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_180_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_180_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":58,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":58,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":658,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_180_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_180_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_180_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_180_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_20_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[58,25,564,317]],["rect",[658,25,564,317]],["rect",[58,378,564,317]],["rect",[658,378,564,317]],["clip",["evenodd"]],["restore"],["save"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[1027,20,233,90,24,24,24,24]],["closePath"],["clip",[]],["save"],["globalAlpha",0.5555555555555556],["fillStyle","rgba(215, 50, 110, 0.8)"],["fillRect",[1027,20,233,90]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",2],["save"],["beginPath"],["roundRect",[1027,20,233,90,24,24,24,24]],["closePath"],["stroke"],["restore"],["save"],["save"],["save"],["save"],["fillStyle","#ffffff"],["font",["400","",33,"Bitter"]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",4],["lineJoin","round"],["strokeText",["First toast",1067,75]],["fillText",["First toast",1067,75]],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_20_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_20_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_20_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_20_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_20_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_20_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_20_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":58,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":58,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":658,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_20_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_20_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_20_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_20_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_20_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_20_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_60_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["rect",[58,25,564,317]],["rect",[658,25,564,317]],["rect",[58,378,564,317]],["rect",[658,378,564,317]],["clip",["evenodd"]],["restore"],["save"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[1027,20,233,90,24,24,24,24]],["closePath"],["clip",[]],["save"],["globalAlpha",1],["fillStyle","rgba(215, 50, 110, 0.8)"],["fillRect",[1027,20,233,90]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",2],["save"],["beginPath"],["roundRect",[1027,20,233,90,24,24,24,24]],["closePath"],["stroke"],["restore"],["save"],["save"],["save"],["save"],["fillStyle","#ffffff"],["font",["400","",33,"Bitter"]],["strokeStyle","rgba(0, 0, 30, 0.44)"],["lineWidth",4],["lineJoin","round"],["strokeText",["First toast",1067,75]],["fillText",["First toast",1067,75]],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_60_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_60_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_60_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_60_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_60_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":58,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":25,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":58,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":658,"y":378,"w":564,"h":317},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_60_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_60_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/baseline-toast/vcs-output_60_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/baseline-toast/vcs-output_60_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/graphics-test/vcs-output_49_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/graphics-test/vcs-output_49_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/graphics-test/vcs-output_49_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/graphics-test/vcs-output_49_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/graphics-test/vcs-output_49_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/graphics-test/vcs-output_49_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/graphics-test/vcs-output_49_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":0,"y":0,"w":1280,"h":720},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/graphics-test/vcs-output_49_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/graphics-test/vcs-output_49_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/graphics-test/vcs-output_49_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/graphics-test/vcs-output_49_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/graphics-test/vcs-output_49_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/graphics-test/vcs-output_49_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/graphics-test/vcs-scenario.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | activeVideoInputSlots: [true], 3 | params: {}, 4 | }; 5 | 6 | export default { 7 | compositionId: 'example:graphics-test', 8 | durationInFrames: 50, 9 | outputFrames: [49], 10 | initialState: { ...state }, 11 | }; 12 | -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-output_0_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1920,"height":1080,"commands":[["save"],["beginPath"],["rect",[0,0,1920,1080]],["rect",[54,293,879,494]],["rect",[987,293,879,494]],["clip",["evenodd"]],["save"],["save"],["save"],["fillStyle","rgba(90, 0, 0, 1)"],["fillRect",[0,0,1920,1080]],["restore"],["restore"],["restore"],["restore"],["save"],["save"],["save"],["save"],["fillStyle","rgba(50, 70, 255, 0.7)"],["fillRect",[0,724,1920,356]],["save"],["save"],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",75,"Roboto"]],["fillText",["Hello from test @ landscape 1080",785,1031]],["restore"],["restore"],["save"],["drawImage",[{"type":"defaultAsset","id":"test_square_320px.png"},1758,778,108,108]],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-landscape-1080/vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-landscape-1080/vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-landscape-1080/vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-output_0_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":54,"y":293,"w":879,"h":494},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":987,"y":293,"w":879,"h":494},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-landscape-1080/vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-landscape-1080/vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-landscape-1080/vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-landscape-1080/vcs-scenario.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | activeVideoInputSlots: [true, true], 3 | params: { 4 | showGraphics: true, 5 | demoText: 'Hello from test @ landscape 1080', 6 | }, 7 | }; 8 | 9 | const durationInFrames = 5; 10 | 11 | const outputFrames = [0]; 12 | 13 | const outputSize = { w: 1920, h: 1080 }; 14 | 15 | function frameWillRenderCb(frameIdx) { 16 | let didUpdate = false; 17 | 18 | return didUpdate ? { ...state } : null; 19 | } 20 | 21 | export default { 22 | compositionId: 'example:hello', 23 | durationInFrames, 24 | outputFrames, 25 | outputSize, 26 | initialState: { ...state }, 27 | frameWillRenderCb, 28 | }; 29 | -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-output_0_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":720,"height":1280,"commands":[["save"],["beginPath"],["rect",[0,0,720,1280]],["rect",[26,354,322,572]],["rect",[373,354,322,572]],["clip",["evenodd"]],["save"],["save"],["save"],["fillStyle","rgba(90, 0, 0, 1)"],["fillRect",[0,0,720,1280]],["restore"],["restore"],["restore"],["restore"],["save"],["save"],["save"],["save"],["fillStyle","rgba(50, 70, 255, 0.7)"],["fillRect",[0,858,720,422]],["save"],["save"],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",50,"Roboto"]],["fillText",["Hello from test @ portrait ",-20,1181]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",50,"Roboto"]],["fillText",["720x1280",-20,1240]],["restore"],["restore"],["save"],["drawImage",[{"type":"defaultAsset","id":"test_square_320px.png"},528,922,128,128]],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-portrait/vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-portrait/vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-portrait/vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-output_0_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":26,"y":354,"w":322,"h":572},"attrs":{"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":373,"y":354,"w":322,"h":572},"attrs":{"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-portrait/vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-portrait/vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello-portrait/vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello-portrait/vcs-scenario.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | activeVideoInputSlots: [true, true], 3 | params: { 4 | showGraphics: true, 5 | demoText: 'Hello from test @ portrait 720x1280', 6 | }, 7 | }; 8 | 9 | const durationInFrames = 5; 10 | 11 | const outputFrames = [0]; 12 | 13 | const outputSize = { w: 720, h: 1280 }; 14 | 15 | function frameWillRenderCb(frameIdx) { 16 | let didUpdate = false; 17 | 18 | return didUpdate ? { ...state } : null; 19 | } 20 | 21 | export default { 22 | compositionId: 'example:hello', 23 | durationInFrames, 24 | outputFrames, 25 | outputSize, 26 | initialState: { ...state }, 27 | frameWillRenderCb, 28 | }; 29 | -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_0_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["roundRect",[36,195,586,330,25,25,25,25]],["roundRect",[658,195,586,330,25,25,25,25]],["clip",["evenodd"]],["save"],["save"],["save"],["fillStyle","rgba(90, 0, 0, 1)"],["fillRect",[0,0,1280,720]],["restore"],["restore"],["restore"],["restore"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[20,476,1240,224,25,25,25,25]],["closePath"],["clip",[]],["fillStyle","rgba(50, 70, 255, 0.7)"],["fillRect",[20,476,1240,224]],["restore"],["save"],["save"],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",50,"Roboto"]],["fillText",["Hello from test scenario",715,660]],["restore"],["restore"],["save"],["drawImage",[{"type":"defaultAsset","id":"test_square_320px.png"},1152,512,72,72]],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_0_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_0_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_0_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_0_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":36,"y":195,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":195,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_0_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_0_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_0_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_180_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["roundRect",[36,12,586,330,25,25,25,25]],["roundRect",[658,12,586,330,25,25,25,25]],["roundRect",[36,378,586,330,25,25,25,25]],["clip",["evenodd"]],["save"],["save"],["save"],["fillStyle","rgba(90, 0, 0, 1)"],["fillRect",[0,0,1280,720]],["restore"],["restore"],["restore"],["restore"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[20,476,1240,224,25,25,25,25]],["closePath"],["clip",[]],["fillStyle","rgba(50, 70, 255, 0.7)"],["fillRect",[20,476,1240,224]],["restore"],["save"],["save"],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",50,"Roboto"]],["fillText",["Emoji: ",762,656]],["fillStyle","#ffffff"],["fillText_emoji",["😭",908,651,42,42]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",50,"Roboto"]],["fillText",[",",958,656]],["fillStyle","#ffffff"],["fillText_emoji",["😎",968,651,42,42]],["fillStyle","#ffffff"],["fillText_emoji",["🥶",1018,651,42,42]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",50,"Roboto"]],["fillText",[",",1068,656]],["fillStyle","#ffffff"],["fillText_emoji",["🎱",1077,651,42,42]],["fillStyle","#ffffff"],["fillText_emoji",["📱",1127,651,42,42]],["fillStyle","#ffffff"],["fillText_emoji",["💚",1177,651,42,42]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",50,"Roboto"]],["fillText",[".",1227,656]],["restore"],["restore"],["save"],["drawImage",[{"type":"defaultAsset","id":"test_square_320px.png"},1116,512,108,108]],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_180_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_180_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_180_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_180_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_180_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_180_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_180_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":36,"y":12,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":12,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":36,"y":378,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_180_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_180_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_180_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_180_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_180_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_180_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_190_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["roundRect",[36,12,586,330,25,25,25,25]],["roundRect",[658,12,586,330,25,25,25,25]],["roundRect",[36,378,586,330,25,25,25,25]],["roundRect",[658,378,586,330,25,25,25,25]],["clip",["evenodd"]],["save"],["save"],["save"],["fillStyle","rgba(90, 0, 0, 1)"],["fillRect",[0,0,1280,720]],["restore"],["restore"],["restore"],["restore"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[1012,20,248,680,25,25,25,25]],["closePath"],["clip",[]],["fillStyle","rgba(50, 70, 255, 0.7)"],["fillRect",[1012,20,248,680]],["restore"],["save"],["save"],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",["Emoji: ",896,663]],["fillStyle","#ffffff"],["fillText_emoji",["😭",1001,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[",",1037,663]],["fillStyle","#ffffff"],["fillText_emoji",["😎",1044,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["🥶",1080,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[",",1116,663]],["fillStyle","#ffffff"],["fillText_emoji",["🎱",1123,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["📱",1159,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["💚",1195,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[".",1231,663]],["restore"],["restore"],["save"],["drawImage",[{"type":"defaultAsset","id":"test_square_320px.png"},1116,56,108,108]],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_190_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_190_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_190_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_190_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_190_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_190_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_190_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":36,"y":12,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":658,"y":12,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":36,"y":378,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":658,"y":378,"w":586,"h":330},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_190_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_190_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_190_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_190_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_190_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_190_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_200_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["roundRect",[36,129,379,213,25,25,25,25]],["roundRect",[451,129,379,213,25,25,25,25]],["roundRect",[865,129,379,213,25,25,25,25]],["roundRect",[36,378,379,213,25,25,25,25]],["roundRect",[451,378,379,213,25,25,25,25]],["clip",["evenodd"]],["save"],["save"],["save"],["fillStyle","rgba(90, 0, 0, 1)"],["fillRect",[0,0,1280,720]],["restore"],["restore"],["restore"],["restore"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[1012,20,248,680,25,25,25,25]],["closePath"],["clip",[]],["fillStyle","rgba(50, 70, 255, 0.7)"],["fillRect",[1012,20,248,680]],["restore"],["save"],["save"],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",["Emoji: ",896,663]],["fillStyle","#ffffff"],["fillText_emoji",["😭",1001,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[",",1037,663]],["fillStyle","#ffffff"],["fillText_emoji",["😎",1044,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["🥶",1080,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[",",1116,663]],["fillStyle","#ffffff"],["fillText_emoji",["🎱",1123,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["📱",1159,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["💚",1195,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[".",1231,663]],["restore"],["restore"],["save"],["drawImage",[{"type":"defaultAsset","id":"test_square_320px.png"},1116,56,108,108]],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_200_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_200_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_200_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_200_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_200_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":36,"y":129,"w":379,"h":213},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":1,"frame":{"x":451,"y":129,"w":379,"h":213},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":865,"y":129,"w":379,"h":213},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":36,"y":378,"w":379,"h":213},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":4,"frame":{"x":451,"y":378,"w":379,"h":213},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_200_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_200_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_200_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_200_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_340_fgdisplaylist.canvex.json: -------------------------------------------------------------------------------- 1 | {"width":1280,"height":720,"commands":[["save"],["beginPath"],["rect",[0,0,1280,720]],["roundRect",[36,177,293,165,25,25,25,25]],["roundRect",[365,177,293,165,25,25,25,25]],["roundRect",[695,177,293,165,25,25,25,25]],["roundRect",[36,378,293,165,25,25,25,25]],["roundRect",[365,378,293,165,25,25,25,25]],["clip",["evenodd"]],["save"],["save"],["save"],["fillStyle","rgba(90, 0, 0, 1)"],["fillRect",[0,0,1280,720]],["restore"],["restore"],["restore"],["restore"],["save"],["save"],["save"],["save"],["save"],["beginPath"],["roundRect",[1012,20,248,680,25,25,25,25]],["closePath"],["clip",[]],["fillStyle","rgba(50, 70, 255, 0.7)"],["fillRect",[1012,20,248,680]],["restore"],["save"],["save"],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",["Emoji: ",896,663]],["fillStyle","#ffffff"],["fillText_emoji",["😭",1001,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[",",1037,663]],["fillStyle","#ffffff"],["fillText_emoji",["😎",1044,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["🥶",1080,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[",",1116,663]],["fillStyle","#ffffff"],["fillText_emoji",["🎱",1123,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["📱",1159,659,30,30]],["fillStyle","#ffffff"],["fillText_emoji",["💚",1195,659,30,30]],["fillStyle","rgba(255, 250, 200, 0.95)"],["font",["300","",36,"Roboto"]],["fillText",[".",1231,663]],["restore"],["restore"],["save"],["drawImage",[{"type":"defaultAsset","id":"test_square_320px.png"},1048,484,180,180]],["restore"],["restore"],["restore"],["restore"],["restore"]]} -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_340_fgdisplaylist.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_340_fgdisplaylist.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_340_fgdisplaylist.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_340_fgdisplaylist.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_340_fgdisplaylist.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_340_fgdisplaylist.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_340_videolayers.json: -------------------------------------------------------------------------------- 1 | [{"type":"video","id":0,"frame":{"x":36,"y":177,"w":293,"h":165},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":2,"frame":{"x":365,"y":177,"w":293,"h":165},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":3,"frame":{"x":695,"y":177,"w":293,"h":165},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":4,"frame":{"x":36,"y":378,"w":293,"h":165},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}},{"type":"video","id":5,"frame":{"x":365,"y":378,"w":293,"h":165},"attrs":{"cornerRadiusPx":25,"scaleMode":"fill","zoomFactor":1}}] -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_340_videolayerspreview.canvex.linux_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_340_videolayerspreview.canvex.linux_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_340_videolayerspreview.canvex.macos_skia_arm64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_340_videolayerspreview.canvex.macos_skia_arm64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-output_340_videolayerspreview.canvex.macos_skia_x86_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/scenarios/hello/vcs-output_340_videolayerspreview.canvex.macos_skia_x86_64.png -------------------------------------------------------------------------------- /server-render/test/scenarios/hello/vcs-scenario.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | activeVideoInputSlots: [true, true], 3 | params: { 4 | showGraphics: true, 5 | useRoundedCornersStyle: true, 6 | demoText: 'Hello from test scenario', 7 | }, 8 | }; 9 | 10 | const durationInFrames = 350; 11 | 12 | const outputFrames = [0, 180, 190, 200, 340]; 13 | 14 | function frameWillRenderCb(frameIdx) { 15 | let didUpdate = false; 16 | if (frameIdx === outputFrames[1]) { 17 | state.activeVideoInputSlots.push(true); 18 | 19 | // change text to show some emoji 20 | state.params.demoText = 'Emoji: 😭,😎🥶,🎱📱💚.'; 21 | 22 | didUpdate = true; 23 | } else if (frameIdx === outputFrames[2]) { 24 | state.activeVideoInputSlots.push(true); 25 | state.params.graphicsOnSide = true; 26 | didUpdate = true; 27 | } else if (frameIdx === outputFrames[3]) { 28 | state.activeVideoInputSlots.push(true); 29 | didUpdate = true; 30 | } else if (frameIdx === outputFrames[4]) { 31 | state.activeVideoInputSlots.push(true); 32 | 33 | state.activeVideoInputSlots[1] = false; // remove an existing participant 34 | 35 | state.params.fitGridToGraphics = true; 36 | didUpdate = true; 37 | } 38 | 39 | return didUpdate ? { ...state } : null; 40 | } 41 | 42 | export default { 43 | compositionId: 'example:hello', 44 | durationInFrames, 45 | outputFrames, 46 | initialState: { ...state }, 47 | frameWillRenderCb, 48 | }; 49 | -------------------------------------------------------------------------------- /server-render/test/vcsrender/expected_basetest_render_yuv/vcsrenderout_0100.linux_skia_x86_64.yuv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/vcsrender/expected_basetest_render_yuv/vcsrenderout_0100.linux_skia_x86_64.yuv -------------------------------------------------------------------------------- /server-render/test/vcsrender/expected_basetest_render_yuv/vcsrenderout_0100.macos_skia_arm64.yuv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/vcsrender/expected_basetest_render_yuv/vcsrenderout_0100.macos_skia_arm64.yuv -------------------------------------------------------------------------------- /server-render/test/vcsrender/expected_basetest_render_yuv/vcsrenderout_0200.linux_skia_x86_64.yuv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/vcsrender/expected_basetest_render_yuv/vcsrenderout_0200.linux_skia_x86_64.yuv -------------------------------------------------------------------------------- /server-render/test/vcsrender/expected_basetest_render_yuv/vcsrenderout_0200.macos_skia_arm64.yuv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/test/vcsrender/expected_basetest_render_yuv/vcsrenderout_0200.macos_skia_arm64.yuv -------------------------------------------------------------------------------- /server-render/vcscut/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["eslint:recommended"], 4 | "env": { 5 | "node": true, 6 | "es2020": true 7 | }, 8 | "parserOptions": { 9 | "ecmaVersion": "latest", 10 | "sourceType": "module", 11 | "ecmaFeatures": { 12 | "jsx": false 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /server-render/vcscut/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /dist 3 | /cut-tmp 4 | /example-data/sources 5 | -------------------------------------------------------------------------------- /server-render/vcscut/ffexec.js: -------------------------------------------------------------------------------- 1 | import * as fs from "node:fs"; 2 | import * as Path from "node:path"; 3 | import * as childProcess from "node:child_process"; 4 | 5 | // this could be configurable 6 | const g_stderrTempFilePrefix = "cut_ffmpegout_"; 7 | 8 | export async function runFfmpegCommandAsync(contextId, args) { 9 | if (!Array.isArray(args)) { 10 | throw new Error("Invalid args for ffmpeg"); 11 | } 12 | if (!args.includes("-y")) { 13 | // answer yes to any interactive questions 14 | args = ["-y"].concat(args); 15 | } 16 | 17 | console.log("cmd: ffmpeg", args.join(" ")); 18 | 19 | const stderrOutPath = Path.resolve( 20 | "/tmp", 21 | `${g_stderrTempFilePrefix}${contextId}.txt` 22 | ); 23 | try { 24 | fs.rmSync(stderrOutPath); 25 | } catch (e) {} 26 | 27 | const child = childProcess.spawn("ffmpeg", args, { 28 | // ffmpeg writes log output to stderr but it lets the output buffer fill up, 29 | // so the default of a pipe doesn't work. it will hang our process. 30 | // write the output to a tmp file instead 31 | stdio: ["pipe", "pipe", fs.openSync(stderrOutPath, "w")], 32 | }); 33 | child.on("error", (err) => { 34 | throw new Error(`ffmpeg child error: ${err.message}`); 35 | }); 36 | const exitCode = await new Promise((resolve, _reject) => { 37 | child.on("close", resolve); 38 | }); 39 | if (exitCode) { 40 | throw new Error( 41 | `ffmpeg subprocess exited with ${exitCode}, log at: ${stderrOutPath}` 42 | ); 43 | } 44 | 45 | return true; 46 | } 47 | -------------------------------------------------------------------------------- /server-render/vcscut/ffinput.js: -------------------------------------------------------------------------------- 1 | import { runFfmpegCommandAsync } from './ffexec.js'; 2 | 3 | export async function extractYuvSeqAsync(id, src, dst, start, duration) { 4 | const args = [ 5 | '-ss', 6 | start, 7 | '-t', 8 | duration, 9 | '-i', 10 | src, 11 | '-pix_fmt', 12 | 'yuv420p', 13 | '-f', 14 | 'segment', 15 | '-segment_time', 16 | '0.01', 17 | dst, 18 | ]; 19 | return runFfmpegCommandAsync(`extractYuvVideo_${id}`, args); 20 | } 21 | 22 | export async function extractWavAudioAsync(id, src, dst, start, duration) { 23 | const args = [ 24 | '-ss', 25 | start, 26 | '-t', 27 | duration, 28 | '-i', 29 | src, 30 | '-acodec', 31 | 'pcm_s16le', 32 | '-ar', 33 | '44100', 34 | '-ac', 35 | '2', 36 | dst, 37 | ]; 38 | return runFfmpegCommandAsync(`extractWavAudio_${id}`, args); 39 | } 40 | -------------------------------------------------------------------------------- /server-render/vcscut/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@daily-co/vcs-cut", 3 | "version": "0.1.0", 4 | "author": "Daily (https://daily.co)", 5 | "license": "BSD-2-Clause", 6 | "type": "module", 7 | "engines": { 8 | "node": ">=18.19.0" 9 | }, 10 | "main": "cut.js" 11 | } 12 | -------------------------------------------------------------------------------- /server-render/vcscut/timeutil.js: -------------------------------------------------------------------------------- 1 | export function parseClipTime(tc) { 2 | let t; 3 | if (typeof tc === 'string') { 4 | let idx; 5 | if ((idx = tc.indexOf(':')) !== -1) { 6 | // TODO: support also this format HH:MM:SS.MILLI 7 | throw new Error('Timecode format not yet supported: ' + tc); 8 | } 9 | t = parseFloat(tc); 10 | } else if (typeof tc === 'number') { 11 | t = tc; 12 | } else { 13 | throw new Error('Invalide type for timecode value: ' + typeof tc); 14 | } 15 | if (!Number.isFinite(t)) { 16 | throw new Error('Invalid timecode, number not valid: ' + tc); 17 | } 18 | return t; 19 | } 20 | -------------------------------------------------------------------------------- /server-render/vcsrender/.gitignore: -------------------------------------------------------------------------------- 1 | build/** 2 | target/** 3 | example-data/temp/** 4 | .vscode/** 5 | -------------------------------------------------------------------------------- /server-render/vcsrender/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vcsrender-sys" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | canvex-sys = { path = "../canvex" } 8 | 9 | [build-dependencies] 10 | bindgen = "0.65.1" 11 | pkg-config = "0.3.16" 12 | cc = "1.0" 13 | 14 | [lib] 15 | name = "vcsrender" 16 | -------------------------------------------------------------------------------- /server-render/vcsrender/convert_movie_to_yuvseq.sh: -------------------------------------------------------------------------------- 1 | infile=$1 2 | if [ -z "$infile" ]; then 3 | echo "Error: first argument must be input file" 4 | exit 1 5 | fi 6 | 7 | outfileprefix=$2 8 | if [ -z "$outfileprefix" ]; then 9 | echo "Error: second argument must be output directory and file prefix for YUV sequence" 10 | exit 1 11 | fi 12 | 13 | duration=$3 14 | # duration must be in ffmpeg acceptable timecode, e.g. "00:30" for 30 seconds 15 | 16 | set -e 17 | 18 | outdir="$(dirname "$outfileprefix")" 19 | 20 | mkdir -p "$outdir" 21 | 22 | ffargs=( "-i" "${infile}" \ 23 | "-pix_fmt" "yuv420p" "-f" "segment" "-segment_time" "0.01" ) 24 | 25 | [[ -n "$duration" ]] && ffargs+=("-t" "${duration}") 26 | 27 | ffargs+=("${outfileprefix}_%06d.yuv") 28 | 29 | ffmpeg ${ffargs[@]} 30 | -------------------------------------------------------------------------------- /server-render/vcsrender/convert_png_to_yuv.sh: -------------------------------------------------------------------------------- 1 | infile=$1 2 | if [ -z "$infile" ]; then 3 | echo "Error: argument must be input PNG file" 4 | exit 1 5 | fi 6 | 7 | set -e 8 | 9 | if [ -z "$3" ]; then 10 | ext=${infile##*.} 11 | basefilename=$(basename "$infile" $ext) 12 | outfile=$(dirname "$infile")/"$basefilename"yuv 13 | else 14 | outfile=$3 15 | fi 16 | 17 | ffmpeg -y -i "$infile" -pix_fmt yuv420p -update 1 "$outfile" 18 | 19 | echo "\nOutput written to: $outfile" 20 | -------------------------------------------------------------------------------- /server-render/vcsrender/convert_yuv_to_png.sh: -------------------------------------------------------------------------------- 1 | size=$1 2 | if [ -z "$size" ]; then 3 | echo "Error: first argument must be image size (e.g. 1280x720)" 4 | exit 1 5 | fi 6 | 7 | infile=$2 8 | if [ -z "$infile" ]; then 9 | echo "Error: second argument must be input YUV file" 10 | exit 1 11 | fi 12 | 13 | set -e 14 | 15 | if [ -z "$3" ]; then 16 | ext=${infile##*.} 17 | basefilename=$(basename "$infile" $ext) 18 | outfile=$(dirname "$infile")/"$basefilename"png 19 | else 20 | outfile=$3 21 | fi 22 | 23 | ffmpeg -y -f rawvideo -s "$size" -i "$infile" -update 1 "$outfile" 24 | 25 | echo "\nOutput written to: $outfile" 26 | -------------------------------------------------------------------------------- /server-render/vcsrender/convert_yuvseq_to_movie.sh: -------------------------------------------------------------------------------- 1 | indir=$1 2 | if [ -z "$indir" ]; then 3 | echo "Error: argument 1 must be input directory containing YUV sequence" 4 | exit 1 5 | fi 6 | 7 | isize=$2 8 | if [ -z "$isize" ]; then 9 | echo "Error: argument 2 must be input size (e.g. 1280x720)" 10 | exit 1 11 | fi 12 | 13 | fps=$3 14 | if [ -z "$fps" ]; then 15 | echo "Error: argument 3 must be frame rate" 16 | exit 1 17 | fi 18 | 19 | outfile=$4 20 | if [ -z "$outfile" ]; then 21 | echo "Error: argument 4 must be destination movie file" 22 | exit 1 23 | fi 24 | 25 | set -e 26 | 27 | rm -f "$outfile" 28 | 29 | # ffmpeg's input image sequence syntax doesn't work for yuv files. 30 | # instead we need to use cat to feed the raw video frames. 31 | 32 | cat "$indir"/*.yuv | ffmpeg -f rawvideo -s "$isize" -r "$fps" -pix_fmt yuv420p -i - -c:v libx264 "$outfile" 33 | -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/batchtest1/batchtest1_fg_000000.json: -------------------------------------------------------------------------------- 1 | { "width": 1280, "height": 720, "commands": [] } 2 | -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/batchtest1/batchtest1_fg_000030.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 1280, 3 | "height": 720, 4 | "commands": [ 5 | ["save"], 6 | ["save"], 7 | ["save"], 8 | ["save"], 9 | ["fillStyle", "rgba(255, 250, 200, 0.95)"], 10 | ["font", ["400", "", 50, "Roboto"]], 11 | ["strokeStyle", "rgba(0, 0, 0, 0.8)"], 12 | ["lineWidth", 12], 13 | ["lineJoin", "round"], 14 | ["strokeText", ["An example text overlay", 376, 371]], 15 | ["fillText", ["An example text overlay", 376, 371]], 16 | ["restore"], 17 | ["restore"], 18 | ["restore"], 19 | ["restore"] 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/batchtest1/batchtest1_fg_000080.json: -------------------------------------------------------------------------------- 1 | { 2 | "width": 1280, 3 | "height": 720, 4 | "commands": [ 5 | ["save"], 6 | ["save"], 7 | ["save"], 8 | ["save"], 9 | ["fillStyle", "rgba(255, 250, 200, 0.95)"], 10 | ["font", ["400", "", 50, "Roboto"]], 11 | ["strokeStyle", "rgba(0, 0, 0, 0.8)"], 12 | ["lineWidth", 12], 13 | ["lineJoin", "round"], 14 | [ 15 | "strokeText", 16 | ["Lorem ipsum dolor sit amet, consectetur adipiscing elit. ", 24, 341] 17 | ], 18 | [ 19 | "fillText", 20 | ["Lorem ipsum dolor sit amet, consectetur adipiscing elit. ", 24, 341] 21 | ], 22 | ["fillStyle", "rgba(255, 250, 200, 0.95)"], 23 | ["font", ["400", "", 50, "Roboto"]], 24 | ["strokeStyle", "rgba(0, 0, 0, 0.8)"], 25 | ["lineWidth", 12], 26 | ["lineJoin", "round"], 27 | ["strokeText", ["Nam a tellus vitae quam feugiat ullam.", 213, 400]], 28 | ["fillText", ["Nam a tellus vitae quam feugiat ullam.", 213, 400]], 29 | ["restore"], 30 | ["restore"], 31 | ["restore"], 32 | ["restore"] 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/batchtest1/batchtest1_vl_000000.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "video", 4 | "id": 0, 5 | "frame": { "x": 0, "y": 0, "w": 640, "h": 720 }, 6 | "attrs": { "scaleMode": "fill" } 7 | }, 8 | { 9 | "type": "video", 10 | "id": 1, 11 | "frame": { "x": 640, "y": 0, "w": 640, "h": 720 }, 12 | "attrs": { "scaleMode": "fill" } 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/batchtest1/batchtest1_vl_000050.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "video", 4 | "id": 0, 5 | "frame": { "x": 58, "y": 25, "w": 564, "h": 317 }, 6 | "attrs": { "scaleMode": "fill" } 7 | }, 8 | { 9 | "type": "video", 10 | "id": 1, 11 | "frame": { "x": 658, "y": 25, "w": 564, "h": 317 }, 12 | "attrs": { "scaleMode": "fill" } 13 | }, 14 | { 15 | "type": "video", 16 | "id": 2, 17 | "frame": { "x": 358, "y": 378, "w": 564, "h": 317 }, 18 | "attrs": { "scaleMode": "fill" } 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/batchtest1/batchtest1_vl_000080.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "video", 4 | "id": 0, 5 | "frame": { "x": 0, "y": 185, "w": 622, "h": 350 }, 6 | "attrs": { "scaleMode": "fill" } 7 | }, 8 | { 9 | "type": "video", 10 | "id": 1, 11 | "frame": { "x": 658, "y": 185, "w": 622, "h": 350 }, 12 | "attrs": { "scaleMode": "fill" } 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/big-buck-bunny_trim_38s_1m.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/vcsrender/example-data/big-buck-bunny_trim_38s_1m.mp4 -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/pauli_webcam_example_720.m4v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/vcsrender/example-data/pauli_webcam_example_720.m4v -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/testpattern_956x602.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/vcsrender/example-data/testpattern_956x602.png -------------------------------------------------------------------------------- /server-render/vcsrender/example-data/testpattern_956x602.yuv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/vcsrender/example-data/testpattern_956x602.yuv -------------------------------------------------------------------------------- /server-render/vcsrender/libyuv/include/libyuv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_H_ 12 | #define INCLUDE_LIBYUV_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/compare.h" 16 | #include "libyuv/convert.h" 17 | #include "libyuv/convert_argb.h" 18 | #include "libyuv/convert_from.h" 19 | #include "libyuv/convert_from_argb.h" 20 | #include "libyuv/cpu_id.h" 21 | #include "libyuv/mjpeg_decoder.h" 22 | #include "libyuv/planar_functions.h" 23 | #include "libyuv/rotate.h" 24 | #include "libyuv/rotate_argb.h" 25 | #include "libyuv/row.h" 26 | #include "libyuv/scale.h" 27 | #include "libyuv/scale_argb.h" 28 | #include "libyuv/scale_row.h" 29 | #include "libyuv/scale_uv.h" 30 | #include "libyuv/version.h" 31 | #include "libyuv/video_common.h" 32 | 33 | #endif // INCLUDE_LIBYUV_H_ 34 | -------------------------------------------------------------------------------- /server-render/vcsrender/libyuv/include/libyuv/rotate_argb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_ROTATE_ARGB_H_ 12 | #define INCLUDE_LIBYUV_ROTATE_ARGB_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/rotate.h" // For RotationMode. 16 | 17 | #ifdef __cplusplus 18 | namespace libyuv { 19 | extern "C" { 20 | #endif 21 | 22 | // Rotate ARGB frame 23 | LIBYUV_API 24 | int ARGBRotate(const uint8_t* src_argb, 25 | int src_stride_argb, 26 | uint8_t* dst_argb, 27 | int dst_stride_argb, 28 | int src_width, 29 | int src_height, 30 | enum RotationMode mode); 31 | 32 | #ifdef __cplusplus 33 | } // extern "C" 34 | } // namespace libyuv 35 | #endif 36 | 37 | #endif // INCLUDE_LIBYUV_ROTATE_ARGB_H_ 38 | -------------------------------------------------------------------------------- /server-render/vcsrender/libyuv/include/libyuv/scale_rgb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_SCALE_RGB_H_ 12 | #define INCLUDE_LIBYUV_SCALE_RGB_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/scale.h" // For FilterMode 16 | 17 | #ifdef __cplusplus 18 | namespace libyuv { 19 | extern "C" { 20 | #endif 21 | 22 | // RGB can be RAW, RGB24 or YUV24 23 | // RGB scales 24 bit images by converting a row at a time to ARGB 24 | // and using ARGB row functions to scale, then convert to RGB. 25 | // TODO(fbarchard): Allow input/output formats to be specified. 26 | LIBYUV_API 27 | int RGBScale(const uint8_t* src_rgb, 28 | int src_stride_rgb, 29 | int src_width, 30 | int src_height, 31 | uint8_t* dst_rgb, 32 | int dst_stride_rgb, 33 | int dst_width, 34 | int dst_height, 35 | enum FilterMode filtering); 36 | 37 | #ifdef __cplusplus 38 | } // extern "C" 39 | } // namespace libyuv 40 | #endif 41 | 42 | #endif // INCLUDE_LIBYUV_SCALE_UV_H_ 43 | -------------------------------------------------------------------------------- /server-render/vcsrender/libyuv/include/libyuv/scale_uv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_SCALE_UV_H_ 12 | #define INCLUDE_LIBYUV_SCALE_UV_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/scale.h" // For FilterMode 16 | 17 | #ifdef __cplusplus 18 | namespace libyuv { 19 | extern "C" { 20 | #endif 21 | 22 | LIBYUV_API 23 | int UVScale(const uint8_t* src_uv, 24 | int src_stride_uv, 25 | int src_width, 26 | int src_height, 27 | uint8_t* dst_uv, 28 | int dst_stride_uv, 29 | int dst_width, 30 | int dst_height, 31 | enum FilterMode filtering); 32 | 33 | // Scale a 16 bit UV image. 34 | // This function is currently incomplete, it can't handle all cases. 35 | LIBYUV_API 36 | int UVScale_16(const uint16_t* src_uv, 37 | int src_stride_uv, 38 | int src_width, 39 | int src_height, 40 | uint16_t* dst_uv, 41 | int dst_stride_uv, 42 | int dst_width, 43 | int dst_height, 44 | enum FilterMode filtering); 45 | 46 | #ifdef __cplusplus 47 | } // extern "C" 48 | } // namespace libyuv 49 | #endif 50 | 51 | #endif // INCLUDE_LIBYUV_SCALE_UV_H_ 52 | -------------------------------------------------------------------------------- /server-render/vcsrender/libyuv/include/libyuv/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_VERSION_H_ 12 | #define INCLUDE_LIBYUV_VERSION_H_ 13 | 14 | #define LIBYUV_VERSION 1882 15 | 16 | #endif // INCLUDE_LIBYUV_VERSION_H_ 17 | -------------------------------------------------------------------------------- /server-render/vcsrender/libyuv/lib-static/linux-x64/libyuv_internal.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/vcsrender/libyuv/lib-static/linux-x64/libyuv_internal.a -------------------------------------------------------------------------------- /server-render/vcsrender/libyuv/lib-static/mac-arm64/libyuv_internal.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/vcsrender/libyuv/lib-static/mac-arm64/libyuv_internal.a -------------------------------------------------------------------------------- /server-render/vcsrender/libyuv/lib-static/mac-arm64/libyuv_neon.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daily-co/daily-vcs/dd89b628b31bff18cb9273d46e98d6a8e631e3e5/server-render/vcsrender/libyuv/lib-static/mac-arm64/libyuv_neon.a -------------------------------------------------------------------------------- /server-render/vcsrender/src/file_util.cpp: -------------------------------------------------------------------------------- 1 | #include "file_util.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | std::string readTextFile(const std::string& path) { 8 | struct stat sb{}; 9 | std::string str; 10 | 11 | FILE* f = fopen(path.c_str(), "r"); 12 | if (!f) { 13 | throw std::runtime_error("Unable to open file"); 14 | } 15 | 16 | stat(path.c_str(), &sb); 17 | str.resize(sb.st_size); 18 | 19 | const size_t readResult = fread(const_cast(str.data()), sb.st_size, 1, f); 20 | fclose(f); 21 | 22 | if (readResult != 1) { 23 | throw std::runtime_error("Could not read all data from file"); 24 | } 25 | 26 | return str; 27 | } 28 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/file_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // Read text file in one operation using 'stat' for file size. 5 | // Throws on error. 6 | std::string readTextFile(const std::string& path); 7 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/fileseq_util.cpp: -------------------------------------------------------------------------------- 1 | #include "fileseq_util.h" 2 | 3 | std::pair getFilenameSeqPattern(const std::filesystem::path& path) { 4 | auto filename = path.stem().string(); 5 | 6 | auto idx = filename.find_last_of("_"); 7 | if (idx == std::string::npos || idx == filename.size() - 1) { 8 | throw std::runtime_error("Sequence filename not in expected format"); 9 | } 10 | auto pattern = filename.substr(0, idx + 1); 11 | int numDigits = filename.size() - idx - 1; 12 | 13 | return std::make_pair(pattern, numDigits); 14 | } 15 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/fileseq_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | // throws if filename doesn't match expected format. 7 | // must have an underscore followed by numbers, e.g. "foobar_0123.jpg" 8 | std::pair getFilenameSeqPattern(const std::filesystem::path& path); 9 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/imageseq.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "yuvbuf.h" 6 | 7 | 8 | namespace vcsrender { 9 | 10 | class ImageSequence { 11 | public: 12 | static std::unique_ptr createFromDir(std::string dir, int w, int h); 13 | 14 | // unvalidated metadata for raw sequences 15 | int w = 0; 16 | int h = 0; 17 | 18 | ImageSequence( 19 | std::filesystem::path dir, 20 | std::string fileRoot, 21 | int numDigits, 22 | std::string fileExt) 23 | : dir_(dir), 24 | fileRoot_(fileRoot), 25 | numDigits_(numDigits), 26 | fileExt_(fileExt) { 27 | load_(); 28 | } 29 | 30 | size_t getNumberOfFrames() const noexcept { 31 | return numFrames_; 32 | } 33 | 34 | std::unique_ptr readYuv420ForFrame(size_t frame); 35 | 36 | private: 37 | std::filesystem::path dir_; 38 | std::string fileRoot_; 39 | int numDigits_; 40 | std::string fileExt_; 41 | 42 | size_t numFrames_; 43 | bool startsAtOne_; 44 | 45 | void load_(); 46 | 47 | }; 48 | 49 | } // namespace vcsrender 50 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/inputloader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "inputtimings.h" 4 | #include "yuvbuf.h" 5 | #include "imageseq.h" 6 | 7 | namespace vcsrender { 8 | 9 | struct ActiveImageSeq { 10 | std::shared_ptr imSeq; 11 | size_t startFrame; 12 | size_t duration; 13 | }; 14 | 15 | class VideoInputLoader { 16 | public: 17 | VideoInputLoader(VCSVideoInputTimingsDesc& td) : timingsDesc_(td) {} 18 | 19 | // must be called at start of render loop 20 | bool start(); 21 | 22 | // must be called with frames in increasing order. 23 | // may throw on errors. 24 | VideoInputBufsById readInputBufsAtFrame(size_t frame); 25 | 26 | private: 27 | VCSVideoInputTimingsDesc& timingsDesc_; 28 | size_t frameCursor_; 29 | size_t evCursor_; 30 | 31 | std::map activeImageSeqsByInputId_; 32 | 33 | void startPlaybackForEvent_(VideoInputPlaybackEvent* ev); 34 | }; 35 | 36 | } // namespace vcsrender -------------------------------------------------------------------------------- /server-render/vcsrender/src/inputtimings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace vcsrender { 9 | 10 | /* 11 | Provides C++ types for the "input timings" data written out by vcs-cut 12 | to describe where clips start and stop on a timeline. 13 | 14 | An example of the format: 15 | 16 | { 17 | "durationInFrames": 1668, 18 | "playbackEvents": [ 19 | { 20 | "frame": 72, 21 | "videoInputId": 1001, 22 | "durationInFrames": 72, 23 | "clipId": "s1", 24 | "seqDir": "/Users/pauli/Documents/daily/ffmpeg-scripts/cut-tmp/s1" 25 | }, 26 | { 27 | "frame": 216, 28 | "videoInputId": 1002, 29 | "durationInFrames": 192, 30 | "clipId": "s2", 31 | "seqDir": "/Users/pauli/Documents/daily/ffmpeg-scripts/cut-tmp/s2" 32 | }, 33 | ... 34 | 35 | 36 | NOTE: playbackEvents are expected to be already sorted by frame index 37 | by vcs-cut when writing the file. 38 | */ 39 | 40 | struct VideoInputPlaybackEvent { 41 | size_t frameIndex; 42 | size_t durationInFrames; 43 | uint32_t videoInputId; 44 | std::string seqDir; 45 | uint32_t w; 46 | uint32_t h; 47 | // we ignore "clipId" from the JSON, it's metadata for vcs-cut 48 | }; 49 | 50 | struct VCSVideoInputTimingsDesc { 51 | size_t durationInFrames = 0; 52 | size_t startFrame = 0; 53 | std::vector playbackEvents; 54 | }; 55 | 56 | } // namespace vcsrender 57 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_upper_case_globals)] 2 | #![allow(non_camel_case_types)] 3 | include!(concat!(env!("OUT_DIR"), "/vcsrender_bindings.rs")); 4 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/mask.cpp: -------------------------------------------------------------------------------- 1 | #include "mask.h" 2 | #include "canvex_c_api.h" 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | namespace vcsrender { 9 | 10 | MaskCache::MaskCache() { 11 | capacity_ = 100; 12 | } 13 | 14 | std::shared_ptr MaskCache::getCachedMask(uint32_t w, uint32_t h, uint32_t cornerRadius) { 15 | std::tuple key {w, h, cornerRadius}; 16 | 17 | auto it = std::find_if(maskBufs_.begin(), maskBufs_.end(), 18 | [&key](const auto& el) { return el.first == key; }); 19 | 20 | if (it != std::end(maskBufs_)) { // already in cache 21 | //std::cout << "Found cached mask for " << w << " / " << h << " / " << cornerRadius << std::endl; 22 | auto& el = *it; 23 | return el.second; 24 | } 25 | 26 | std::cout << "creating roundrect mask for " << w << " / " << h << " / " << cornerRadius << std::endl; 27 | 28 | auto buf = std::make_shared(w, h); 29 | 30 | // clear to black 31 | memset(buf->data, 0, buf->rowBytes * buf->h); 32 | 33 | CanvexRenderRoundedRectMask_u8( 34 | buf->data, 35 | buf->w, 36 | buf->h, 37 | buf->rowBytes, 38 | 0, 0, buf->w, buf->h, 39 | cornerRadius, cornerRadius, cornerRadius, cornerRadius 40 | ); 41 | 42 | maskBufs_.emplace_back(key, buf); 43 | 44 | if (maskBufs_.size() > capacity_) { 45 | std::cout << "vcsrender maskcache is full (not expected to happen often, maybe capacity needs to be increased)" << std::endl; 46 | while (maskBufs_.size() > capacity_) { 47 | maskBufs_.pop_front(); 48 | } 49 | } 50 | 51 | return buf; 52 | } 53 | 54 | } // namespace vcsrender 55 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/mask.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | namespace vcsrender { 8 | 9 | struct AlphaBuf { 10 | uint32_t w; 11 | uint32_t h; 12 | uint32_t rowBytes; 13 | uint8_t* data; 14 | 15 | AlphaBuf(uint32_t a_w, uint32_t a_h, bool dense = false) 16 | : w(a_w), h(a_h) { 17 | rowBytes = w; 18 | if (!dense) { 19 | // round up rowbytes to a multiple of 16 20 | rowBytes = (rowBytes + 15) & (~15); 21 | } 22 | 23 | data = new uint8_t[rowBytes * h]; 24 | } 25 | 26 | ~AlphaBuf() { 27 | delete [] data; 28 | } 29 | }; 30 | 31 | class MaskCache { 32 | public: 33 | MaskCache(); 34 | 35 | std::shared_ptr getCachedMask(uint32_t w, uint32_t h, uint32_t cornerRadius); 36 | 37 | private: 38 | size_t capacity_; 39 | 40 | using MaskCacheKey = std::tuple; // width, height, cornerRadius 41 | using CachedMaskBuf = std::pair>; 42 | 43 | std::deque maskBufs_; 44 | }; 45 | 46 | } // namespace vcsrender 47 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/meson.build: -------------------------------------------------------------------------------- 1 | vcsrender_base_sources = files( 2 | 'parse/parse_scenedesc.cpp', 3 | 'yuv_compositor.cpp', 4 | 'file_util.cpp', 5 | 'fileseq_util.cpp', 6 | 'mask.cpp', 7 | 'vcsrender_c_api.cpp', 8 | 'thumbs.cpp', 9 | ) 10 | 11 | vcsrender_demo_sources = files( 12 | 'demo_main.cpp', 13 | ) + vcsrender_base_sources 14 | 15 | vcsrender_cli_sources = files( 16 | 'parse/parse_inputtimings.cpp', 17 | 'vcsrender_main.cpp', 18 | 'imageseq.cpp', 19 | 'sceneseq.cpp', 20 | 'inputloader.cpp', 21 | ) + vcsrender_base_sources 22 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/parse/parse_inputtimings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../inputtimings.h" 3 | 4 | namespace vcsrender { 5 | 6 | // throws on parse error 7 | std::unique_ptr ParseVCSVideoInputTimingsDescJSON(const std::string& str); 8 | std::unique_ptr ParseVCSVideoInputTimingsDescJSON(const char* jsonStr); 9 | 10 | } // namespace vcsrender 11 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/parse/parse_scenedesc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../scenedesc.h" 3 | 4 | namespace vcsrender { 5 | 6 | struct VideoLayerParseOptions { 7 | double scale = 1.0; 8 | }; 9 | 10 | // throws on parse error 11 | std::unique_ptr ParseVCSVideoLayerListJSON(const std::string& str, VideoLayerParseOptions opts); 12 | std::unique_ptr ParseVCSVideoLayerListJSON(const char* cstr, VideoLayerParseOptions opts); 13 | 14 | } // namespace vcsrender 15 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/scenedesc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace vcsrender { 9 | 10 | /* 11 | Provides C++ types for the data written out by VCS runner (in video-scenedesc.js). 12 | 13 | The 2D graphics display list is handled by canvex, it's not included here. 14 | Matching types and functions are in canvex_display_list.h in that project. 15 | (They are internal to canvex; vcsrender calls through the canvex C API to render.) 16 | 17 | Example data from VCS runner: 18 | [ {"type":"video","id":45210,"frame":{"x":0,"y":0,"w":960,"h":1080},"attrs":{"scaleMode":"fill"}}, 19 | {"type":"video","id":46724,"frame":{"x":960,"y":0,"w":960,"h":1080},"attrs":{"scaleMode":"fill"}} ] 20 | */ 21 | 22 | struct VCSFrame { 23 | double x = 0.0; 24 | double y = 0.0; 25 | double w = 0.0; 26 | double h = 0.0; 27 | }; 28 | 29 | enum VCSScaleMode { 30 | fill = 0, 31 | fit 32 | }; 33 | 34 | struct VideoLayerAttrs { 35 | VCSScaleMode scaleMode = VCSScaleMode::fill; 36 | double cornerRadiusPx = 0.0; 37 | double zoomFactor = 1.0; 38 | }; 39 | 40 | struct VideoLayerDesc { 41 | uint32_t id = 0; 42 | VCSFrame frame {}; 43 | VideoLayerAttrs attrs {}; 44 | 45 | VideoLayerDesc() {} 46 | }; 47 | 48 | using VCSVideoLayerList = std::vector; 49 | 50 | } // namespace vcsrender 51 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/sceneseq.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | 6 | namespace vcsrender { 7 | 8 | struct SceneJsonFrame { 9 | size_t index = 0; 10 | bool hasVl = false; 11 | bool hasFg = false; 12 | }; 13 | 14 | struct SceneDescAtFrame { 15 | size_t index; 16 | std::unique_ptr json_vl; 17 | std::unique_ptr json_fg; 18 | double layerScale = 1.0; 19 | }; 20 | 21 | class SceneJsonSequence { 22 | public: 23 | static std::unique_ptr createFromDir(std::string dir); 24 | 25 | SceneJsonSequence( 26 | std::filesystem::path dir, 27 | std::string fileRoot, 28 | int numDigits, 29 | std::string fileExt) 30 | : dir_(dir), 31 | fileRoot_(fileRoot), 32 | numDigits_(numDigits), 33 | fileExt_(fileExt) { 34 | load_(); 35 | } 36 | 37 | size_t getMaxFrameIndex() const noexcept { 38 | return frames_.size() > 0 ? frames_.back().index : 0; 39 | } 40 | 41 | SceneDescAtFrame readJsonForFrame(size_t frame); 42 | 43 | private: 44 | std::filesystem::path dir_; 45 | std::string fileRoot_; 46 | int numDigits_; 47 | std::string fileExt_; 48 | std::string fileRootWithoutId_; 49 | 50 | std::vector frames_; 51 | 52 | void load_(); 53 | 54 | std::unique_ptr readJsonWithFileId(size_t frameIdx, const std::string& fileId); 55 | }; 56 | 57 | } // namespace vcsrender 58 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/thumbs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "yuvbuf.h" 4 | 5 | namespace vcsrender { 6 | 7 | enum ThumbCaptureOutputMode { 8 | Luma_RawBinary = 1, // raw luma data, no line breaks 9 | Luma_AsciiArt // ASCII art with line breaks 10 | }; 11 | 12 | struct ThumbCaptureSettings { 13 | int32_t w = 78; 14 | int32_t h = 20; 15 | uint64_t captureIntervalInFrames = 60; 16 | ThumbCaptureOutputMode outputMode = Luma_AsciiArt; 17 | }; 18 | 19 | std::unique_ptr renderThumbAtFrame( 20 | const ThumbCaptureSettings& settings, 21 | uint64_t frameIndex, 22 | Yuv420PlanarBuf& yuvBuf 23 | ); 24 | 25 | } // namespace vcsrender 26 | -------------------------------------------------------------------------------- /server-render/vcsrender/src/time_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | static inline double getMonotonicTime() noexcept { 5 | auto now = std::chrono::steady_clock::now(); 6 | int64_t now_usec = std::chrono::time_point_cast(now) 7 | .time_since_epoch().count(); 8 | return now_usec / 1.0e6; 9 | } 10 | -------------------------------------------------------------------------------- /server-render/vcsrender/subprojects/canvex: -------------------------------------------------------------------------------- 1 | ../../canvex --------------------------------------------------------------------------------