wavesurfer.js
ffmpeg.wasm
wavesurfer.js | ffmpeg.wasm | |
---|---|---|
11 | 76 | |
8,168 | 13,028 | |
1.2% | 2.1% | |
9.4 | 8.9 | |
2 days ago | 25 days ago | |
TypeScript | C | |
BSD 3-clause "New" or "Revised" License | MIT License |
Stars - the number of stars that a project has on GitHub. Growth - month over month growth in stars.
Activity is a relative number indicating how actively a project is being developed. Recent commits have higher weight than older ones.
For example, an activity of 9.0 indicates that a project is amongst the top 10% of the most actively developed projects that we are tracking.
wavesurfer.js
- Wavesurfer.js
-
Theme Customization (Expanse from Archetype Themes)
Actually I want to modify the Expanse theme from Archetype Themes in a way that its possible to implement an audio player (using Wavesurfer JS library) which keeps playing when a new page is loaded. So there cant be an entire page reload, I need to modify the theme so the main content is fetched instead.
-
Wavesurfer waveform not appearing
I'm trying to get a basic version of wavesurfer working. I followed the tutorial from this youtube video and downloaded the same code from the github. The buttons appear, but the waveform doesn't appear.
-
Does anybody know the code to that player?
Could be this though: https://github.com/katspaugh/wavesurfer.js
-
delete
/*! * wavesurfer.js regions plugin 6.0.2 (2022-02-20) * https://wavesurfer-js.org * @license BSD-3-Clause */ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("WaveSurfer",[],t):"object"==typeof exports?exports.WaveSurfer=t():(e.WaveSurfer=e.WaveSurfer||{},e.WaveSurfer.regions=t())}(self,(function(){return(()=>{"use strict";var e={23:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var i=r(638);function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function a(e){for(var t=1;t=this.maxRegions}},{key:"add",value:function(e){var t=this;if(this.wouldExceedMaxRegions())return null;!(e=a({edgeScrollWidth:this.params.edgeScrollWidth||this.defaultEdgeScrollWidth},e)).formatTimeCallback&&this.params.formatTimeCallback&&(e=a(a({},e),{},{formatTimeCallback:this.params.formatTimeCallback})),!e.minLength&&this.regionsMinLength&&(e=a(a({},e),{},{minLength:this.regionsMinLength}));var r=new this.wavesurfer.Region(e,this.util,this.wavesurfer);return this.list[r.id]=r,r.on("remove",(function(){delete t.list[r.id]})),r}},{key:"clear",value:function(){var e=this;Object.keys(this.list).forEach((function(t){e.list[t].remove()}))}},{key:"enableDragSelection",value:function(e){var t=this;this.disableDragSelection();var r,i,n,a,s,o,l,h=e.slop||2,u=this.wavesurfer.drawer.container,d=!1!==e.scroll&&this.wavesurfer.params.scrollParent,c=e.scrollSpeed||1,f=e.scrollThreshold||10,v=this.wavesurfer.getDuration(),g=0,p=function e(r){if(a&&o){var s=t.wrapper.scrollLeft+c*o;t.wrapper.scrollLeft=s=Math.min(i,Math.max(0,s));var l=t.wavesurfer.drawer.handleEvent(r);a.update({start:Math.min(l*v,n*v),end:Math.max(l*v,n*v)}),s0&&window.requestAnimationFrame((function(){e(r)}))}},m=function(h){if(!(h.touches&&h.touches.length>1)){if(v=t.wavesurfer.getDuration(),s=h.targetTouches?h.targetTouches[0].identifier:null,i=t.wrapper.scrollWidth-t.wrapper.clientWidth,l=t.util.withOrientation(t.wrapper.getBoundingClientRect(),t.vertical),t.wavesurfer.params.splitChannels){var u=(h.touches?h.touches[0].clientY:h.clientY)-l.top,d=null!=t.wavesurfer.backend.buffer?t.wavesurfer.backend.buffer.numberOfChannels:1,c=t.wrapper.clientHeight/d,f=Math.floor(u/c);e.channelIdx=f;var g=t.wavesurfer.params.splitChannelsOptions.channelColors[f];g&&g.dragColor&&(e.color=g.dragColor)}r=!0,n=t.wavesurfer.drawer.handleEvent(h,!0),a=null,o=null}};this.wrapper.addEventListener("mousedown",m),this.wrapper.addEventListener("touchstart",m),this.on("disable-drag-selection",(function(){t.wrapper.removeEventListener("touchstart",m),t.wrapper.removeEventListener("mousedown",m)}));var w=function(e){e.touches&&e.touches.length>1||(r=!1,g=0,o=null,a&&(t.util.preventClick(),a.fireEvent("update-end",e),t.wavesurfer.fireEvent("region-update-end",a,e)),a=null)};this.wrapper.addEventListener("mouseleave",w),this.wrapper.addEventListener("mouseup",w),this.wrapper.addEventListener("touchend",w),document.body.addEventListener("mouseup",w),document.body.addEventListener("touchend",w),this.on("disable-drag-selection",(function(){document.body.removeEventListener("mouseup",w),document.body.removeEventListener("touchend",w),t.wrapper.removeEventListener("touchend",w),t.wrapper.removeEventListener("mouseup",w),t.wrapper.removeEventListener("mouseleave",w)}));var b=function(i){if(r&&!(++g<=h)&&!(i.touches&&i.touches.length>1)&&(!i.targetTouches||i.targetTouches[0].identifier==s)&&(a||(a=t.add(e||{})))){var c=t.wavesurfer.drawer.handleEvent(i),m=t.wavesurfer.regions.util.getRegionSnapToGridValue(n*v),w=t.wavesurfer.regions.util.getRegionSnapToGridValue(c*v);a.update({start:Math.min(w,m),end:Math.max(w,m)});var b=t.util.withOrientation(i,t.vertical);if(d&&u.clientWidth=l.right-f?1:null)&&p(i)}}};this.wrapper.addEventListener("mousemove",b),this.wrapper.addEventListener("touchmove",b),this.on("disable-drag-selection",(function(){t.wrapper.removeEventListener("touchmove",b),t.wrapper.removeEventListener("mousemove",b)})),this.wavesurfer.on("region-created",(function(e){t.regionsMinLength&&(e.minLength=t.regionsMinLength)}))}},{key:"disableDragSelection",value:function(){this.fireEvent("disable-drag-selection")}},{key:"getCurrentRegion",value:function(){var e=this,t=this.wavesurfer.getCurrentTime(),r=null;return Object.keys(this.list).forEach((function(i){var n=e.list[i];n.start<=t&&n.end>=t&&(!r||n.end-n.start{function r(e,t){for(var r=0;r=0&&se&&(r=e-((i=e)-r)),null!=this.minLength&&(i=Math.max(r+this.minLength,i)),null!=this.maxLength&&(i=Math.min(r+this.maxLength,i)),null!=this.element){var n=Math.round(r/e*t),a=Math.round(i/e*t)-n;for(var s in this.style(this.element,{left:n+"px",width:a+"px",backgroundColor:this.color,cursor:this.drag?"move":"default"}),this.attributes)this.element.setAttribute("data-region-"+s,this.attributes[s]);this.showTooltip&&(this.element.title=this.formatTime(this.start,this.end))}}},{key:"bindInOut",value:function(){var e=this;this.firedIn=!1,this.firedOut=!1;var t=function(t){var r=Math.round(10*e.start)/10,i=Math.round(10*e.end)/10;t=Math.round(10*t)/10,!e.firedOut&&e.firedIn&&(r>t||i<=t)&&(e.firedOut=!0,e.firedIn=!1,e.fireEvent("out"),e.wavesurfer.fireEvent("region-out",e)),!e.firedIn&&r<=t&&i>t&&(e.firedIn=!0,e.firedOut=!1,e.fireEvent("in"),e.wavesurfer.fireEvent("region-in",e))};this.wavesurfer.backend.on("audioprocess",t),this.on("remove",(function(){e.wavesurfer.backend.un("audioprocess",t)})),this.on("out",(function(){if(e.loop){var t=e.wavesurfer.getCurrentTime();t>=e.start&&t<=e.end&&e.wavesurfer.play(e.start)}}))}},{key:"bindEvents",value:function(){var e=this,t=this.preventContextMenu;this.element.addEventListener("mouseenter",(function(t){e.fireEvent("mouseenter",t),e.wavesurfer.fireEvent("region-mouseenter",e,t)})),this.element.addEventListener("mouseleave",(function(t){e.fireEvent("mouseleave",t),e.wavesurfer.fireEvent("region-mouseleave",e,t)})),this.element.addEventListener("click",(function(t){t.preventDefault(),e.fireEvent("click",t),e.wavesurfer.fireEvent("region-click",e,t)})),this.element.addEventListener("dblclick",(function(t){t.stopPropagation(),t.preventDefault(),e.fireEvent("dblclick",t),e.wavesurfer.fireEvent("region-dblclick",e,t)})),this.element.addEventListener("contextmenu",(function(r){t&&r.preventDefault(),e.fireEvent("contextmenu",r),e.wavesurfer.fireEvent("region-contextmenu",e,r)})),(this.drag||this.resize)&&this.bindDragEvents()}},{key:"bindDragEvents",value:function(){var e,t,r,i,n,a,s,o,l,h=this,u=this.wavesurfer.drawer.container,d=this.scrollSpeed,c=(this.scrollThreshold,!1),f=function t(u){var c=h.util.withOrientation(u,h.vertical),f=h.wavesurfer.getDuration();if(a&&(r||n)){var v=c.clientX,g=0,p=0,m=0,w=h.regionsUtil.getRegionSnapToGridValue(h.wavesurfer.drawer.handleEvent(u)*f);if(r)-1===a?(p=o*h.wavesurfer.params.minPxPerSec,g=v-s.left):(p=l*h.wavesurfer.params.minPxPerSec,g=s.right-v);else{var b=h.minLength;b||(b=0),"start"===n?(w>h.end-b&&(w=h.end-b,m=d*a),w<0&&(w=0)):"end"===n&&(wf&&(w=f))}var y=h.wrapper.scrollLeft;if(-1===a){if(0===Math.round(y))return;if(Math.round(y-p+g)<=0)return}else{if(Math.round(y)===i)return;if(Math.round(y+p-g)>=i)return}var E=y-m+d*a;if(-1===a){var L=Math.max(0+p-g,E);h.wrapper.scrollLeft=E=L}else{var k=Math.min(i-p+g,E);h.wrapper.scrollLeft=E=k}var x=w-e;e=w,r?h.onDrag(x):h.onResize(x,n),window.requestAnimationFrame((function(){t(u)}))}},v=function(a){var u=h.wavesurfer.getDuration();a.touches&&a.touches.length>1||(t=a.targetTouches?a.targetTouches[0].identifier:null,(h.drag||h.resize)&&a.stopPropagation(),e=h.regionsUtil.getRegionSnapToGridValue(h.wavesurfer.drawer.handleEvent(a,!0)*u),o=e-h.start,l=h.end-e,i=h.wrapper.scrollWidth-h.wrapper.clientWidth,s=h.util.withOrientation(h.wrapper.getBoundingClientRect(),h.vertical),h.isResizing=!1,h.isDragging=!1,"handle"===a.target.tagName.toLowerCase()?(h.isResizing=!0,n=a.target.classList.contains("wavesurfer-handle-start")?"start":"end"):(h.isDragging=!0,r=!0,n=!1))},g=function(e){e.touches&&e.touches.length>1||((r||n)&&(h.isDragging=!1,h.isResizing=!1,r=!1,a=null,n=!1),c&&(c=!1,h.util.preventClick(),h.fireEvent("update-end",e),h.wavesurfer.fireEvent("region-update-end",h,e)))},p=function(i){var d=h.wavesurfer.getDuration(),v=h.util.withOrientation(i,h.vertical);if(!(i.touches&&i.touches.length>1)&&(!i.targetTouches||i.targetTouches[0].identifier==t)&&(r||n)){var g=h.regionsUtil.getRegionSnapToGridValue(h.wavesurfer.drawer.handleEvent(i)*d);if(r){var p=h.wavesurfer.getDuration();g>p-l&&(g=p-l),g-o<0&&(g=o)}if(n){var m=h.minLength;m||(m=0),"start"===n?(g>h.end-m&&(g=h.end-m),g<0&&(g=0)):"end"===n&&(gd&&(g=d))}var w=g-e;if(e=g,h.drag&&r&&(c=c||!!w,h.onDrag(w)),h.resize&&n&&(c=c||!!w,h.onResize(w,n)),h.scroll&&u.clientWidths.right-h.edgeScrollWidth?1:null)&&f(i)}}};this.element.addEventListener("mousedown",v),this.element.addEventListener("touchstart",v),document.body.addEventListener("mousemove",p),document.body.addEventListener("touchmove",p,{passive:!1}),document.addEventListener("mouseup",g),document.body.addEventListener("touchend",g),this.on("remove",(function(){document.removeEventListener("mouseup",g),document.body.removeEventListener("touchend",g),document.body.removeEventListener("mousemove",p),document.body.removeEventListener("touchmove",p)})),this.wavesurfer.on("destroy",(function(){document.removeEventListener("mouseup",g),document.body.removeEventListener("touchend",g)}))}},{key:"onDrag",value:function(e){var t=this.wavesurfer.getDuration();this.end+e>t&&(e=t-this.end),this.start+e<0&&(e=-1\*this.start);var r={direction:this.\_getDragDirection(e),action:"drag"};this.update({start:this.start+e,end:this.end+e},r)}},{key:"\_getDragDirection",value:function(e){return e<0?"left":e>0?"right":null}},{key:"onResize",value:function(e,t){var r=this.wavesurfer.getDuration(),i={action:"resize",direction:"start"===t?"left":"right"};"start"===t?(e>0&&this.end-(this.start+e)this.maxLength&&(e=this.end-this.start-this.maxLength),e<0&&this.start+e<0&&(e=-1\*this.start),this.update({start:Math.min(this.start+e,this.end),end:Math.max(this.start+e,this.end)},i)):(e<0&&this.end+e-this.start0&&this.end+e-this.start>this.maxLength&&(e=this.maxLength-(this.end-this.start)),e>0&&this.end+e>r&&(e=r-this.end),this.update({start:Math.min(this.end+e,this.start),end:Math.max(this.end+e,this.start)},i))}},{key:"updateHandlesResize",value:function(e){var t;t=e?this.vertical?"row-resize":"col-resize":"auto",this.handleLeftEl&&this.style(this.handleLeftEl,{cursor:t}),this.handleRightEl&&this.style(this.handleRightEl,{cursor:t})}}])&&r(t.prototype,i),n&&r(t,n),Object.defineProperty(t,"prototype",{writable:!1}),e}();t.Region=i}},t={};var r=function r(i){var n=t[i];if(void 0!==n)return n.exports;var a=t[i]={exports:{}};return e[i](a,a.exports,r),a.exports}(23);return r})()}));
-
Svelte Performance Test | Frame Accurate Subtitle Display
Thanks so much! The timeline actually isn't as complicated as it may look. There are lots of really awesome projects to take inspiration from (e.g. WavesurferJS). The one thing I wanted to point out is that the component was much easier to build in Svelte than in Vue. When we had the timeline component in Vue it used dependencies from other projects (because they were readily available). With Svelte there was nothing to install from NPM so we built it from scratch... and it was actually a lot of fun! It also scales really nicely for larger projects!
- What is this thing called?
-
Improvements to my Rails app!
- Track preview with a Waveform display with Wavesurfer (https://wavesurfer-js.org/)
- HTML5 Player for Shopify
-
How to create a video editor that works in your browser.
wavesufer.js
ffmpeg.wasm
-
Show HN: I open-sourced the in-memory PostgreSQL I built at work for E2E tests
There's already ffmpeg wasm. I've used it in projects. Works great.
https://github.com/ffmpegwasm/ffmpeg.wasm
-
FFmpeg 7.0 Released
There's a low-hanging fruit that I think would make ffmpeg more helpful for regular people.
There's a million terrible websites that offer file conversion services. They're ad-ridden, with god-knows-what privacy/security postures. There's little reason for users to need to upload their files to a third-party when they can do it locally. But getting them to download fiddly technical software is tough - and they're right to mistrust it.
So, there's a WASM version of ffmpeg, already working and hosted at Netlify [1]. It downloads the WASM bundle to your browser and you can run conversions/transformations as you wish, in your browser. Sandboxed and pretty performant too!
If this tool a) was updated regularly b) had a nicer, non-CLI UI for everyday users and c) was available at an easily-Googlable domain name - it would solve all the problems I mentioned above.
[1]: https://ffmpegwasm.netlify.app/
-
FFmpeg-online: ffpmeg running on the browser
As their github page says, based on https://ffmpegwasm.netlify.app ...
I'm guessing no one did GPU-optimizations? I saw a web app (not an ffmpeg transpilation) that went clever and used WebGL so it can access the GPU and use its parallel processing capabilities...
-
Locoly (locoly.app): an in-browser video editor running all computations locally
ffmpeg.wasm: The engine making all these happen. However, I’m a bit concerned about its current situation. The repo has not been updated for more than six months now, and that’s not a healthy sign for an open-source project. Clearly I was reading the commits wrong. The author mentioned “speed up x264 with SIMD intrinsics” in their roadmap (https://github.com/ffmpegwasm/ffmpeg.wasm/discussions/415), which, if landed, could make such on-device video editors much more competitive.
-
[TASK] Reverse Engineer my Web App Before Production
I use https://github.com/ffmpegwasm/ffmpeg.wasm and I want my FFMPEG commands to be hidden from others.
- AWS service for transcoding audio to mp3 and images to jpg?
-
I made a simple online video editor with React and ffmpeg
Possibly using this? https://github.com/ffmpegwasm/ffmpeg.wasm
-
Newbie question: Is there any possible way to grab metadata from local media files and process them in the webbrowser?
You could try using something like ffmpeg wasm which is a way of using ffmpeg client side in browser. Unfortunately WebAssembly only supports files less than 2 gigabytes, which is a problem for videos. And I don't know if ffmpeg wasm contains ffprobe, so you might have to find another project or try to compile ffprobe to wasm yourself. This stuff is out of my wheelhouse so I can't offer much help.
- Show HN: FFmpeg UI
- Petition to add support for Gopher protocol in Firefox
What are some alternatives?
RictyDiminished - Ricty Diminished --- fonts for programming
rust-ffmpeg-wasi - ffmpeg 7 libraries precompiled for WebAsembly/WASI, as a Rust crate.
waveform-playlist - Multitrack Web Audio editor and player with canvas waveform preview. Set cues, fades and shift multiple tracks in time. Record audio tracks or provide audio annotations. Export your mix to AudioBuffer or WAV! Add effects from Tone.js. Project inspired by Audacity.
ffprobe-wasm - A Web-based FFProbe. Powered by FFmpeg, Vue and Web Assembly!
Vega - video editor
ffmpeg-libav-tutorial - FFmpeg libav tutorial - learn how media works from basic to transmuxing, transcoding and more. Translations: 🇺🇸 🇨🇳 🇰🇷 🇪🇸 🇻🇳 🇧🇷
tonejs-instruments - A small instrument sample library with quick-loader for tone.js
node-ytdl-core - YouTube video downloader in javascript.
vue-audio-visual - VueJS audio visualization components
handbrake-js - Video encoding / transcoding / converting for node.js
spectrum-vue - Adobe Spectrum UI Components for Vue.
ffmpeg.js - Port of FFmpeg with Emscripten