{"id":19323098,"url":"https://github.com/ojack/hydra-sync","last_synced_at":"2025-07-08T14:04:25.849Z","repository":{"id":70843058,"uuid":"139899286","full_name":"ojack/hydra-sync","owner":"ojack","description":null,"archived":false,"fork":false,"pushed_at":"2018-09-12T22:29:53.000Z","size":12626,"stargazers_count":26,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-02T03:09:24.160Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ojack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-07-05T20:52:21.000Z","updated_at":"2025-02-08T22:33:16.000Z","dependencies_parsed_at":"2023-03-21T03:48:26.983Z","dependency_job_id":null,"html_url":"https://github.com/ojack/hydra-sync","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ojack%2Fhydra-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ojack%2Fhydra-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ojack%2Fhydra-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ojack%2Fhydra-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ojack","download_url":"https://codeload.github.com/ojack/hydra-sync/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250308512,"owners_count":21409283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T01:45:05.556Z","updated_at":"2025-04-22T19:32:07.282Z","avatar_url":"https://github.com/ojack.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Hydra\n![hydra](https://github.com/ojack/hydra/blob/master/hydra-3-01.png?raw=true)\n\nSet of tools for livecoding networked visuals. Inspired by analog modular synthesizers, these tools are an exploration into using streaming over the web for routing video sources and outputs in realtime.\n\nHydra uses multiple framebuffers to allow dynamically mixing, compositing, and collaborating between connected browser-visual-streams. Coordinate and color transforms can be applied to each output via chained functions (see \"basic functions\" and \"editing transformation functions\" below.)\n\nNote: experimental/in development. Right now only works on Chrome or Chromium, on machines with WebGL.\nI welcome pull requests as well as comments, ideas, and bugs in the issues section =]\n\nNote: this repository is for the online version of hydra. Other pieces of hydra are published as separate modules:\n* [hydra-synth](https://github.com/ojack/hydra-synth): synth engine of hydra as a standalone npm module\n\nExperimental/in progress/not documented:\n* [rtc-patch-bay](https://github.com/ojack/rtc-patch-bay): networking logic of hydra as a standalone npm module\n* [atom-hydra](https://github.com/ojack/atom-hydra): use hydra within atom\n\n\nOther projects\n#### Getting started\n\nGo to https://hydra-editor-v1.glitch.me\n\n* CTRL-Enter: run a line of code\n* CTRL-Shift-Enter: run all code on screen\n* ALT-Enter: run a block\n* CTRL-Shift-H: hide or show code\n\nAll code can be run either from the in-browser text editor or from the browser console.\n\n#### Basic functions\nrender an oscillator with parameters frequency, sync, and rgb offset:\n```\nosc(20, 0.1, 0.8).out()\n```\n\nrotate the oscillator 1.5 radians:\n```\nosc(20, 0.1, 0.8).rotate(0.8).out()\n```\npixelate the output of the above function:\n```\nosc(20, 0.1, 0.8).rotate(0.8).pixelate(20, 30).out()\n```\nshow webcam output:\n```\ns0.initCam() // initialize a webcam in source buffer s0\nsrc(s0).out() // render source buffer s0\n```\nIf you have more than one camera connected, you can select the camera using an index:\n```\ns0.initCam(1) // initialize a webcam in source buffer s0\n```\nwebcam kaleidoscope:\n```\ns0.initCam() // initialize a webcam in source buffer s0\nsrc(s0).kaleid(4).out() // render the webcam to a kaleidoscope\n```\n\nYou can also composite multiple sources together:\n```\nosc(10)\n  .rotate(0.5)\n  .diff(osc(200))\n  .out()\n```\n\nBy default, the environment contains four separate output buffers that can each render different graphics.  The outputs are accessed by the variables o0, o1, o2, and o3.\n\nto render to output buffer o1:\n```\nosc().out(o1)\nrender(o1) // render the contents of o1\n```\nIf no output is specified in out(), the graphics are rendered to buffer o0.\nto show all render buffers at once:\n```\nrender()\n```\n\nThe output buffers can then be mixed and composited to produce what is shown on the screen.\n```\ns0.initCam() // initialize a webcam in source buffer s0\nsrc(s0).out(o0) // set the source of o0 to render the buffer containing the webcam\nosc(10, 0.2, 0.8).diff(o0).out(o1) // initialize a gradient in output buffer o1, composite with the contents of o0\nrender(o1) // render o1 to the screen\n```\n\nThe composite functions blend(), diff(), mult(), and add() perform arithmetic operations to combine the input texture color with the base texture color, similar to photoshop blend modes.\n\nmodulate(texture, amount) uses the red and green channels of the input texture to modify the x and y coordinates of the base texture. More about modulation at: https://lumen-app.com/guide/modulation/\n```\nosc(21, 0).modulate(o1).out(o0)\nosc(40).rotate(1.57).out(o1)\n```\n\n#### Passing functions as variables\nEach parameter can be defined as a function rather than a static variable. For example,\n```\nosc(function({time}){return 100 * Math.sin(time * 0.1)}).out()\n```\nmodifies the oscillator frequency as a function of time. This can be written more concisely using es6 syntax:\n```\nosc(({time}) =\u003e (100 * Math.sin(time * 0.1))).out()\n```\n\n#### Desktop capture\nTo use screen capture or a browser tab as an input texture, you must first install the chrome extension for screensharing, and restart chrome. Desktop capture can be useful for inputing graphics from another application, or a video or website in another browser tab. It can also be used to create interesting feedback effects.\n\nTo install, go to http://chrome://extensions/\nClick \"Load unpacked extension\", and select the \"extensions\" folder in \"screen-capture-extension\" in this repo. Restart chrome. The extension should work from now on without needing to reinstall.\n\nselect a screen tab to use as input texture:\n```\ns0.initScreen()\n```\n\nrender screen tab:\n```\ns0.initScreen()\nsrc(s0).out()\n```\n\n#### Connecting to remote streams\nAny hydra instance can use other instances/windows containing hydra as input sources, as long as they are connected to the internet and not blocked by a firewall. Hydra uses webrtc (real time webstreaming) under the hood to share video streams between open windows. The included module rtc-patch-bay manages connections between connected windows, and can also be used as a standalone module to convert any website into a source within hydra. (See standalone camera source below for example.)\n\nTo begin, open hydra simultaneously in two separate windows.\nIn one of the windows, set a name for the given patch-bay source:\n```\npb.setName(\"myGraphics\")\n```\nThe title of the window should change to the name entered in setName().\n\nFrom the other window, initiate \"myGraphics\" as a source stream.\n```\ns0.initStream(\"myGraphics\")\n```\nrender to screen:\n```\ns0.initStream(\"myGraphics\")\nsrc(s0).out()\n```\nThe connections sometimes take a few seconds to be established; open the browser console to see progress.\nTo list available sources, type the following in the console:\n```\npb.list()\n```\n\n#### Running locally\nTo run locally, you must have nodejs and npm installed. Install from: https://nodejs.org/en/\n\nopen terminal and enter directory\n```\ncd hydra\n```\ninstall dependencies:\n```\nnpm install -d\n```\nrun server\n```\nnpm run start\n```\ngo to https://localhost:8000 in the browser\n\n#### Audio Responsiveness (experimental)\nFFT functionality is available via an audio object accessed via \"a\". The editor uses https://github.com/meyda/meyda for audio analysis.\nTo show the fft bins,\n```\na.show()\n```\nSet number of fft bins:\n```\na.setBins(6)\n```\nAccess the value of the leftmost (lowest frequency) bin:\n```\na.fft[0]\n```\nUse the value to control a variable:\n```\nosc(10, 0, () =\u003e (a.fft[0]*4))\n  .out()\n```\nIt is possible to calibrate the responsiveness by changing the minimum and maximum value detected. (Represented by black lines over the fft). To set minimum value detected:\n```\na.setCutoff(4)\n```\nTo set maximum:\n```\na.setMax(10)\n```\nThe fft[\u003cindex\u003e] will return a value between 0 and 1, where 0 represents the cutoff and 1 corresponds to the maximum.\n\nTo hide the audio waveform:\n```\na.hide()\n```\n\n#### Adding/editing transformation functions\n\nAll of the available functions for transforming coordinates and color, as well as compositing textures, correspond directly to a snippet of fragment shader code. These transformations are defined in the file hydra/hydra-server/app/src/glslTransforms.js. When running locally, you can edit this file to change the available functions, and refresh the page to see changes.\n\n\n#### API\n\nFor updated list of functions, see comosable-glslTransforms.js file in hydra/hydra-server/app/src/\n\n#### Changelog between v0 and v1:\n* Syntax change from 'o0.osc()' to 'osc().out(o0)'. Note: old syntax still works\n* multiple generator functions can be composited into each other:\n`osc(10)\n  .rotate(0.5)\n  .diff(osc(200).rotate(0.2))\n  .out()`\n* Buffer can be an input to itself:\n`osc(40, 0.1, 1)\n  .modulate(src(o0), 0.1)\n  .scale(1.1)\n  .rotate(0.04)\n  .out(o0)`\n* Multiple cameras can be specified using s0.initCam(1)\n* synth logic exists as a separate module, hydra-synth\n* added preliminary fft capability\n* fixed some bugs in editor and camera\n\n #### Libraries and tools used:\n * [Regl: functional webgl](http://regl.party/)\n * glitch.io: hosting for sandbox signalling server\n * codemirror: browser-based text editor\n * simple-peer\n\n #### Inspiration:\n * Space-Time Dynamics in Video Feedback (1984). [video](https://www.youtube.com/watch?v=B4Kn3djJMCE) and [paper](http://csc.ucdavis.edu/~cmg/papers/Crutchfield.PhysicaD1984.pdf) by Jim Crutchfield about using analog video feedback to model complex systems.\n * [Satellite Arts Project (1977) - Kit Galloway and Sherrie Rabinowitz](http://www.ecafe.com/getty/SA/)\n * [Sandin Image Processor](http://www.audiovisualizers.com/toolshak/vidsynth/sandin/sandin.htm)\n * [kynd - reactive buffers experiment](https://kynd.github.io/reactive_buffers_experiment/)\n\n #### Related projects:\n * [Lumen app (osx application)](https://lumen-app.com/)\n * [Vsynth (package for MaxMSP)] (https://cycling74.com/forums/vsynth-package)\n * [VEDA (VJ system within atom)](https://veda.gl/)\n * [The Force](https://videodromm.com/The_Force/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fojack%2Fhydra-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fojack%2Fhydra-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fojack%2Fhydra-sync/lists"}